Merge branch 'upstream' of git://electric-eye.fr.zoreil.com/home/romieu/linux-2.6...
authorJeff Garzik <jeff@garzik.org>
Sat, 29 Jul 2006 05:26:51 +0000 (01:26 -0400)
committerJeff Garzik <jeff@garzik.org>
Sat, 29 Jul 2006 05:26:51 +0000 (01:26 -0400)
328 files changed:
Documentation/feature-removal-schedule.txt
Documentation/x86_64/boot-options.txt
MAINTAINERS
arch/i386/kernel/process.c
arch/i386/kernel/time.c
arch/i386/kernel/traps.c
arch/s390/defconfig
arch/s390/kernel/head31.S
arch/s390/kernel/head64.S
arch/s390/kernel/setup.c
arch/sparc/kernel/devices.c
arch/sparc/kernel/irq.c
arch/sparc/kernel/of_device.c
arch/sparc/kernel/prom.c
arch/sparc/kernel/smp.c
arch/sparc/kernel/sparc_ksyms.c
arch/sparc/kernel/sun4d_smp.c
arch/sparc/kernel/sys_sparc.c
arch/sparc/kernel/time.c
arch/sparc/mm/io-unit.c
arch/sparc/prom/tree.c
arch/sparc64/defconfig
arch/sparc64/kernel/devices.c
arch/sparc64/kernel/of_device.c
arch/sparc64/kernel/prom.c
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/kernel/sys_sparc.c
arch/sparc64/mm/fault.c
arch/sparc64/prom/tree.c
arch/x86_64/ia32/ia32entry.S
arch/x86_64/kernel/time.c
arch/x86_64/kernel/traps.c
block/blktrace.c
block/cfq-iosched.c
drivers/block/cciss.c
drivers/bluetooth/hci_usb.c
drivers/char/pcmcia/synclink_cs.c
drivers/char/synclink.c
drivers/char/synclink_gt.c
drivers/char/synclinkmp.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/cpufreq_userspace.c
drivers/dma/ioatdma.c
drivers/fc4/fc.c
drivers/ide/ide-disk.c
drivers/ide/ide-dma.c
drivers/ide/ide.c
drivers/ide/pci/it821x.c
drivers/infiniband/core/mad.c
drivers/infiniband/core/user_mad.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/hw/ipath/ipath_driver.c
drivers/infiniband/hw/ipath/ipath_keys.c
drivers/infiniband/hw/ipath/ipath_verbs.c
drivers/infiniband/hw/mthca/mthca_cmd.c
drivers/infiniband/hw/mthca/mthca_srq.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/message/fusion/Kconfig
drivers/message/fusion/Makefile
drivers/message/fusion/mptbase.c
drivers/message/fusion/mptbase.h
drivers/message/fusion/mptctl.c
drivers/message/fusion/mptctl.h
drivers/message/fusion/mptfc.c
drivers/message/fusion/mptsas.c
drivers/message/fusion/mptscsih.c
drivers/message/fusion/mptspi.c
drivers/net/dummy.c
drivers/net/e1000/e1000.h
drivers/net/e1000/e1000_main.c
drivers/net/ifb.c
drivers/net/myri10ge/myri10ge.c
drivers/net/skge.c
drivers/net/sky2.c
drivers/net/spider_net.c
drivers/net/spider_net.h
drivers/net/sunhme.c
drivers/net/sunlance.c
drivers/net/tg3.c
drivers/net/wan/c101.c
drivers/net/wan/hdlc_ppp.c
drivers/net/wan/hdlc_raw.c
drivers/net/wan/hdlc_raw_eth.c
drivers/net/wan/hdlc_x25.c
drivers/net/wan/n2.c
drivers/net/wireless/Kconfig
drivers/net/wireless/bcm43xx/bcm43xx_main.c
drivers/net/wireless/orinoco.c
drivers/net/wireless/zd1201.c
drivers/s390/block/xpram.c
drivers/s390/char/raw3270.c
drivers/s390/char/tape_class.c
drivers/s390/char/tape_core.c
drivers/s390/cio/ccwgroup.c
drivers/s390/cio/cmf.c
drivers/s390/cio/device_fsm.c
drivers/s390/net/ctcmain.c
drivers/s390/net/qeth_main.c
drivers/sbus/sbus.c
drivers/scsi/53c7xx.c
drivers/scsi/NCR53C9x.c
drivers/scsi/NCR_D700.c
drivers/scsi/aha152x.c
drivers/scsi/aic7xxx/aic79xx_core.c
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/arm/fas216.c
drivers/scsi/ata_piix.c
drivers/scsi/atari_NCR5380.c
drivers/scsi/constants.c
drivers/scsi/esp.c
drivers/scsi/ibmvscsi/iseries_vscsi.c
drivers/scsi/ibmvscsi/rpa_vscsi.c
drivers/scsi/jazz_esp.c
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_mem.c
drivers/scsi/lpfc/lpfc_nportdisc.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_sli.h
drivers/scsi/lpfc/lpfc_version.h
drivers/scsi/mac53c94.c
drivers/scsi/mesh.c
drivers/scsi/pluto.c
drivers/scsi/qlogicpti.c
drivers/scsi/scsi.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_ioctl.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_priv.h
drivers/scsi/scsi_transport_sas.c
drivers/scsi/sd.c
drivers/scsi/seagate.c
drivers/scsi/sr.c
drivers/scsi/st.c
drivers/scsi/sun3_NCR5380.c
drivers/scsi/sun3x_esp.c
drivers/scsi/wd33c93.c
drivers/serial/sunsab.c
drivers/serial/sunzilog.c
fs/xfs/linux-2.6/xfs_buf.h
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/quota/xfs_qm_bhv.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_log.c
fs/xfs/xfs_vfsops.c
include/asm-m68k/oplib.h
include/asm-s390/system.h
include/asm-s390/timex.h
include/asm-sparc/oplib.h
include/asm-sparc/signal.h
include/asm-sparc64/openprom.h
include/asm-sparc64/oplib.h
include/asm-sparc64/pgtable.h
include/asm-sparc64/sfp-machine.h
include/asm-x86_64/page.h
include/linux/cpu.h
include/linux/cpufreq.h
include/linux/futex.h
include/linux/ide.h
include/linux/netdevice.h
include/linux/netfilter_bridge.h
include/linux/skbuff.h
include/net/netdma.h
include/net/pkt_sched.h
include/net/sctp/structs.h
include/net/sctp/user.h
include/rdma/ib_mad.h
include/scsi/scsi_cmnd.h
include/scsi/scsi_transport_sas.h
kernel/cpu.c
kernel/cpuset.c
kernel/futex.c
kernel/futex_compat.c
net/8021q/vlan.c
net/appletalk/ddp.c
net/atm/br2684.c
net/atm/clip.c
net/atm/lec.c
net/atm/mpc.c
net/atm/pppoatm.c
net/atm/resources.c
net/ax25/sysctl_net_ax25.c
net/bluetooth/rfcomm/core.c
net/bridge/br_ioctl.c
net/bridge/br_netfilter.c
net/core/ethtool.c
net/core/user_dma.c
net/dccp/feat.h
net/dccp/ipv4.c
net/dccp/ipv6.c
net/dccp/options.c
net/decnet/dn_dev.c
net/decnet/dn_fib.c
net/decnet/dn_neigh.c
net/decnet/dn_rules.c
net/decnet/dn_table.c
net/econet/af_econet.c
net/ieee80211/Kconfig
net/ieee80211/ieee80211_crypt.c
net/ieee80211/ieee80211_crypt_ccmp.c
net/ieee80211/ieee80211_crypt_wep.c
net/ieee80211/ieee80211_wx.c
net/ieee80211/softmac/ieee80211softmac_auth.c
net/ieee80211/softmac/ieee80211softmac_io.c
net/ipv4/ah4.c
net/ipv4/arp.c
net/ipv4/devinet.c
net/ipv4/esp4.c
net/ipv4/fib_hash.c
net/ipv4/fib_rules.c
net/ipv4/fib_semantics.c
net/ipv4/igmp.c
net/ipv4/inet_diag.c
net/ipv4/ip_gre.c
net/ipv4/ip_input.c
net/ipv4/ip_options.c
net/ipv4/ipcomp.c
net/ipv4/ipip.c
net/ipv4/ipmr.c
net/ipv4/ipvs/ip_vs_ctl.c
net/ipv4/ipvs/ip_vs_est.c
net/ipv4/netfilter/ip_conntrack_helper_h323.c
net/ipv4/netfilter/ip_conntrack_standalone.c
net/ipv4/netfilter/ip_nat_snmp_basic.c
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/raw.c
net/ipv4/tcp_ipv4.c
net/ipv4/udp.c
net/ipv4/xfrm4_mode_tunnel.c
net/ipv6/ip6_input.c
net/ipv6/ip6_tunnel.c
net/ipv6/raw.c
net/ipv6/sit.c
net/ipv6/xfrm6_tunnel.c
net/irda/af_irda.c
net/irda/ircomm/ircomm_core.c
net/irda/ircomm/ircomm_lmp.c
net/irda/ircomm/ircomm_param.c
net/irda/ircomm/ircomm_tty.c
net/irda/irda_device.c
net/irda/iriap.c
net/irda/iriap_event.c
net/irda/irias_object.c
net/irda/irlan/irlan_common.c
net/irda/irlan/irlan_provider.c
net/irda/irlap.c
net/irda/irlap_frame.c
net/irda/irlmp.c
net/irda/irnet/irnet_ppp.c
net/irda/irttp.c
net/lapb/lapb_iface.c
net/llc/llc_core.c
net/netfilter/Kconfig
net/netfilter/nf_conntrack_standalone.c
net/netfilter/nf_queue.c
net/netfilter/xt_physdev.c
net/netfilter/xt_pkttype.c
net/netlink/af_netlink.c
net/rxrpc/connection.c
net/rxrpc/peer.c
net/rxrpc/transport.c
net/sched/act_api.c
net/sched/act_pedit.c
net/sched/act_police.c
net/sched/cls_basic.c
net/sched/cls_fw.c
net/sched/cls_route.c
net/sched/cls_rsvp.h
net/sched/cls_tcindex.c
net/sched/cls_u32.c
net/sched/em_meta.c
net/sched/ematch.c
net/sched/estimator.c
net/sched/sch_cbq.c
net/sched/sch_generic.c
net/sched/sch_gred.c
net/sched/sch_hfsc.c
net/sched/sch_htb.c
net/sched/sch_netem.c
net/sctp/associola.c
net/sctp/bind_addr.c
net/sctp/endpointola.c
net/sctp/ipv6.c
net/sctp/outqueue.c
net/sctp/protocol.c
net/sctp/sm_make_chunk.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/sctp/transport.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_gss/gss_krb5_mech.c
net/sunrpc/auth_gss/gss_mech_switch.c
net/sunrpc/auth_gss/gss_spkm3_mech.c
net/sunrpc/auth_gss/gss_spkm3_token.c
net/sunrpc/clnt.c
net/sunrpc/stats.c
net/sunrpc/svc.c
net/sunrpc/svcsock.c
net/sunrpc/xprt.c
net/sunrpc/xprtsock.c
net/tipc/bearer.c
net/tipc/cluster.c
net/tipc/discover.c
net/tipc/link.c
net/tipc/name_table.c
net/tipc/net.c
net/tipc/port.c
net/tipc/ref.c
net/tipc/subscr.c
net/tipc/user_reg.c
net/tipc/zone.c
net/unix/af_unix.c
net/wanrouter/af_wanpipe.c
net/wanrouter/wanmain.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c

index 9d3a077..87851ef 100644 (file)
@@ -258,3 +258,19 @@ Why:       These drivers never compiled since they were added to the kernel
 Who:   Jean Delvare <khali@linux-fr.org>
 
 ---------------------------
+
+What:  Bridge netfilter deferred IPv4/IPv6 output hook calling
+When:  January 2007
+Why:   The deferred output hooks are a layering violation causing unusual
+       and broken behaviour on bridge devices. Examples of things they
+       break include QoS classifation using the MARK or CLASSIFY targets,
+       the IPsec policy match and connection tracking with VLANs on a
+       bridge. Their only use is to enable bridge output port filtering
+       within iptables with the physdev match, which can also be done by
+       combining iptables and ebtables using netfilter marks. Until it
+       will get removed the hook deferral is disabled by default and is
+       only enabled when needed.
+
+Who:   Patrick McHardy <kaber@trash.net>
+
+---------------------------
index 6887d44..6da24e7 100644 (file)
@@ -238,6 +238,13 @@ Debugging
   pagefaulttrace Dump all page faults. Only useful for extreme debugging
                and will create a lot of output.
 
+  call_trace=[old|both|newfallback|new]
+               old: use old inexact backtracer
+               new: use new exact dwarf2 unwinder
+               both: print entries from both
+               newfallback: use new unwinder but fall back to old if it gets
+                       stuck (default)
+
 Misc
 
   noreplacement  Don't replace instructions with more appropriate ones
index e99028c..b2afc7a 100644 (file)
@@ -1676,10 +1676,8 @@ L:       linux-kernel@vger.kernel.org
 S:     Maintained
 
 LAPB module
-P:     Henner Eisen
-M:     eis@baty.hanse.de
 L:     linux-x25@vger.kernel.org
-S:     Maintained
+S:     Orphan
 
 LASI 53c700 driver for PARISC
 P:     James E.J. Bottomley
index 923bb29..8657c73 100644 (file)
@@ -690,8 +690,8 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
        /*
         * Now maybe handle debug registers and/or IO bitmaps
         */
-       if (unlikely((task_thread_info(next_p)->flags & _TIF_WORK_CTXSW))
-           || test_tsk_thread_flag(prev_p, TIF_IO_BITMAP))
+       if (unlikely((task_thread_info(next_p)->flags & _TIF_WORK_CTXSW)
+           || test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)))
                __switch_to_xtra(next_p, tss);
 
        disable_tsc(prev_p, next_p);
index 8705c0f..edd00f6 100644 (file)
@@ -135,7 +135,7 @@ unsigned long profile_pc(struct pt_regs *regs)
 {
        unsigned long pc = instruction_pointer(regs);
 
-       if (in_lock_functions(pc))
+       if (!user_mode_vm(regs) && in_lock_functions(pc))
                return *(unsigned long *)(regs->ebp + 4);
 
        return pc;
index 313ac1f..3facc8f 100644 (file)
@@ -187,10 +187,21 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
                        if (unwind_init_blocked(&info, task) == 0)
                                unw_ret = show_trace_unwind(&info, log_lvl);
                }
-               if (unw_ret > 0) {
-                       if (call_trace > 0)
+               if (unw_ret > 0 && !arch_unw_user_mode(&info)) {
+#ifdef CONFIG_STACK_UNWIND
+                       print_symbol("DWARF2 unwinder stuck at %s\n",
+                                    UNW_PC(info.regs));
+                       if (call_trace == 1) {
+                               printk("Leftover inexact backtrace:\n");
+                               if (UNW_SP(info.regs))
+                                       stack = (void *)UNW_SP(info.regs);
+                       } else if (call_trace > 1)
                                return;
-                       printk("%sLegacy call trace:\n", log_lvl);
+                       else
+                               printk("Full inexact backtrace again:\n");
+#else
+                       printk("Inexact backtrace:\n");
+#endif
                }
        }
 
index f4dfc10..f1d4591 100644 (file)
@@ -1,13 +1,16 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17-rc1
-# Mon Apr  3 14:34:15 2006
+# Linux kernel version: 2.6.18-rc2
+# Thu Jul 27 13:51:07 2006
 #
 CONFIG_MMU=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_S390=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
@@ -25,6 +28,7 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
 CONFIG_SYSCTL=y
 CONFIG_AUDIT=y
 # CONFIG_AUDITSYSCALL is not set
@@ -43,10 +47,12 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
+CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -94,7 +100,6 @@ CONFIG_HOTPLUG_CPU=y
 CONFIG_DEFAULT_MIGRATION_COST=1000000
 CONFIG_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
-CONFIG_BINFMT_ELF32=y
 
 #
 # Code generation options
@@ -115,6 +120,7 @@ CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
 
 #
 # I/O subsystem configuration
@@ -142,6 +148,7 @@ CONFIG_VIRT_CPU_ACCOUNTING=y
 # CONFIG_APPLDATA_BASE is not set
 CONFIG_NO_IDLE_HZ=y
 CONFIG_NO_IDLE_HZ_INIT=y
+CONFIG_S390_HYPFS_FS=y
 CONFIG_KEXEC=y
 
 #
@@ -174,6 +181,8 @@ CONFIG_IP_FIB_HASH=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -186,7 +195,10 @@ CONFIG_IPV6=y
 # CONFIG_INET6_IPCOMP is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
 # CONFIG_IPV6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -263,6 +275,7 @@ CONFIG_NET_ESTIMATOR=y
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
@@ -276,6 +289,7 @@ CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
+CONFIG_SYS_HYPERVISOR=y
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -334,6 +348,7 @@ CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 
@@ -359,9 +374,7 @@ CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
-CONFIG_MD_RAID5=m
-# CONFIG_MD_RAID5_RESHAPE is not set
-# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_RAID456 is not set
 CONFIG_MD_MULTIPATH=m
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=y
@@ -419,7 +432,8 @@ CONFIG_S390_TAPE_34XX=m
 #
 # Cryptographic devices
 #
-CONFIG_Z90CRYPT=m
+CONFIG_ZCRYPT=m
+# CONFIG_ZCRYPT_MONOLITHIC is not set
 
 #
 # Network device support
@@ -509,6 +523,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -614,26 +629,36 @@ CONFIG_MSDOS_PARTITION=y
 # Instrumentation Support
 #
 # CONFIG_PROFILING is not set
-# CONFIG_STATISTICS is not set
+CONFIG_STATISTICS=y
+CONFIG_KPROBES=y
 
 #
 # Kernel hacking
 #
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_DETECT_SOFTLOCKUP is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
 CONFIG_DEBUG_PREEMPT=y
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_FRAME_POINTER is not set
 # CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
@@ -688,3 +713,4 @@ CONFIG_CRYPTO=y
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=m
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
index d00de17..a4dc61f 100644 (file)
@@ -273,7 +273,7 @@ startup_continue:
 .Lbss_end:  .long _end
 .Lparmaddr: .long PARMAREA
 .Lsccbaddr: .long .Lsccb
-       .align  4096
+       .org    0x12000
 .Lsccb:
        .hword  0x1000                  # length, one page
        .byte   0x00,0x00,0x00
@@ -290,7 +290,7 @@ startup_continue:
 .Lscpincr2:
        .quad   0x00
        .fill   3984,1,0
-       .align  4096
+       .org    0x13000
 
 #ifdef CONFIG_SHARED_KERNEL
        .org    0x100000
index 47744fc..9d80c5b 100644 (file)
@@ -268,7 +268,7 @@ startup_continue:
 .Lparmaddr:
        .quad   PARMAREA
 
-       .align 4096
+       .org    0x12000
 .Lsccb:
        .hword 0x1000                   # length, one page
        .byte 0x00,0x00,0x00
@@ -285,7 +285,7 @@ startup_continue:
 .Lscpincr2:
        .quad 0x00
        .fill 3984,1,0
-       .align 4096
+       .org    0x13000
 
 #ifdef CONFIG_SHARED_KERNEL
        .org   0x100000
index 1ca34f5..c902f05 100644 (file)
@@ -877,31 +877,57 @@ static struct bin_attribute ipl_scp_data_attr = {
 
 static decl_subsys(ipl, NULL, NULL);
 
+static int ipl_register_fcp_files(void)
+{
+       int rc;
+
+       rc = sysfs_create_group(&ipl_subsys.kset.kobj,
+                               &ipl_fcp_attr_group);
+       if (rc)
+               goto out;
+       rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
+                                  &ipl_parameter_attr);
+       if (rc)
+               goto out_ipl_parm;
+       rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
+                                  &ipl_scp_data_attr);
+       if (!rc)
+               goto out;
+
+       sysfs_remove_bin_file(&ipl_subsys.kset.kobj, &ipl_parameter_attr);
+
+out_ipl_parm:
+       sysfs_remove_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
+out:
+       return rc;
+}
+
 static int __init
 ipl_device_sysfs_register(void) {
        int rc;
 
        rc = firmware_register(&ipl_subsys);
        if (rc)
-               return rc;
+               goto out;
 
        switch (get_ipl_type()) {
        case ipl_type_ccw:
-               sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_ccw_attr_group);
+               rc = sysfs_create_group(&ipl_subsys.kset.kobj,
+                                       &ipl_ccw_attr_group);
                break;
        case ipl_type_fcp:
-               sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
-               sysfs_create_bin_file(&ipl_subsys.kset.kobj,
-                                     &ipl_parameter_attr);
-               sysfs_create_bin_file(&ipl_subsys.kset.kobj,
-                                     &ipl_scp_data_attr);
+               rc = ipl_register_fcp_files();
                break;
        default:
-               sysfs_create_group(&ipl_subsys.kset.kobj,
-                                  &ipl_unknown_attr_group);
+               rc = sysfs_create_group(&ipl_subsys.kset.kobj,
+                                       &ipl_unknown_attr_group);
                break;
        }
-       return 0;
+
+       if (rc)
+               firmware_unregister(&ipl_subsys);
+out:
+       return rc;
 }
 
 __initcall(ipl_device_sysfs_register);
index adba9df..af90a5f 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <asm/page.h>
 #include <asm/oplib.h>
+#include <asm/prom.h>
 #include <asm/smp.h>
 #include <asm/system.h>
 #include <asm/cpudata.h>
@@ -34,12 +35,6 @@ static int check_cpu_node(int nd, int *cur_inst,
                          int (*compare)(int, int, void *), void *compare_arg,
                          int *prom_node, int *mid)
 {
-       char node_str[128];
-
-       prom_getstring(nd, "device_type", node_str, sizeof(node_str));
-       if (strcmp(node_str, "cpu"))
-               return -ENODEV;
-       
        if (!compare(nd, *cur_inst, compare_arg)) {
                if (prom_node)
                        *prom_node = nd;
@@ -59,20 +54,14 @@ static int check_cpu_node(int nd, int *cur_inst,
 static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg,
                         int *prom_node, int *mid)
 {
-       int nd, cur_inst, err;
+       struct device_node *dp;
+       int cur_inst;
 
-       nd = prom_root_node;
        cur_inst = 0;
-
-       err = check_cpu_node(nd, &cur_inst, compare, compare_arg,
-                            prom_node, mid);
-       if (!err)
-               return 0;
-
-       nd = prom_getchild(nd);
-       while ((nd = prom_getsibling(nd)) != 0) {
-               err = check_cpu_node(nd, &cur_inst, compare, compare_arg,
-                                    prom_node, mid);
+       for_each_node_by_type(dp, "cpu") {
+               int err = check_cpu_node(dp->node, &cur_inst,
+                                        compare, compare_arg,
+                                        prom_node, mid);
                if (!err)
                        return 0;
        }
index cde7332..72f0201 100644 (file)
@@ -329,7 +329,7 @@ void handler_irq(int irq, struct pt_regs * regs)
        disable_pil_irq(irq);
 #ifdef CONFIG_SMP
        /* Only rotate on lower priority IRQ's (scsi, ethernet, etc.). */
-       if(irq < 10)
+       if((sparc_cpu_model==sun4m) && (irq < 10))
                smp4m_irq_rotate(cpu);
 #endif
        action = sparc_irq[irq].action;
index 5a2faad..97bf87e 100644 (file)
@@ -596,14 +596,41 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
                static int pil_to_sbus[] = {
                        0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0,
                };
-               struct device_node *busp = dp->parent;
+               struct device_node *io_unit, *sbi = dp->parent;
                struct linux_prom_registers *regs;
-               int board = of_getintprop_default(busp, "board#", 0);
-               int slot;
+               int board, slot;
+
+               while (sbi) {
+                       if (!strcmp(sbi->name, "sbi"))
+                               break;
+
+                       sbi = sbi->parent;
+               }
+               if (!sbi)
+                       goto build_resources;
 
                regs = of_get_property(dp, "reg", NULL);
+               if (!regs)
+                       goto build_resources;
+
                slot = regs->which_io;
 
+               /* If SBI's parent is not io-unit or the io-unit lacks
+                * a "board#" property, something is very wrong.
+                */
+               if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) {
+                       printk("%s: Error, parent is not io-unit.\n",
+                              sbi->full_name);
+                       goto build_resources;
+               }
+               io_unit = sbi->parent;
+               board = of_getintprop_default(io_unit, "board#", -1);
+               if (board == -1) {
+                       printk("%s: Error, lacks board# property.\n",
+                              io_unit->full_name);
+                       goto build_resources;
+               }
+
                for (i = 0; i < op->num_irqs; i++) {
                        int this_irq = op->irqs[i];
                        int sbusl = pil_to_sbus[this_irq];
@@ -617,6 +644,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
                }
        }
 
+build_resources:
        build_device_resources(op, parent);
 
        op->dev.parent = parent;
index 4b06dcb..4ca9e5f 100644 (file)
@@ -444,6 +444,7 @@ static struct property * __init build_one_prop(phandle node, char *prev, char *s
        static struct property *tmp = NULL;
        struct property *p;
        int len;
+       const char *name;
 
        if (tmp) {
                p = tmp;
@@ -456,19 +457,21 @@ static struct property * __init build_one_prop(phandle node, char *prev, char *s
 
        p->name = (char *) (p + 1);
        if (special_name) {
+               strcpy(p->name, special_name);
                p->length = special_len;
                p->value = prom_early_alloc(special_len);
                memcpy(p->value, special_val, special_len);
        } else {
                if (prev == NULL) {
-                       prom_firstprop(node, p->name);
+                       name = prom_firstprop(node, NULL);
                } else {
-                       prom_nextprop(node, prev, p->name);
+                       name = prom_nextprop(node, prev, NULL);
                }
-               if (strlen(p->name) == 0) {
+               if (strlen(name) == 0) {
                        tmp = p;
                        return NULL;
                }
+               strcpy(p->name, name);
                p->length = prom_getproplen(node, p->name);
                if (p->length <= 0) {
                        p->length = 0;
index 6135d4f..e311ade 100644 (file)
@@ -87,6 +87,7 @@ void __cpuinit smp_store_cpu_info(int id)
 void __init smp_cpus_done(unsigned int max_cpus)
 {
        extern void smp4m_smp_done(void);
+       extern void smp4d_smp_done(void);
        unsigned long bogosum = 0;
        int cpu, num;
 
@@ -100,8 +101,34 @@ void __init smp_cpus_done(unsigned int max_cpus)
                num, bogosum/(500000/HZ),
                (bogosum/(5000/HZ))%100);
 
-       BUG_ON(sparc_cpu_model != sun4m);
-       smp4m_smp_done();
+       switch(sparc_cpu_model) {
+       case sun4:
+               printk("SUN4\n");
+               BUG();
+               break;
+       case sun4c:
+               printk("SUN4C\n");
+               BUG();
+               break;
+       case sun4m:
+               smp4m_smp_done();
+               break;
+       case sun4d:
+               smp4d_smp_done();
+               break;
+       case sun4e:
+               printk("SUN4E\n");
+               BUG();
+               break;
+       case sun4u:
+               printk("SUN4U\n");
+               BUG();
+               break;
+       default:
+               printk("UNKNOWN!\n");
+               BUG();
+               break;
+       };
 }
 
 void cpu_panic(void)
@@ -267,9 +294,9 @@ int setup_profiling_timer(unsigned int multiplier)
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
        extern void smp4m_boot_cpus(void);
+       extern void smp4d_boot_cpus(void);
        int i, cpuid, extra;
 
-       BUG_ON(sparc_cpu_model != sun4m);
        printk("Entering SMP Mode...\n");
 
        extra = 0;
@@ -283,7 +310,34 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 
        smp_store_cpu_info(boot_cpu_id);
 
-       smp4m_boot_cpus();
+       switch(sparc_cpu_model) {
+       case sun4:
+               printk("SUN4\n");
+               BUG();
+               break;
+       case sun4c:
+               printk("SUN4C\n");
+               BUG();
+               break;
+       case sun4m:
+               smp4m_boot_cpus();
+               break;
+       case sun4d:
+               smp4d_boot_cpus();
+               break;
+       case sun4e:
+               printk("SUN4E\n");
+               BUG();
+               break;
+       case sun4u:
+               printk("SUN4U\n");
+               BUG();
+               break;
+       default:
+               printk("UNKNOWN!\n");
+               BUG();
+               break;
+       };
 }
 
 /* Set this up early so that things like the scheduler can init
@@ -323,9 +377,37 @@ void __init smp_prepare_boot_cpu(void)
 int __cpuinit __cpu_up(unsigned int cpu)
 {
        extern int smp4m_boot_one_cpu(int);
-       int ret;
-
-       ret = smp4m_boot_one_cpu(cpu);
+       extern int smp4d_boot_one_cpu(int);
+       int ret=0;
+
+       switch(sparc_cpu_model) {
+       case sun4:
+               printk("SUN4\n");
+               BUG();
+               break;
+       case sun4c:
+               printk("SUN4C\n");
+               BUG();
+               break;
+       case sun4m:
+               ret = smp4m_boot_one_cpu(cpu);
+               break;
+       case sun4d:
+               ret = smp4d_boot_one_cpu(cpu);
+               break;
+       case sun4e:
+               printk("SUN4E\n");
+               BUG();
+               break;
+       case sun4u:
+               printk("SUN4U\n");
+               BUG();
+               break;
+       default:
+               printk("UNKNOWN!\n");
+               BUG();
+               break;
+       };
 
        if (!ret) {
                cpu_set(cpu, smp_commenced_mask);
index 5fb987f..4d441a5 100644 (file)
@@ -237,7 +237,6 @@ EXPORT_SYMBOL(prom_node_has_property);
 EXPORT_SYMBOL(prom_setprop);
 EXPORT_SYMBOL(saved_command_line);
 EXPORT_SYMBOL(prom_apply_obio_ranges);
-EXPORT_SYMBOL(prom_getname);
 EXPORT_SYMBOL(prom_feval);
 EXPORT_SYMBOL(prom_getbool);
 EXPORT_SYMBOL(prom_getstring);
index b141b7e..ba843f6 100644 (file)
@@ -43,15 +43,10 @@ extern ctxd_t *srmmu_ctx_table_phys;
 extern void calibrate_delay(void);
 
 extern volatile int smp_processors_ready;
-extern int smp_num_cpus;
 static int smp_highest_cpu;
 extern volatile unsigned long cpu_callin_map[NR_CPUS];
 extern cpuinfo_sparc cpu_data[NR_CPUS];
 extern unsigned char boot_cpu_id;
-extern int smp_activated;
-extern volatile int __cpu_number_map[NR_CPUS];
-extern volatile int __cpu_logical_map[NR_CPUS];
-extern volatile unsigned long ipi_count;
 extern volatile int smp_process_available;
 
 extern cpumask_t smp_commenced_mask;
@@ -144,6 +139,8 @@ void __init smp4d_callin(void)
        spin_lock_irqsave(&sun4d_imsk_lock, flags);
        cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */
        spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
+       cpu_set(cpuid, cpu_online_map);
+
 }
 
 extern void init_IRQ(void);
@@ -160,51 +157,24 @@ extern unsigned long trapbase_cpu3[];
 
 void __init smp4d_boot_cpus(void)
 {
-       int cpucount = 0;
-       int i, mid;
-
-       printk("Entering SMP Mode...\n");
-       
        if (boot_cpu_id)
                current_set[0] = NULL;
-
-       local_irq_enable();
-       cpus_clear(cpu_present_map);
-
-       /* XXX This whole thing has to go.  See sparc64. */
-       for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++)
-               cpu_set(mid, cpu_present_map);
-       SMP_PRINTK(("cpu_present_map %08lx\n", cpus_addr(cpu_present_map)[0]));
-       for(i=0; i < NR_CPUS; i++)
-               __cpu_number_map[i] = -1;
-       for(i=0; i < NR_CPUS; i++)
-               __cpu_logical_map[i] = -1;
-       __cpu_number_map[boot_cpu_id] = 0;
-       __cpu_logical_map[0] = boot_cpu_id;
-       current_thread_info()->cpu = boot_cpu_id;
-       smp_store_cpu_info(boot_cpu_id);
        smp_setup_percpu_timer();
        local_flush_cache_all();
-       if (cpu_find_by_instance(1, NULL, NULL))
-               return;  /* Not an MP box. */
-       SMP_PRINTK(("Iterating over CPUs\n"));
-       for(i = 0; i < NR_CPUS; i++) {
-               if(i == boot_cpu_id)
-                       continue;
-
-               if (cpu_isset(i, cpu_present_map)) {
+}
+
+int smp4d_boot_one_cpu(int i)
+{
                        extern unsigned long sun4d_cpu_startup;
                        unsigned long *entry = &sun4d_cpu_startup;
                        struct task_struct *p;
                        int timeout;
-                       int no;
+                       int cpu_node;
 
+                       cpu_find_by_instance(i, &cpu_node,NULL);
                        /* Cook up an idler for this guy. */
                        p = fork_idle(i);
-                       cpucount++;
                        current_set[i] = task_thread_info(p);
-                       for (no = 0; !cpu_find_by_instance(no, NULL, &mid)
-                                    && mid != i; no++) ;
 
                        /*
                         * Initialize the contexts table
@@ -216,9 +186,9 @@ void __init smp4d_boot_cpus(void)
                        smp_penguin_ctable.reg_size = 0;
 
                        /* whirrr, whirrr, whirrrrrrrrr... */
-                       SMP_PRINTK(("Starting CPU %d at %p task %d node %08x\n", i, entry, cpucount, cpu_data(no).prom_node));
+                       SMP_PRINTK(("Starting CPU %d at %p \n", i, entry));
                        local_flush_cache_all();
-                       prom_startcpu(cpu_data(no).prom_node,
+                       prom_startcpu(cpu_node,
                                      &smp_penguin_ctable, 0, (char *)entry);
                                      
                        SMP_PRINTK(("prom_startcpu returned :)\n"));
@@ -230,39 +200,30 @@ void __init smp4d_boot_cpus(void)
                                udelay(200);
                        }
                        
-                       if(cpu_callin_map[i]) {
-                               /* Another "Red Snapper". */
-                               __cpu_number_map[i] = cpucount;
-                               __cpu_logical_map[cpucount] = i;
-                       } else {
-                               cpucount--;
-                               printk("Processor %d is stuck.\n", i);
-                       }
-               }
-               if(!(cpu_callin_map[i])) {
-                       cpu_clear(i, cpu_present_map);
-                       __cpu_number_map[i] = -1;
-               }
+       if (!(cpu_callin_map[i])) {
+               printk("Processor %d is stuck.\n", i);
+               return -ENODEV;
+
        }
        local_flush_cache_all();
-       if(cpucount == 0) {
-               printk("Error: only one Processor found.\n");
-               cpu_present_map = cpumask_of_cpu(hard_smp4d_processor_id());
-       } else {
-               unsigned long bogosum = 0;
-               
-               for_each_present_cpu(i) {
-                       bogosum += cpu_data(i).udelay_val;
-                       smp_highest_cpu = i;
+       return 0;
+}
+
+void __init smp4d_smp_done(void)
+{
+       int i, first;
+       int *prev;
+
+       /* setup cpu list for irq rotation */
+       first = 0;
+       prev = &first;
+       for (i = 0; i < NR_CPUS; i++)
+               if (cpu_online(i)) {
+                       *prev = i;
+                       prev = &cpu_data(i).next;
                }
-               SMP_PRINTK(("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", cpucount + 1, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100));
-               printk("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n",
-                      cpucount + 1,
-                      bogosum/(500000/HZ),
-                      (bogosum/(5000/HZ))%100);
-               smp_activated = 1;
-               smp_num_cpus = cpucount + 1;
-       }
+       *prev = first;
+       local_flush_cache_all();
 
        /* Free unneeded trap tables */
        ClearPageReserved(virt_to_page(trapbase_cpu1));
@@ -334,7 +295,7 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
                        register int i;
 
                        mask = cpumask_of_cpu(hard_smp4d_processor_id());
-                       cpus_andnot(mask, cpu_present_map, mask);
+                       cpus_andnot(mask, cpu_online_map, mask);
                        for(i = 0; i <= high; i++) {
                                if (cpu_isset(i, mask)) {
                                        ccall_info.processors_in[i] = 0;
index 0cdfc9d..a41c8a5 100644 (file)
@@ -465,21 +465,21 @@ sys_rt_sigaction(int sig,
 
 asmlinkage int sys_getdomainname(char __user *name, int len)
 {
-       int nlen;
-       int err = -EFAULT;
+       int nlen, err;
        
+       if (len < 0 || len > __NEW_UTS_LEN)
+               return -EINVAL;
+
        down_read(&uts_sem);
        
        nlen = strlen(system_utsname.domainname) + 1;
-
        if (nlen < len)
                len = nlen;
-       if (len > __NEW_UTS_LEN)
-               goto done;
-       if (copy_to_user(name, system_utsname.domainname, len))
-               goto done;
-       err = 0;
-done:
+
+       err = -EFAULT;
+       if (!copy_to_user(name, system_utsname.domainname, len))
+               err = 0;
+
        up_read(&uts_sem);
        return err;
 }
index 04eb1ea..845081b 100644 (file)
@@ -225,6 +225,32 @@ static __inline__ int has_low_battery(void)
        return (data1 == data2);        /* Was the write blocked? */
 }
 
+static void __init mostek_set_system_time(void)
+{
+       unsigned int year, mon, day, hour, min, sec;
+       struct mostek48t02 *mregs;
+
+       mregs = (struct mostek48t02 *)mstk48t02_regs;
+       if(!mregs) {
+               prom_printf("Something wrong, clock regs not mapped yet.\n");
+               prom_halt();
+       }               
+       spin_lock_irq(&mostek_lock);
+       mregs->creg |= MSTK_CREG_READ;
+       sec = MSTK_REG_SEC(mregs);
+       min = MSTK_REG_MIN(mregs);
+       hour = MSTK_REG_HOUR(mregs);
+       day = MSTK_REG_DOM(mregs);
+       mon = MSTK_REG_MONTH(mregs);
+       year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
+       xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+       xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
+        set_normalized_timespec(&wall_to_monotonic,
+                                -xtime.tv_sec, -xtime.tv_nsec);
+       mregs->creg &= ~MSTK_CREG_READ;
+       spin_unlock_irq(&mostek_lock);
+}
+
 /* Probe for the real time clock chip on Sun4 */
 static __inline__ void sun4_clock_probe(void)
 {
@@ -273,6 +299,7 @@ static __inline__ void sun4_clock_probe(void)
 #endif
 }
 
+#ifndef CONFIG_SUN4
 static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match)
 {
        struct device_node *dp = op->node;
@@ -307,6 +334,8 @@ static int __devinit clock_probe(struct of_device *op, const struct of_device_id
        if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
                kick_start_clock();
 
+       mostek_set_system_time();
+
        return 0;
 }
 
@@ -325,56 +354,37 @@ static struct of_platform_driver clock_driver = {
 
 
 /* Probe for the mostek real time clock chip. */
-static void clock_init(void)
+static int __init clock_init(void)
 {
-       of_register_driver(&clock_driver, &of_bus_type);
+       return of_register_driver(&clock_driver, &of_bus_type);
 }
 
+/* Must be after subsys_initcall() so that busses are probed.  Must
+ * be before device_initcall() because things like the RTC driver
+ * need to see the clock registers.
+ */
+fs_initcall(clock_init);
+#endif /* !CONFIG_SUN4 */
+
 void __init sbus_time_init(void)
 {
-       unsigned int year, mon, day, hour, min, sec;
-       struct mostek48t02 *mregs;
-
-#ifdef CONFIG_SUN4
-       int temp;
-       struct intersil *iregs;
-#endif
 
        BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM);
        btfixup();
 
        if (ARCH_SUN4)
                sun4_clock_probe();
-       else
-               clock_init();
 
        sparc_init_timers(timer_interrupt);
        
 #ifdef CONFIG_SUN4
        if(idprom->id_machtype == (SM_SUN4 | SM_4_330)) {
-#endif
-       mregs = (struct mostek48t02 *)mstk48t02_regs;
-       if(!mregs) {
-               prom_printf("Something wrong, clock regs not mapped yet.\n");
-               prom_halt();
-       }               
-       spin_lock_irq(&mostek_lock);
-       mregs->creg |= MSTK_CREG_READ;
-       sec = MSTK_REG_SEC(mregs);
-       min = MSTK_REG_MIN(mregs);
-       hour = MSTK_REG_HOUR(mregs);
-       day = MSTK_REG_DOM(mregs);
-       mon = MSTK_REG_MONTH(mregs);
-       year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
-       xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-       xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-        set_normalized_timespec(&wall_to_monotonic,
-                                -xtime.tv_sec, -xtime.tv_nsec);
-       mregs->creg &= ~MSTK_CREG_READ;
-       spin_unlock_irq(&mostek_lock);
-#ifdef CONFIG_SUN4
+               mostek_set_system_time();
        } else if(idprom->id_machtype == (SM_SUN4 | SM_4_260) ) {
                /* initialise the intersil on sun4 */
+               unsigned int year, mon, day, hour, min, sec;
+               int temp;
+               struct intersil *iregs;
 
                iregs=intersil_clock;
                if(!iregs) {
index 42c1c70..2bb1309 100644 (file)
@@ -64,6 +64,7 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus)
        
        sbus->iommu = (struct iommu_struct *)iounit;
        iounit->page_table = xpt;
+       spin_lock_init(&iounit->lock);
        
        for (xptend = iounit->page_table + (16 * PAGE_SIZE) / sizeof(iopte_t);
             xpt < xptend;)
index 2bf03ee..5ec2465 100644 (file)
@@ -205,24 +205,6 @@ int prom_searchsiblings(int node_start, char *nodename)
        return 0;
 }
 
-/* Gets name in the form prom v2+ uses it (name@x,yyyyy or name (if no reg)) */
-int prom_getname (int node, char *buffer, int len)
-{
-       int i;
-       struct linux_prom_registers reg[PROMREG_MAX];
-       
-       i = prom_getproperty (node, "name", buffer, len);
-       if (i <= 0) return -1;
-       buffer [i] = 0;
-       len -= i;
-       i = prom_getproperty (node, "reg", (char *)reg, sizeof (reg));
-       if (i <= 0) return 0;
-       if (len < 11) return -1;
-       buffer = strchr (buffer, 0);
-       sprintf (buffer, "@%x,%x", reg[0].which_io, (uint)reg[0].phys_addr);
-       return 0;
-}
-
 /* Interal version of nextprop that does not alter return values. */
 char * __prom_nextprop(int node, char * oprop)
 {
index 3835362..43d9229 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Wed Jul 12 14:00:58 2006
+# Linux kernel version: 2.6.18-rc2
+# Fri Jul 21 14:19:24 2006
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -36,6 +36,7 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
@@ -1120,7 +1121,7 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
-# CONFIG_USB_CY7C63 is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
 # CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
@@ -1279,7 +1280,6 @@ CONFIG_RAMFS=y
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
index f8ef2f2..ec10f7e 100644 (file)
@@ -66,9 +66,6 @@ static int check_cpu_node(struct device_node *dp, int *cur_inst,
                          void *compare_arg,
                          struct device_node **dev_node, int *mid)
 {
-       if (strcmp(dp->type, "cpu"))
-               return -ENODEV;
-
        if (!compare(dp, *cur_inst, compare_arg)) {
                if (dev_node)
                        *dev_node = dp;
index 7064cee..238bbf6 100644 (file)
@@ -542,9 +542,17 @@ static void __init build_device_resources(struct of_device *op,
        /* Convert to num-cells.  */
        num_reg /= 4;
 
-       /* Conver to num-entries.  */
+       /* Convert to num-entries.  */
        num_reg /= na + ns;
 
+       /* Prevent overruning the op->resources[] array.  */
+       if (num_reg > PROMREG_MAX) {
+               printk(KERN_WARNING "%s: Too many regs (%d), "
+                      "limiting to %d.\n",
+                      op->node->full_name, num_reg, PROMREG_MAX);
+               num_reg = PROMREG_MAX;
+       }
+
        for (index = 0; index < num_reg; index++) {
                struct resource *r = &op->resource[index];
                u32 addr[OF_MAX_ADDR_CELLS];
@@ -650,8 +658,22 @@ apply_interrupt_map(struct device_node *dp, struct device_node *pp,
        next:
                imap += (na + 3);
        }
-       if (i == imlen)
+       if (i == imlen) {
+               /* Psycho and Sabre PCI controllers can have 'interrupt-map'
+                * properties that do not include the on-board device
+                * interrupts.  Instead, the device's 'interrupts' property
+                * is already a fully specified INO value.
+                *
+                * Handle this by deciding that, if we didn't get a
+                * match in the parent's 'interrupt-map', and the
+                * parent is an IRQ translater, then use the parent as
+                * our IRQ controller.
+                */
+               if (pp->irq_trans)
+                       return pp;
+
                return NULL;
+       }
 
        *irq_p = irq;
        cp = of_find_node_by_phandle(handle);
@@ -803,6 +825,14 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
                op->num_irqs = 0;
        }
 
+       /* Prevent overruning the op->irqs[] array.  */
+       if (op->num_irqs > PROMINTR_MAX) {
+               printk(KERN_WARNING "%s: Too many irqs (%d), "
+                      "limiting to %d.\n",
+                      dp->full_name, op->num_irqs, PROMINTR_MAX);
+               op->num_irqs = PROMINTR_MAX;
+       }
+
        build_device_resources(op, parent);
        for (i = 0; i < op->num_irqs; i++)
                op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]);
index c86007a..5cc5ab6 100644 (file)
@@ -344,10 +344,12 @@ static unsigned long __psycho_onboard_imap_off[] = {
 /*0x2f*/       PSYCHO_IMAP_CE,
 /*0x30*/       PSYCHO_IMAP_A_ERR,
 /*0x31*/       PSYCHO_IMAP_B_ERR,
-/*0x32*/       PSYCHO_IMAP_PMGMT
+/*0x32*/       PSYCHO_IMAP_PMGMT,
+/*0x33*/       PSYCHO_IMAP_GFX,
+/*0x34*/       PSYCHO_IMAP_EUPA,
 };
 #define PSYCHO_ONBOARD_IRQ_BASE                0x20
-#define PSYCHO_ONBOARD_IRQ_LAST                0x32
+#define PSYCHO_ONBOARD_IRQ_LAST                0x34
 #define psycho_onboard_imap_offset(__ino) \
        __psycho_onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE]
 
@@ -529,6 +531,10 @@ static unsigned long __sabre_onboard_imap_off[] = {
 /*0x2e*/       SABRE_IMAP_UE,
 /*0x2f*/       SABRE_IMAP_CE,
 /*0x30*/       SABRE_IMAP_PCIERR,
+/*0x31*/       0 /* reserved */,
+/*0x32*/       0 /* reserved */,
+/*0x33*/       SABRE_IMAP_GFX,
+/*0x34*/       SABRE_IMAP_EUPA,
 };
 #define SABRE_ONBOARD_IRQ_BASE         0x20
 #define SABRE_ONBOARD_IRQ_LAST         0x30
@@ -895,6 +901,8 @@ static unsigned long sysio_irq_offsets[] = {
        SYSIO_IMAP_CE,
        SYSIO_IMAP_SBERR,
        SYSIO_IMAP_PMGMT,
+       SYSIO_IMAP_GFX,
+       SYSIO_IMAP_EUPA,
 };
 
 #undef bogon
index 237524d..beffc82 100644 (file)
@@ -254,7 +254,6 @@ EXPORT_SYMBOL(prom_getproperty);
 EXPORT_SYMBOL(prom_node_has_property);
 EXPORT_SYMBOL(prom_setprop);
 EXPORT_SYMBOL(saved_command_line);
-EXPORT_SYMBOL(prom_getname);
 EXPORT_SYMBOL(prom_finddevice);
 EXPORT_SYMBOL(prom_feval);
 EXPORT_SYMBOL(prom_getbool);
index 51c056d..054d0ab 100644 (file)
@@ -701,21 +701,21 @@ extern void check_pending(int signum);
 
 asmlinkage long sys_getdomainname(char __user *name, int len)
 {
-        int nlen;
-       int err = -EFAULT;
+        int nlen, err;
+
+       if (len < 0 || len > __NEW_UTS_LEN)
+               return -EINVAL;
 
        down_read(&uts_sem);
        
        nlen = strlen(system_utsname.domainname) + 1;
-
         if (nlen < len)
                 len = nlen;
-       if (len > __NEW_UTS_LEN)
-               goto done;
-       if (copy_to_user(name, system_utsname.domainname, len))
-               goto done;
-       err = 0;
-done:
+
+       err = -EFAULT;
+       if (!copy_to_user(name, system_utsname.domainname, len))
+               err = 0;
+
        up_read(&uts_sem);
        return err;
 }
index 1605967..55ae802 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/kprobes.h>
+#include <linux/kallsyms.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -132,6 +133,8 @@ static void bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr)
 
        printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n",
               regs->tpc);
+       printk(KERN_CRIT "OOPS: RPC [%016lx]\n", regs->u_regs[15]);
+       print_symbol("RPC: <%s>\n", regs->u_regs[15]);
        printk(KERN_CRIT "OOPS: Fault was to vaddr[%lx]\n", vaddr);
        __asm__("mov %%sp, %0" : "=r" (ksp));
        show_stack(current, ksp);
index 49075ab..500f05e 100644 (file)
@@ -193,91 +193,6 @@ prom_searchsiblings(int node_start, const char *nodename)
        return 0;
 }
 
-/* Gets name in the {name@x,yyyyy|name (if no reg)} form */
-int 
-prom_getname (int node, char *buffer, int len)
-{
-       int i, sbus = 0;
-       int pci = 0, ebus = 0, ide = 0;
-       struct linux_prom_registers *reg;
-       struct linux_prom64_registers reg64[PROMREG_MAX];
-       
-       for (sbus = prom_getparent (node); sbus; sbus = prom_getparent (sbus)) {
-               i = prom_getproperty (sbus, "name", buffer, len);
-               if (i > 0) {
-                       buffer [i] = 0;
-                       if (!strcmp (buffer, "sbus"))
-                               goto getit;
-               }
-       }
-       if ((pci = prom_getparent (node))) {
-               i = prom_getproperty (pci, "name", buffer, len);
-               if (i > 0) {
-                       buffer [i] = 0;
-                       if (!strcmp (buffer, "pci"))
-                               goto getit;
-               }
-               pci = 0;
-       }
-       if ((ebus = prom_getparent (node))) {
-               i = prom_getproperty (ebus, "name", buffer, len);
-               if (i > 0) {
-                       buffer[i] = 0;
-                       if (!strcmp (buffer, "ebus"))
-                               goto getit;
-               }
-               ebus = 0;
-       }
-       if ((ide = prom_getparent (node))) {
-               i = prom_getproperty (ide, "name", buffer, len);
-               if (i > 0) {
-                       buffer [i] = 0;
-                       if (!strcmp (buffer, "ide"))
-                               goto getit;
-               }
-               ide = 0;
-       }
-getit:
-       i = prom_getproperty (node, "name", buffer, len);
-       if (i <= 0) {
-               buffer [0] = 0;
-               return -1;
-       }
-       buffer [i] = 0;
-       len -= i;
-       i = prom_getproperty (node, "reg", (char *)reg64, sizeof (reg64));
-       if (i <= 0) return 0;
-       if (len < 16) return -1;
-       buffer = strchr (buffer, 0);
-       if (sbus) {
-               reg = (struct linux_prom_registers *)reg64;
-               sprintf (buffer, "@%x,%x", reg[0].which_io, (uint)reg[0].phys_addr);
-       } else if (pci) {
-               int dev, fn;
-               reg = (struct linux_prom_registers *)reg64;
-               fn = (reg[0].which_io >> 8) & 0x07;
-               dev = (reg[0].which_io >> 11) & 0x1f;
-               if (fn)
-                       sprintf (buffer, "@%x,%x", dev, fn);
-               else
-                       sprintf (buffer, "@%x", dev);
-       } else if (ebus) {
-               reg = (struct linux_prom_registers *)reg64;
-               sprintf (buffer, "@%x,%x", reg[0].which_io, reg[0].phys_addr);
-       } else if (ide) {
-               reg = (struct linux_prom_registers *)reg64;
-               sprintf (buffer, "@%x,%x", reg[0].which_io, reg[0].phys_addr);
-       } else if (i == 4) {    /* Happens on 8042's children on Ultra/PCI. */
-               reg = (struct linux_prom_registers *)reg64;
-               sprintf (buffer, "@%x", reg[0].which_io);
-       } else {
-               sprintf (buffer, "@%x,%x",
-                        (unsigned int)(reg64[0].phys_addr >> 36),
-                        (unsigned int)(reg64[0].phys_addr));
-       }
-       return 0;
-}
-
 /* Return the first property type for node 'node'.
  * buffer should be at least 32B in length
  */
index 9b5bb41..5d4a7d1 100644 (file)
@@ -103,7 +103,7 @@ ENTRY(ia32_sysenter_target)
        pushq   %rax
        CFI_ADJUST_CFA_OFFSET 8
        cld
-       SAVE_ARGS 0,0,1
+       SAVE_ARGS 0,0,0
        /* no need to do an access_ok check here because rbp has been
           32bit zero extended */ 
 1:     movl    (%rbp),%r9d
index b9ff759..e0341c6 100644 (file)
@@ -193,7 +193,7 @@ unsigned long profile_pc(struct pt_regs *regs)
           is just accounted to the spinlock function.
           Better would be to write these functions in assembler again
           and check exactly. */
-       if (in_lock_functions(pc)) {
+       if (!user_mode(regs) && in_lock_functions(pc)) {
                char *v = *(char **)regs->rsp;
                if ((v >= _stext && v <= _etext) ||
                        (v >= _sinittext && v <= _einittext) ||
index eb39a27..f7a9d14 100644 (file)
@@ -254,7 +254,6 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
 {
        const unsigned cpu = safe_smp_processor_id();
        unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr;
-       int i = 11;
        unsigned used = 0;
 
        printk("\nCall Trace:\n");
@@ -275,11 +274,20 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
                        if (unwind_init_blocked(&info, tsk) == 0)
                                unw_ret = show_trace_unwind(&info, NULL);
                }
-               if (unw_ret > 0) {
-                       if (call_trace > 0)
+               if (unw_ret > 0 && !arch_unw_user_mode(&info)) {
+#ifdef CONFIG_STACK_UNWIND
+                       unsigned long rip = info.regs.rip;
+                       print_symbol("DWARF2 unwinder stuck at %s\n", rip);
+                       if (call_trace == 1) {
+                               printk("Leftover inexact backtrace:\n");
+                               stack = (unsigned long *)info.regs.rsp;
+                       } else if (call_trace > 1)
                                return;
-                       printk("Legacy call trace:");
-                       i = 18;
+                       else
+                               printk("Full inexact backtrace again:\n");
+#else
+                       printk("Inexact backtrace:\n");
+#endif
                }
        }
 
@@ -1118,8 +1126,10 @@ static int __init call_trace_setup(char *s)
                call_trace = -1;
        else if (strcmp(s, "both") == 0)
                call_trace = 0;
-       else if (strcmp(s, "new") == 0)
+       else if (strcmp(s, "newfallback") == 0)
                call_trace = 1;
+       else if (strcmp(s, "new") == 0)
+               call_trace = 2;
        return 1;
 }
 __setup("call_trace=", call_trace_setup);
index b8c0702..265f7a8 100644 (file)
@@ -80,7 +80,7 @@ static u32 bio_act[5] __read_mostly = { 0, BLK_TC_ACT(BLK_TC_BARRIER), BLK_TC_AC
 #define trace_sync_bit(rw)     \
        (((rw) & (1 << BIO_RW_SYNC)) >> (BIO_RW_SYNC - 1))
 #define trace_ahead_bit(rw)    \
-       (((rw) & (1 << BIO_RW_AHEAD)) << (BIO_RW_AHEAD - 0))
+       (((rw) & (1 << BIO_RW_AHEAD)) << (2 - BIO_RW_AHEAD))
 
 /*
  * The worker for the various blk_add_trace*() types. Fills out a
index 102ebc2..aae3123 100644 (file)
@@ -936,7 +936,7 @@ static int cfq_arm_slice_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq)
         * seeks. so allow a little bit of time for him to submit a new rq
         */
        if (sample_valid(cic->seek_samples) && CIC_SEEKY(cic))
-               sl = 2;
+               sl = min(sl, msecs_to_jiffies(2));
 
        mod_timer(&cfqd->idle_slice_timer, jiffies + sl);
        return 1;
index 1c4df22..7b0eca7 100644 (file)
@@ -1233,6 +1233,50 @@ static inline void complete_buffers(struct bio *bio, int status)
        }
 }
 
+static void cciss_check_queues(ctlr_info_t *h)
+{
+       int start_queue = h->next_to_run;
+       int i;
+
+       /* check to see if we have maxed out the number of commands that can
+        * be placed on the queue.  If so then exit.  We do this check here
+        * in case the interrupt we serviced was from an ioctl and did not
+        * free any new commands.
+        */
+       if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS)
+               return;
+
+       /* We have room on the queue for more commands.  Now we need to queue
+        * them up.  We will also keep track of the next queue to run so
+        * that every queue gets a chance to be started first.
+        */
+       for (i = 0; i < h->highest_lun + 1; i++) {
+               int curr_queue = (start_queue + i) % (h->highest_lun + 1);
+               /* make sure the disk has been added and the drive is real
+                * because this can be called from the middle of init_one.
+                */
+               if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads))
+                       continue;
+               blk_start_queue(h->gendisk[curr_queue]->queue);
+
+               /* check to see if we have maxed out the number of commands
+                * that can be placed on the queue.
+                */
+               if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) {
+                       if (curr_queue == start_queue) {
+                               h->next_to_run =
+                                   (start_queue + 1) % (h->highest_lun + 1);
+                               break;
+                       } else {
+                               h->next_to_run = curr_queue;
+                               break;
+                       }
+               } else {
+                       curr_queue = (curr_queue + 1) % (h->highest_lun + 1);
+               }
+       }
+}
+
 static void cciss_softirq_done(struct request *rq)
 {
        CommandList_struct *cmd = rq->completion_data;
@@ -1264,6 +1308,7 @@ static void cciss_softirq_done(struct request *rq)
        spin_lock_irqsave(&h->lock, flags);
        end_that_request_last(rq, rq->errors);
        cmd_free(h, cmd, 1);
+       cciss_check_queues(h);
        spin_unlock_irqrestore(&h->lock, flags);
 }
 
@@ -2528,8 +2573,6 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
        CommandList_struct *c;
        unsigned long flags;
        __u32 a, a1, a2;
-       int j;
-       int start_queue = h->next_to_run;
 
        if (interrupt_not_for_us(h))
                return IRQ_NONE;
@@ -2588,45 +2631,6 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
                }
        }
 
-       /* check to see if we have maxed out the number of commands that can
-        * be placed on the queue.  If so then exit.  We do this check here
-        * in case the interrupt we serviced was from an ioctl and did not
-        * free any new commands.
-        */
-       if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS)
-               goto cleanup;
-
-       /* We have room on the queue for more commands.  Now we need to queue
-        * them up.  We will also keep track of the next queue to run so
-        * that every queue gets a chance to be started first.
-        */
-       for (j = 0; j < h->highest_lun + 1; j++) {
-               int curr_queue = (start_queue + j) % (h->highest_lun + 1);
-               /* make sure the disk has been added and the drive is real
-                * because this can be called from the middle of init_one.
-                */
-               if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads))
-                       continue;
-               blk_start_queue(h->gendisk[curr_queue]->queue);
-
-               /* check to see if we have maxed out the number of commands
-                * that can be placed on the queue.
-                */
-               if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) {
-                       if (curr_queue == start_queue) {
-                               h->next_to_run =
-                                   (start_queue + 1) % (h->highest_lun + 1);
-                               goto cleanup;
-                       } else {
-                               h->next_to_run = curr_queue;
-                               goto cleanup;
-                       }
-               } else {
-                       curr_queue = (curr_queue + 1) % (h->highest_lun + 1);
-               }
-       }
-
-      cleanup:
        spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
        return IRQ_HANDLED;
 }
index 6a0c223..e2d4bea 100644 (file)
@@ -67,6 +67,8 @@ static int ignore = 0;
 static int ignore_dga = 0;
 static int ignore_csr = 0;
 static int ignore_sniffer = 0;
+static int disable_scofix = 0;
+static int force_scofix = 0;
 static int reset = 0;
 
 #ifdef CONFIG_BT_HCIUSB_SCO
@@ -107,9 +109,12 @@ static struct usb_device_id blacklist_ids[] = {
        { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE },
 
        /* Broadcom BCM2035 */
-       { USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_BROKEN_ISOC },
+       { USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
        { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 },
 
+       /* IBM/Lenovo ThinkPad with Broadcom chip */
+       { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU },
+
        /* Microsoft Wireless Transceiver for Bluetooth 2.0 */
        { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
 
@@ -119,11 +124,13 @@ static struct usb_device_id blacklist_ids[] = {
        /* ISSC Bluetooth Adapter v3.1 */
        { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
 
-       /* RTX Telecom based adapter with buggy SCO support */
+       /* RTX Telecom based adapters with buggy SCO support */
        { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
+       { USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC },
 
-       /* Belkin F8T012 */
+       /* Belkin F8T012 and F8T013 devices */
        { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU },
+       { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_WRONG_SCO_MTU },
 
        /* Digianswer devices */
        { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
@@ -990,8 +997,10 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
        if (reset || id->driver_info & HCI_RESET)
                set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
 
-       if (id->driver_info & HCI_WRONG_SCO_MTU)
-               set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
+       if (force_scofix || id->driver_info & HCI_WRONG_SCO_MTU) {
+               if (!disable_scofix)
+                       set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
+       }
 
        if (id->driver_info & HCI_SNIFFER) {
                if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
@@ -1161,6 +1170,12 @@ MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
 module_param(ignore_sniffer, bool, 0644);
 MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
 
+module_param(disable_scofix, bool, 0644);
+MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");
+
+module_param(force_scofix, bool, 0644);
+MODULE_PARM_DESC(force_scofix, "Force fixup of wrong SCO buffers size");
+
 module_param(reset, bool, 0644);
 MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
 
index 17bc8ab..00f574c 100644 (file)
@@ -1174,8 +1174,12 @@ static void dcd_change(MGSLPC_INFO *info)
        else
                info->input_signal_events.dcd_down++;
 #ifdef CONFIG_HDLC
-       if (info->netcount)
-               hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, info->netdev);
+       if (info->netcount) {
+               if (info->serial_signals & SerialSignal_DCD)
+                       netif_carrier_on(info->netdev);
+               else
+                       netif_carrier_off(info->netdev);
+       }
 #endif
        wake_up_interruptible(&info->status_event_wait_q);
        wake_up_interruptible(&info->event_wait_q);
@@ -4251,8 +4255,10 @@ static int hdlcdev_open(struct net_device *dev)
        spin_lock_irqsave(&info->lock, flags);
        get_signals(info);
        spin_unlock_irqrestore(&info->lock, flags);
-       hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, dev);
-
+       if (info->serial_signals & SerialSignal_DCD)
+               netif_carrier_on(dev);
+       else
+               netif_carrier_off(dev);
        return 0;
 }
 
index df782dd..78b1b1a 100644 (file)
@@ -1344,8 +1344,12 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info )
                        } else
                                info->input_signal_events.dcd_down++;
 #ifdef CONFIG_HDLC
-                       if (info->netcount)
-                               hdlc_set_carrier(status & MISCSTATUS_DCD, info->netdev);
+                       if (info->netcount) {
+                               if (status & MISCSTATUS_DCD)
+                                       netif_carrier_on(info->netdev);
+                               else
+                                       netif_carrier_off(info->netdev);
+                       }
 #endif
                }
                if (status & MISCSTATUS_CTS_LATCHED)
@@ -7844,8 +7848,10 @@ static int hdlcdev_open(struct net_device *dev)
        spin_lock_irqsave(&info->irq_spinlock, flags);
        usc_get_serial_signals(info);
        spin_unlock_irqrestore(&info->irq_spinlock, flags);
-       hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, dev);
-
+       if (info->serial_signals & SerialSignal_DCD)
+               netif_carrier_on(dev);
+       else
+               netif_carrier_off(dev);
        return 0;
 }
 
index e829594..b2dbbdb 100644 (file)
@@ -1497,8 +1497,10 @@ static int hdlcdev_open(struct net_device *dev)
        spin_lock_irqsave(&info->lock, flags);
        get_signals(info);
        spin_unlock_irqrestore(&info->lock, flags);
-       hdlc_set_carrier(info->signals & SerialSignal_DCD, dev);
-
+       if (info->signals & SerialSignal_DCD)
+               netif_carrier_on(dev);
+       else
+               netif_carrier_off(dev);
        return 0;
 }
 
@@ -1997,8 +1999,12 @@ static void dcd_change(struct slgt_info *info)
                info->input_signal_events.dcd_down++;
        }
 #ifdef CONFIG_HDLC
-       if (info->netcount)
-               hdlc_set_carrier(info->signals & SerialSignal_DCD, info->netdev);
+       if (info->netcount) {
+               if (info->signals & SerialSignal_DCD)
+                       netif_carrier_on(info->netdev);
+               else
+                       netif_carrier_off(info->netdev);
+       }
 #endif
        wake_up_interruptible(&info->status_event_wait_q);
        wake_up_interruptible(&info->event_wait_q);
index 1e443a2..66f3754 100644 (file)
@@ -1752,8 +1752,10 @@ static int hdlcdev_open(struct net_device *dev)
        spin_lock_irqsave(&info->lock, flags);
        get_signals(info);
        spin_unlock_irqrestore(&info->lock, flags);
-       hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, dev);
-
+       if (info->serial_signals & SerialSignal_DCD)
+               netif_carrier_on(dev);
+       else
+               netif_carrier_off(dev);
        return 0;
 }
 
@@ -2522,8 +2524,12 @@ void isr_io_pin( SLMP_INFO *info, u16 status )
                        } else
                                info->input_signal_events.dcd_down++;
 #ifdef CONFIG_HDLC
-                       if (info->netcount)
-                               hdlc_set_carrier(status & SerialSignal_DCD, info->netdev);
+                       if (info->netcount) {
+                               if (status & SerialSignal_DCD)
+                                       netif_carrier_on(info->netdev);
+                               else
+                                       netif_carrier_off(info->netdev);
+                       }
 #endif
                }
                if (status & MISCSTATUS_CTS_LATCHED)
index 8d32818..bc1088d 100644 (file)
@@ -364,10 +364,12 @@ static ssize_t store_##file_name                                  \
        if (ret != 1)                                                   \
                return -EINVAL;                                         \
                                                                        \
+       lock_cpu_hotplug();                                             \
        mutex_lock(&policy->lock);                                      \
        ret = __cpufreq_set_policy(policy, &new_policy);                \
        policy->user_policy.object = policy->object;                    \
        mutex_unlock(&policy->lock);                                    \
+       unlock_cpu_hotplug();                                           \
                                                                        \
        return ret ? ret : count;                                       \
 }
@@ -1197,20 +1199,18 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier);
  *********************************************************************/
 
 
+/* Must be called with lock_cpu_hotplug held */
 int __cpufreq_driver_target(struct cpufreq_policy *policy,
                            unsigned int target_freq,
                            unsigned int relation)
 {
        int retval = -EINVAL;
 
-       lock_cpu_hotplug();
        dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
                target_freq, relation);
        if (cpu_online(policy->cpu) && cpufreq_driver->target)
                retval = cpufreq_driver->target(policy, target_freq, relation);
 
-       unlock_cpu_hotplug();
-
        return retval;
 }
 EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
@@ -1225,17 +1225,23 @@ int cpufreq_driver_target(struct cpufreq_policy *policy,
        if (!policy)
                return -EINVAL;
 
+       lock_cpu_hotplug();
        mutex_lock(&policy->lock);
 
        ret = __cpufreq_driver_target(policy, target_freq, relation);
 
        mutex_unlock(&policy->lock);
+       unlock_cpu_hotplug();
 
        cpufreq_cpu_put(policy);
        return ret;
 }
 EXPORT_SYMBOL_GPL(cpufreq_driver_target);
 
+/*
+ * Locking: Must be called with the lock_cpu_hotplug() lock held
+ * when "event" is CPUFREQ_GOV_LIMITS
+ */
 
 static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
 {
@@ -1257,24 +1263,6 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
 }
 
 
-int cpufreq_governor(unsigned int cpu, unsigned int event)
-{
-       int ret = 0;
-       struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-
-       if (!policy)
-               return -EINVAL;
-
-       mutex_lock(&policy->lock);
-       ret = __cpufreq_governor(policy, event);
-       mutex_unlock(&policy->lock);
-
-       cpufreq_cpu_put(policy);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(cpufreq_governor);
-
-
 int cpufreq_register_governor(struct cpufreq_governor *governor)
 {
        struct cpufreq_governor *t;
@@ -1342,6 +1330,9 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
 EXPORT_SYMBOL(cpufreq_get_policy);
 
 
+/*
+ * Locking: Must be called with the lock_cpu_hotplug() lock held
+ */
 static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy)
 {
        int ret = 0;
@@ -1436,6 +1427,8 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
        if (!data)
                return -EINVAL;
 
+       lock_cpu_hotplug();
+
        /* lock this CPU */
        mutex_lock(&data->lock);
 
@@ -1446,6 +1439,8 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
        data->user_policy.governor = data->governor;
 
        mutex_unlock(&data->lock);
+
+       unlock_cpu_hotplug();
        cpufreq_cpu_put(data);
 
        return ret;
@@ -1469,6 +1464,7 @@ int cpufreq_update_policy(unsigned int cpu)
        if (!data)
                return -ENODEV;
 
+       lock_cpu_hotplug();
        mutex_lock(&data->lock);
 
        dprintk("updating policy for CPU %u\n", cpu);
@@ -1494,7 +1490,7 @@ int cpufreq_update_policy(unsigned int cpu)
        ret = __cpufreq_set_policy(data, &policy);
 
        mutex_unlock(&data->lock);
-
+       unlock_cpu_hotplug();
        cpufreq_cpu_put(data);
        return ret;
 }
index b3ebc8f..c4c578d 100644 (file)
@@ -525,7 +525,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                break;
 
        case CPUFREQ_GOV_LIMITS:
-               lock_cpu_hotplug();
                mutex_lock(&dbs_mutex);
                if (policy->max < this_dbs_info->cur_policy->cur)
                        __cpufreq_driver_target(
@@ -536,7 +535,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                                        this_dbs_info->cur_policy,
                                        policy->min, CPUFREQ_RELATION_L);
                mutex_unlock(&dbs_mutex);
-               unlock_cpu_hotplug();
                break;
        }
        return 0;
index 8729992..52cf1f0 100644 (file)
@@ -239,6 +239,8 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
        total_ticks = (unsigned int) cputime64_sub(cur_jiffies,
                        this_dbs_info->prev_cpu_wall);
        this_dbs_info->prev_cpu_wall = cur_jiffies;
+       if (!total_ticks)
+               return;
        /*
         * Every sampling_rate, we check, if current idle time is less
         * than 20% (default), then we try to increase frequency
@@ -304,7 +306,12 @@ static void do_dbs_timer(void *data)
        unsigned int cpu = smp_processor_id();
        struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu);
 
+       if (!dbs_info->enable)
+               return;
+
+       lock_cpu_hotplug();
        dbs_check_cpu(dbs_info);
+       unlock_cpu_hotplug();
        queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work,
                        usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
 }
@@ -319,11 +326,11 @@ static inline void dbs_timer_init(unsigned int cpu)
        return;
 }
 
-static inline void dbs_timer_exit(unsigned int cpu)
+static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
 {
-       struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu);
-
-       cancel_rearming_delayed_workqueue(kondemand_wq, &dbs_info->work);
+       dbs_info->enable = 0;
+       cancel_delayed_work(&dbs_info->work);
+       flush_workqueue(kondemand_wq);
 }
 
 static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
@@ -396,8 +403,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 
        case CPUFREQ_GOV_STOP:
                mutex_lock(&dbs_mutex);
-               dbs_timer_exit(policy->cpu);
-               this_dbs_info->enable = 0;
+               dbs_timer_exit(this_dbs_info);
                sysfs_remove_group(&policy->kobj, &dbs_attr_group);
                dbs_enable--;
                if (dbs_enable == 0)
@@ -408,7 +414,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                break;
 
        case CPUFREQ_GOV_LIMITS:
-               lock_cpu_hotplug();
                mutex_lock(&dbs_mutex);
                if (policy->max < this_dbs_info->cur_policy->cur)
                        __cpufreq_driver_target(this_dbs_info->cur_policy,
@@ -419,7 +424,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                                                policy->min,
                                                CPUFREQ_RELATION_L);
                mutex_unlock(&dbs_mutex);
-               unlock_cpu_hotplug();
                break;
        }
        return 0;
index 44ae5e5..a06c204 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/cpufreq.h>
+#include <linux/cpu.h>
 #include <linux/types.h>
 #include <linux/fs.h>
 #include <linux/sysfs.h>
@@ -70,6 +71,7 @@ static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy)
 
        dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq);
 
+       lock_cpu_hotplug();
        mutex_lock(&userspace_mutex);
        if (!cpu_is_managed[policy->cpu])
                goto err;
@@ -92,6 +94,7 @@ static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy)
 
  err:
        mutex_unlock(&userspace_mutex);
+       unlock_cpu_hotplug();
        return ret;
 }
 
index 78bf46d..dbd4d6c 100644 (file)
@@ -828,7 +828,7 @@ static int __init ioat_init_module(void)
        /* if forced, worst case is that rmmod hangs */
        __unsafe(THIS_MODULE);
 
-       return pci_module_init(&ioat_pci_drv);
+       return pci_register_driver(&ioat_pci_drv);
 }
 
 module_init(ioat_init_module);
index 66d03f2..1a159e8 100644 (file)
@@ -429,7 +429,7 @@ static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hd
                
                if (fcmd->data) {
                        if (SCpnt->use_sg)
-                               dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->buffer,
+                               dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->request_buffer,
                                                SCpnt->use_sg,
                                                SCpnt->sc_data_direction);
                        else
@@ -810,7 +810,7 @@ static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, i
                                                             SCpnt->request_bufflen,
                                                             SCpnt->sc_data_direction);
                        } else {
-                               struct scatterlist *sg = (struct scatterlist *)SCpnt->buffer;
+                               struct scatterlist *sg = (struct scatterlist *)SCpnt->request_buffer;
                                int nents;
 
                                FCD(("XXX: Use_sg %d %d\n", SCpnt->use_sg, sg->length))
index f712e4c..7cf3eb0 100644 (file)
@@ -776,7 +776,7 @@ static void update_ordered(ide_drive_t *drive)
                 * not available so we don't need to recheck that.
                 */
                capacity = idedisk_capacity(drive);
-               barrier = ide_id_has_flush_cache(id) &&
+               barrier = ide_id_has_flush_cache(id) && !drive->noflush &&
                        (drive->addressing == 0 || capacity <= (1ULL << 28) ||
                         ide_id_has_flush_cache_ext(id));
 
index 98918fb..7c3a13e 100644 (file)
@@ -750,7 +750,7 @@ void ide_dma_verbose(ide_drive_t *drive)
                        goto bug_dma_off;
                printk(", DMA");
        } else if (id->field_valid & 1) {
-               printk(", BUG");
+               goto bug_dma_off;
        }
        return;
 bug_dma_off:
index 05fbd92..defd4b4 100644 (file)
@@ -1539,7 +1539,7 @@ static int __init ide_setup(char *s)
                const char *hd_words[] = {
                        "none", "noprobe", "nowerr", "cdrom", "serialize",
                        "autotune", "noautotune", "minus8", "swapdata", "bswap",
-                       "minus11", "remap", "remap63", "scsi", NULL };
+                       "noflush", "remap", "remap63", "scsi", NULL };
                unit = s[2] - 'a';
                hw   = unit / MAX_DRIVES;
                unit = unit % MAX_DRIVES;
@@ -1578,6 +1578,9 @@ static int __init ide_setup(char *s)
                        case -10: /* "bswap" */
                                drive->bswap = 1;
                                goto done;
+                       case -11: /* noflush */
+                               drive->noflush = 1;
+                               goto done;
                        case -12: /* "remap" */
                                drive->remap_0_to_1 = 1;
                                goto done;
index 3cb0442..e9bad18 100644 (file)
@@ -498,9 +498,14 @@ static int config_chipset_for_dma (ide_drive_t *drive)
 {
        u8 speed        = ide_dma_speed(drive, it821x_ratemask(drive));
 
-       config_it821x_chipset_for_pio(drive, !speed);
-       it821x_tune_chipset(drive, speed);
-       return ide_dma_enable(drive);
+       if (speed) {
+               config_it821x_chipset_for_pio(drive, 0);
+               it821x_tune_chipset(drive, speed);
+
+               return ide_dma_enable(drive);
+       }
+
+       return 0;
 }
 
 /**
index 5ed4dab..1c3cfbb 100644 (file)
@@ -167,6 +167,15 @@ static int is_vendor_method_in_use(
        return 0;
 }
 
+int ib_response_mad(struct ib_mad *mad)
+{
+       return ((mad->mad_hdr.method & IB_MGMT_METHOD_RESP) ||
+               (mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS) ||
+               ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_BM) &&
+                (mad->mad_hdr.attr_mod & IB_BM_ATTR_MOD_RESP)));
+}
+EXPORT_SYMBOL(ib_response_mad);
+
 /*
  * ib_register_mad_agent - Register to send/receive MADs
  */
@@ -570,13 +579,6 @@ int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent)
 }
 EXPORT_SYMBOL(ib_unregister_mad_agent);
 
-static inline int response_mad(struct ib_mad *mad)
-{
-       /* Trap represses are responses although response bit is reset */
-       return ((mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS) ||
-               (mad->mad_hdr.method & IB_MGMT_METHOD_RESP));
-}
-
 static void dequeue_mad(struct ib_mad_list_head *mad_list)
 {
        struct ib_mad_queue *mad_queue;
@@ -723,7 +725,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
        switch (ret)
        {
        case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY:
-               if (response_mad(&mad_priv->mad.mad) &&
+               if (ib_response_mad(&mad_priv->mad.mad) &&
                    mad_agent_priv->agent.recv_handler) {
                        local->mad_priv = mad_priv;
                        local->recv_mad_agent = mad_agent_priv;
@@ -1551,7 +1553,7 @@ find_mad_agent(struct ib_mad_port_private *port_priv,
        unsigned long flags;
 
        spin_lock_irqsave(&port_priv->reg_lock, flags);
-       if (response_mad(mad)) {
+       if (ib_response_mad(mad)) {
                u32 hi_tid;
                struct ib_mad_agent_private *entry;
 
@@ -1799,7 +1801,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
        }
 
        /* Complete corresponding request */
-       if (response_mad(mad_recv_wc->recv_buf.mad)) {
+       if (ib_response_mad(mad_recv_wc->recv_buf.mad)) {
                spin_lock_irqsave(&mad_agent_priv->lock, flags);
                mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc);
                if (!mad_send_wr) {
index afe70a5..1273f88 100644 (file)
@@ -112,8 +112,10 @@ struct ib_umad_device {
 struct ib_umad_file {
        struct ib_umad_port    *port;
        struct list_head        recv_list;
+       struct list_head        send_list;
        struct list_head        port_list;
        spinlock_t              recv_lock;
+       spinlock_t              send_lock;
        wait_queue_head_t       recv_wait;
        struct ib_mad_agent    *agent[IB_UMAD_MAX_AGENTS];
        int                     agents_dead;
@@ -177,12 +179,21 @@ static int queue_packet(struct ib_umad_file *file,
        return ret;
 }
 
+static void dequeue_send(struct ib_umad_file *file,
+                        struct ib_umad_packet *packet)
+ {
+       spin_lock_irq(&file->send_lock);
+       list_del(&packet->list);
+       spin_unlock_irq(&file->send_lock);
+ }
+
 static void send_handler(struct ib_mad_agent *agent,
                         struct ib_mad_send_wc *send_wc)
 {
        struct ib_umad_file *file = agent->context;
        struct ib_umad_packet *packet = send_wc->send_buf->context[0];
 
+       dequeue_send(file, packet);
        ib_destroy_ah(packet->msg->ah);
        ib_free_send_mad(packet->msg);
 
@@ -370,6 +381,51 @@ static int copy_rmpp_mad(struct ib_mad_send_buf *msg, const char __user *buf)
        return 0;
 }
 
+static int same_destination(struct ib_user_mad_hdr *hdr1,
+                           struct ib_user_mad_hdr *hdr2)
+{
+       if (!hdr1->grh_present && !hdr2->grh_present)
+          return (hdr1->lid == hdr2->lid);
+
+       if (hdr1->grh_present && hdr2->grh_present)
+          return !memcmp(hdr1->gid, hdr2->gid, 16);
+
+       return 0;
+}
+
+static int is_duplicate(struct ib_umad_file *file,
+                       struct ib_umad_packet *packet)
+{
+       struct ib_umad_packet *sent_packet;
+       struct ib_mad_hdr *sent_hdr, *hdr;
+
+       hdr = (struct ib_mad_hdr *) packet->mad.data;
+       list_for_each_entry(sent_packet, &file->send_list, list) {
+               sent_hdr = (struct ib_mad_hdr *) sent_packet->mad.data;
+
+               if ((hdr->tid != sent_hdr->tid) ||
+                   (hdr->mgmt_class != sent_hdr->mgmt_class))
+                       continue;
+
+               /*
+                * No need to be overly clever here.  If two new operations have
+                * the same TID, reject the second as a duplicate.  This is more
+                * restrictive than required by the spec.
+                */
+               if (!ib_response_mad((struct ib_mad *) hdr)) {
+                       if (!ib_response_mad((struct ib_mad *) sent_hdr))
+                               return 1;
+                       continue;
+               } else if (!ib_response_mad((struct ib_mad *) sent_hdr))
+                       continue;
+
+               if (same_destination(&packet->mad.hdr, &sent_packet->mad.hdr))
+                       return 1;
+       }
+
+       return 0;
+}
+
 static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
                             size_t count, loff_t *pos)
 {
@@ -379,7 +435,6 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
        struct ib_ah_attr ah_attr;
        struct ib_ah *ah;
        struct ib_rmpp_mad *rmpp_mad;
-       u8 method;
        __be64 *tid;
        int ret, data_len, hdr_len, copy_offset, rmpp_active;
 
@@ -473,28 +528,36 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
        }
 
        /*
-        * If userspace is generating a request that will generate a
-        * response, we need to make sure the high-order part of the
-        * transaction ID matches the agent being used to send the
-        * MAD.
+        * Set the high-order part of the transaction ID to make MADs from
+        * different agents unique, and allow routing responses back to the
+        * original requestor.
         */
-       method = ((struct ib_mad_hdr *) packet->msg->mad)->method;
-
-       if (!(method & IB_MGMT_METHOD_RESP)       &&
-           method != IB_MGMT_METHOD_TRAP_REPRESS &&
-           method != IB_MGMT_METHOD_SEND) {
+       if (!ib_response_mad(packet->msg->mad)) {
                tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid;
                *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 |
                                   (be64_to_cpup(tid) & 0xffffffff));
+               rmpp_mad->mad_hdr.tid = *tid;
+       }
+
+       spin_lock_irq(&file->send_lock);
+       ret = is_duplicate(file, packet);
+       if (!ret)
+               list_add_tail(&packet->list, &file->send_list);
+       spin_unlock_irq(&file->send_lock);
+       if (ret) {
+               ret = -EINVAL;
+               goto err_msg;
        }
 
        ret = ib_post_send_mad(packet->msg, NULL);
        if (ret)
-               goto err_msg;
+               goto err_send;
 
        up_read(&file->port->mutex);
        return count;
 
+err_send:
+       dequeue_send(file, packet);
 err_msg:
        ib_free_send_mad(packet->msg);
 err_ah:
@@ -657,7 +720,9 @@ static int ib_umad_open(struct inode *inode, struct file *filp)
        }
 
        spin_lock_init(&file->recv_lock);
+       spin_lock_init(&file->send_lock);
        INIT_LIST_HEAD(&file->recv_list);
+       INIT_LIST_HEAD(&file->send_list);
        init_waitqueue_head(&file->recv_wait);
 
        file->port = port;
index bdf5d50..30923eb 100644 (file)
 
 #include "uverbs.h"
 
+static struct lock_class_key pd_lock_key;
+static struct lock_class_key mr_lock_key;
+static struct lock_class_key cq_lock_key;
+static struct lock_class_key qp_lock_key;
+static struct lock_class_key ah_lock_key;
+static struct lock_class_key srq_lock_key;
+
 #define INIT_UDATA(udata, ibuf, obuf, ilen, olen)                      \
        do {                                                            \
                (udata)->inbuf  = (void __user *) (ibuf);               \
  */
 
 static void init_uobj(struct ib_uobject *uobj, u64 user_handle,
-                     struct ib_ucontext *context)
+                     struct ib_ucontext *context, struct lock_class_key *key)
 {
        uobj->user_handle = user_handle;
        uobj->context     = context;
        kref_init(&uobj->ref);
        init_rwsem(&uobj->mutex);
+       lockdep_set_class(&uobj->mutex, key);
        uobj->live        = 0;
 }
 
@@ -470,7 +478,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
        if (!uobj)
                return -ENOMEM;
 
-       init_uobj(uobj, 0, file->ucontext);
+       init_uobj(uobj, 0, file->ucontext, &pd_lock_key);
        down_write(&uobj->mutex);
 
        pd = file->device->ib_dev->alloc_pd(file->device->ib_dev,
@@ -591,7 +599,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
        if (!obj)
                return -ENOMEM;
 
-       init_uobj(&obj->uobject, 0, file->ucontext);
+       init_uobj(&obj->uobject, 0, file->ucontext, &mr_lock_key);
        down_write(&obj->uobject.mutex);
 
        /*
@@ -770,7 +778,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
        if (!obj)
                return -ENOMEM;
 
-       init_uobj(&obj->uobject, cmd.user_handle, file->ucontext);
+       init_uobj(&obj->uobject, cmd.user_handle, file->ucontext, &cq_lock_key);
        down_write(&obj->uobject.mutex);
 
        if (cmd.comp_channel >= 0) {
@@ -1051,13 +1059,14 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
        if (!obj)
                return -ENOMEM;
 
-       init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext);
+       init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_key);
        down_write(&obj->uevent.uobject.mutex);
 
+       srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL;
        pd  = idr_read_pd(cmd.pd_handle, file->ucontext);
        scq = idr_read_cq(cmd.send_cq_handle, file->ucontext);
-       rcq = idr_read_cq(cmd.recv_cq_handle, file->ucontext);
-       srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL;
+       rcq = cmd.recv_cq_handle == cmd.send_cq_handle ?
+               scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext);
 
        if (!pd || !scq || !rcq || (cmd.is_srq && !srq)) {
                ret = -EINVAL;
@@ -1125,7 +1134,8 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
 
        put_pd_read(pd);
        put_cq_read(scq);
-       put_cq_read(rcq);
+       if (rcq != scq)
+               put_cq_read(rcq);
        if (srq)
                put_srq_read(srq);
 
@@ -1150,7 +1160,7 @@ err_put:
                put_pd_read(pd);
        if (scq)
                put_cq_read(scq);
-       if (rcq)
+       if (rcq && rcq != scq)
                put_cq_read(rcq);
        if (srq)
                put_srq_read(srq);
@@ -1751,7 +1761,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
        if (!uobj)
                return -ENOMEM;
 
-       init_uobj(uobj, cmd.user_handle, file->ucontext);
+       init_uobj(uobj, cmd.user_handle, file->ucontext, &ah_lock_key);
        down_write(&uobj->mutex);
 
        pd = idr_read_pd(cmd.pd_handle, file->ucontext);
@@ -1775,7 +1785,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
        ah = ib_create_ah(pd, &attr);
        if (IS_ERR(ah)) {
                ret = PTR_ERR(ah);
-               goto err;
+               goto err_put;
        }
 
        ah->uobject  = uobj;
@@ -1811,6 +1821,9 @@ err_copy:
 err_destroy:
        ib_destroy_ah(ah);
 
+err_put:
+       put_pd_read(pd);
+
 err:
        put_uobj_write(uobj);
        return ret;
@@ -1963,7 +1976,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
        if (!obj)
                return -ENOMEM;
 
-       init_uobj(&obj->uobject, cmd.user_handle, file->ucontext);
+       init_uobj(&obj->uobject, cmd.user_handle, file->ucontext, &srq_lock_key);
        down_write(&obj->uobject.mutex);
 
        pd  = idr_read_pd(cmd.pd_handle, file->ucontext);
@@ -1984,7 +1997,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
        srq = pd->device->create_srq(pd, &attr, &udata);
        if (IS_ERR(srq)) {
                ret = PTR_ERR(srq);
-               goto err;
+               goto err_put;
        }
 
        srq->device        = pd->device;
@@ -2029,6 +2042,9 @@ err_copy:
 err_destroy:
        ib_destroy_srq(srq);
 
+err_put:
+       put_pd_read(pd);
+
 err:
        put_uobj_write(&obj->uobject);
        return ret;
index 823131d..f98518d 100644 (file)
@@ -859,6 +859,38 @@ static void ipath_rcv_layer(struct ipath_devdata *dd, u32 etail,
                __ipath_layer_rcv_lid(dd, hdr);
 }
 
+static void ipath_rcv_hdrerr(struct ipath_devdata *dd,
+                            u32 eflags,
+                            u32 l,
+                            u32 etail,
+                            u64 *rc)
+{
+       char emsg[128];
+       struct ipath_message_header *hdr;
+
+       get_rhf_errstring(eflags, emsg, sizeof emsg);
+       hdr = (struct ipath_message_header *)&rc[1];
+       ipath_cdbg(PKT, "RHFerrs %x hdrqtail=%x typ=%u "
+                  "tlen=%x opcode=%x egridx=%x: %s\n",
+                  eflags, l,
+                  ipath_hdrget_rcv_type((__le32 *) rc),
+                  ipath_hdrget_length_in_bytes((__le32 *) rc),
+                  be32_to_cpu(hdr->bth[0]) >> 24,
+                  etail, emsg);
+
+       /* Count local link integrity errors. */
+       if (eflags & (INFINIPATH_RHF_H_ICRCERR | INFINIPATH_RHF_H_VCRCERR)) {
+               u8 n = (dd->ipath_ibcctrl >>
+                       INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) &
+                       INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK;
+
+               if (++dd->ipath_lli_counter > n) {
+                       dd->ipath_lli_counter = 0;
+                       dd->ipath_lli_errors++;
+               }
+       }
+}
+
 /*
  * ipath_kreceive - receive a packet
  * @dd: the infinipath device
@@ -875,7 +907,6 @@ void ipath_kreceive(struct ipath_devdata *dd)
        struct ipath_message_header *hdr;
        u32 eflags, i, etype, tlen, pkttot = 0, updegr=0, reloop=0;
        static u64 totcalls;    /* stats, may eventually remove */
-       char emsg[128];
 
        if (!dd->ipath_hdrqtailptr) {
                ipath_dev_err(dd,
@@ -938,26 +969,9 @@ reloop:
                                   "%x\n", etype);
                }
 
-               if (eflags & ~(INFINIPATH_RHF_H_TIDERR |
-                              INFINIPATH_RHF_H_IHDRERR)) {
-                       get_rhf_errstring(eflags, emsg, sizeof emsg);
-                       ipath_cdbg(PKT, "RHFerrs %x hdrqtail=%x typ=%u "
-                                  "tlen=%x opcode=%x egridx=%x: %s\n",
-                                  eflags, l, etype, tlen, bthbytes[0],
-                                  ipath_hdrget_index((__le32 *) rc), emsg);
-                       /* Count local link integrity errors. */
-                       if (eflags & (INFINIPATH_RHF_H_ICRCERR |
-                                     INFINIPATH_RHF_H_VCRCERR)) {
-                               u8 n = (dd->ipath_ibcctrl >>
-                                       INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) &
-                                       INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK;
-
-                               if (++dd->ipath_lli_counter > n) {
-                                       dd->ipath_lli_counter = 0;
-                                       dd->ipath_lli_errors++;
-                               }
-                       }
-               } else if (etype == RCVHQ_RCV_TYPE_NON_KD) {
+               if (unlikely(eflags))
+                       ipath_rcv_hdrerr(dd, eflags, l, etail, rc);
+               else if (etype == RCVHQ_RCV_TYPE_NON_KD) {
                                int ret = __ipath_verbs_rcv(dd, rc + 1,
                                                            ebuf, tlen);
                                if (ret == -ENODEV)
@@ -981,25 +995,7 @@ reloop:
                else if (etype == RCVHQ_RCV_TYPE_EXPECTED)
                        ipath_dbg("Bug: Expected TID, opcode %x; ignored\n",
                                  be32_to_cpu(hdr->bth[0]) & 0xff);
-               else if (eflags & (INFINIPATH_RHF_H_TIDERR |
-                                  INFINIPATH_RHF_H_IHDRERR)) {
-                       /*
-                        * This is a type 3 packet, only the LRH is in the
-                        * rcvhdrq, the rest of the header is in the eager
-                        * buffer.
-                        */
-                       u8 opcode;
-                       if (ebuf) {
-                               bthbytes = (u8 *) ebuf;
-                               opcode = *bthbytes;
-                       }
-                       else
-                               opcode = 0;
-                       get_rhf_errstring(eflags, emsg, sizeof emsg);
-                       ipath_dbg("Err %x (%s), opcode %x, egrbuf %x, "
-                                 "len %x\n", eflags, emsg, opcode, etail,
-                                 tlen);
-               } else {
+               else {
                        /*
                         * error packet, type of error  unknown.
                         * Probably type 3, but we don't know, so don't
index 46773c6..a5ca279 100644 (file)
@@ -197,6 +197,21 @@ int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
        size_t off;
        int ret;
 
+       /*
+        * We use RKEY == zero for physical addresses
+        * (see ipath_get_dma_mr).
+        */
+       if (rkey == 0) {
+               sge->mr = NULL;
+               sge->vaddr = phys_to_virt(vaddr);
+               sge->length = len;
+               sge->sge_length = len;
+               ss->sg_list = NULL;
+               ss->num_sge = 1;
+               ret = 1;
+               goto bail;
+       }
+
        mr = rkt->table[(rkey >> (32 - ib_ipath_lkey_table_size))];
        if (unlikely(mr == NULL || mr->lkey != rkey)) {
                ret = 0;
index 56ac336..d70a9b6 100644 (file)
@@ -191,10 +191,6 @@ void ipath_skip_sge(struct ipath_sge_state *ss, u32 length)
 {
        struct ipath_sge *sge = &ss->sge;
 
-       while (length > sge->sge_length) {
-               length -= sge->sge_length;
-               ss->sge = *ss->sg_list++;
-       }
        while (length) {
                u32 len = sge->length;
 
@@ -627,6 +623,7 @@ static int ipath_query_device(struct ib_device *ibdev,
        props->device_cap_flags = IB_DEVICE_BAD_PKEY_CNTR |
                IB_DEVICE_BAD_QKEY_CNTR | IB_DEVICE_SHUTDOWN_PORT |
                IB_DEVICE_SYS_IMAGE_GUID;
+       props->page_size_cap = PAGE_SIZE;
        props->vendor_id = ipath_layer_get_vendorid(dev->dd);
        props->vendor_part_id = ipath_layer_get_deviceid(dev->dd);
        props->hw_ver = ipath_layer_get_pcirev(dev->dd);
index d0f7731..deabc14 100644 (file)
@@ -778,11 +778,12 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status)
                ((dev->fw_ver & 0xffff0000ull) >> 16) |
                ((dev->fw_ver & 0x0000ffffull) << 16);
 
+       MTHCA_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET);
+       dev->cmd.max_cmds = 1 << lg;
+
        mthca_dbg(dev, "FW version %012llx, max commands %d\n",
                  (unsigned long long) dev->fw_ver, dev->cmd.max_cmds);
 
-       MTHCA_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET);
-       dev->cmd.max_cmds = 1 << lg;
        MTHCA_GET(dev->catas_err.addr, outbox, QUERY_FW_ERR_START_OFFSET);
        MTHCA_GET(dev->catas_err.size, outbox, QUERY_FW_ERR_SIZE_OFFSET);
 
index fab417c..b60a9d7 100644 (file)
@@ -370,7 +370,8 @@ int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
                return -EINVAL;
 
        if (attr_mask & IB_SRQ_LIMIT) {
-               if (attr->srq_limit > srq->max)
+               u32 max_wr = mthca_is_memfree(dev) ? srq->max - 1 : srq->max;
+               if (attr->srq_limit > max_wr)
                        return -EINVAL;
 
                mutex_lock(&srq->mutex);
index 3f89f5e..474aa21 100644 (file)
@@ -212,6 +212,7 @@ struct ipoib_path {
 
 struct ipoib_neigh {
        struct ipoib_ah    *ah;
+       union ib_gid        dgid;
        struct sk_buff_head queue;
 
        struct neighbour   *neighbour;
index 1c6ea1c..cf71d2a 100644 (file)
@@ -404,6 +404,8 @@ static void path_rec_completion(int status,
                list_for_each_entry(neigh, &path->neigh_list, list) {
                        kref_get(&path->ah->ref);
                        neigh->ah = path->ah;
+                       memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw,
+                              sizeof(union ib_gid));
 
                        while ((skb = __skb_dequeue(&neigh->queue)))
                                __skb_queue_tail(&skqueue, skb);
@@ -510,6 +512,8 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
        if (path->ah) {
                kref_get(&path->ah->ref);
                neigh->ah = path->ah;
+               memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw,
+                      sizeof(union ib_gid));
 
                ipoib_send(dev, skb, path->ah,
                           be32_to_cpup((__be32 *) skb->dst->neighbour->ha));
@@ -633,6 +637,25 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
                neigh = *to_ipoib_neigh(skb->dst->neighbour);
 
                if (likely(neigh->ah)) {
+                       if (unlikely(memcmp(&neigh->dgid.raw,
+                                           skb->dst->neighbour->ha + 4,
+                                           sizeof(union ib_gid)))) {
+                               spin_lock(&priv->lock);
+                               /*
+                                * It's safe to call ipoib_put_ah() inside
+                                * priv->lock here, because we know that
+                                * path->ah will always hold one more reference,
+                                * so ipoib_put_ah() will never do more than
+                                * decrement the ref count.
+                                */
+                               ipoib_put_ah(neigh->ah);
+                               list_del(&neigh->list);
+                               ipoib_neigh_free(neigh);
+                               spin_unlock(&priv->lock);
+                               ipoib_path_lookup(skb, dev);
+                               goto out;
+                       }
+
                        ipoib_send(dev, skb, neigh->ah,
                                   be32_to_cpup((__be32 *) skb->dst->neighbour->ha));
                        goto out;
index ab40488..b5e6a7b 100644 (file)
@@ -264,6 +264,10 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
                if (!ah) {
                        ipoib_warn(priv, "ib_address_create failed\n");
                } else {
+                       spin_lock_irq(&priv->lock);
+                       mcast->ah = ah;
+                       spin_unlock_irq(&priv->lock);
+
                        ipoib_dbg_mcast(priv, "MGID " IPOIB_GID_FMT
                                        " AV %p, LID 0x%04x, SL %d\n",
                                        IPOIB_GID_ARG(mcast->mcmember.mgid),
@@ -271,10 +275,6 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
                                        be16_to_cpu(mcast->mcmember.mlid),
                                        mcast->mcmember.sl);
                }
-
-               spin_lock_irq(&priv->lock);
-               mcast->ah = ah;
-               spin_unlock_irq(&priv->lock);
        }
 
        /* actually send any queued packets */
index bbc2298..ea31d84 100644 (file)
@@ -48,10 +48,8 @@ config FUSION_SAS
          List of supported controllers:
 
          LSISAS1064
-         LSISAS1066
          LSISAS1068
          LSISAS1064E
-         LSISAS1066E
          LSISAS1068E
 
 config FUSION_MAX_SGE
index b114236..3416913 100644 (file)
@@ -9,7 +9,6 @@
 #EXTRA_CFLAGS += -DMPT_DEBUG_EXIT
 #EXTRA_CFLAGS += -DMPT_DEBUG_FAIL
 
-
 #
 # driver/module specifics...
 #
index 43308df..29d0635 100644 (file)
@@ -436,8 +436,6 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
                 */
                if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
                        freereq = 0;
-                       devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
-                               ioc->name, pEvReply));
                } else {
                        devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
                                ioc->name, pEvReply));
@@ -678,19 +676,19 @@ int
 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
 {
        MPT_ADAPTER     *ioc;
+       const struct pci_device_id *id;
 
-       if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
+       if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
                return -EINVAL;
-       }
 
        MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
 
        /* call per pci device probe entry point */
        list_for_each_entry(ioc, &ioc_list, list) {
-               if(dd_cbfunc->probe) {
-                       dd_cbfunc->probe(ioc->pcidev,
-                         ioc->pcidev->driver->id_table);
-               }
+               id = ioc->pcidev->driver ?
+                   ioc->pcidev->driver->id_table : NULL;
+               if (dd_cbfunc->probe)
+                       dd_cbfunc->probe(ioc->pcidev, id);
         }
 
        return 0;
@@ -1056,9 +1054,8 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
 
                                dinitprintk((MYIOC_s_INFO_FMT
                                    "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
-                                   ioc->name,
-                                   ioc->HostPageBuffer,
-                                   ioc->HostPageBuffer_dma,
+                                   ioc->name, ioc->HostPageBuffer,
+                                   (u32)ioc->HostPageBuffer_dma,
                                    host_page_buffer_sz));
                                ioc->alloc_total += host_page_buffer_sz;
                                ioc->HostPageBuffer_sz = host_page_buffer_sz;
@@ -1380,6 +1377,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
                printk(KERN_WARNING MYNAM
                  ": WARNING - %s did not initialize properly! (%d)\n",
                  ioc->name, r);
+
                list_del(&ioc->list);
                if (ioc->alt_ioc)
                        ioc->alt_ioc->alt_ioc = NULL;
@@ -1762,9 +1760,9 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
                                                 * chips (mpt_adapter_disable,
                                                 * mpt_diag_reset)
                                                 */
-                                               ioc->cached_fw = NULL;
                                                ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload:  alt_%s has cached_fw=%p \n",
                                                        ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
+                                               ioc->alt_ioc->cached_fw = NULL;
                                        }
                                } else {
                                        printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
@@ -1885,7 +1883,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
                /* FIXME?  Examine results here? */
        }
 
-out:
+ out:
        if ((ret != 0) && irq_allocated) {
                free_irq(ioc->pci_irq, ioc);
                if (mpt_msi_enable)
@@ -2670,6 +2668,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
        dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
                        ioc->name, count));
 
+       ioc->aen_event_read_flag=0;
        return r;
 }
 
@@ -2737,6 +2736,8 @@ mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
        if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
                ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
                ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
+               ioc->alloc_total += size;
+               ioc->alt_ioc->alloc_total -= size;
        } else {
                if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
                        ioc->alloc_total += size;
@@ -3166,6 +3167,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
 static int
 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
 {
+       MPT_ADAPTER     *iocp=NULL;
        u32 diag0val;
        u32 doorbell;
        int hard_reset_done = 0;
@@ -3301,17 +3303,23 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
                        /* FIXME?  Examine results here? */
                }
 
-               if (ioc->cached_fw) {
+               if (ioc->cached_fw)
+                       iocp = ioc;
+               else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
+                       iocp = ioc->alt_ioc;
+               if (iocp) {
                        /* If the DownloadBoot operation fails, the
                         * IOC will be left unusable. This is a fatal error
                         * case.  _diag_reset will return < 0
                         */
                        for (count = 0; count < 30; count ++) {
-                               diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+                               diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
                                if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
                                        break;
                                }
 
+                               dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n",
+                                       iocp->name, diag0val, count));
                                /* wait 1 sec */
                                if (sleepFlag == CAN_SLEEP) {
                                        msleep (1000);
@@ -3320,7 +3328,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
                                }
                        }
                        if ((count = mpt_downloadboot(ioc,
-                               (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
+                               (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
                                printk(KERN_WARNING MYNAM
                                        ": firmware downloadboot failure (%d)!\n", count);
                        }
@@ -3907,18 +3915,18 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
 
        if (sleepFlag == CAN_SLEEP) {
                while (--cntdn) {
+                       msleep (1);
                        intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
                        if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
                                break;
-                       msleep (1);
                        count++;
                }
        } else {
                while (--cntdn) {
+                       mdelay (1);
                        intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
                        if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
                                break;
-                       mdelay (1);
                        count++;
                }
        }
@@ -4883,6 +4891,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
                pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
                if (!pIoc4)
                        return;
+               ioc->alloc_total += iocpage4sz;
        } else {
                ioc4_dma = ioc->spi_data.IocPg4_dma;
                iocpage4sz = ioc->spi_data.IocPg4Sz;
@@ -4899,6 +4908,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
        } else {
                pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
                ioc->spi_data.pIocPg4 = NULL;
+               ioc->alloc_total -= iocpage4sz;
        }
 }
 
@@ -5030,19 +5040,18 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
        EventAck_t      *pAck;
 
        if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
-               printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK "
-                       "request frame for Event=%x EventContext=%x EventData=%x!\n",
-                       ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
-                       le32_to_cpu(evnp->Data[0]));
+               dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
+                   ioc->name,__FUNCTION__));
                return -1;
        }
-       memset(pAck, 0, sizeof(*pAck));
 
-       dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
+       devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
 
        pAck->Function     = MPI_FUNCTION_EVENT_ACK;
        pAck->ChainOffset  = 0;
+       pAck->Reserved[0]  = pAck->Reserved[1] = 0;
        pAck->MsgFlags     = 0;
+       pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
        pAck->Event        = evnp->Event;
        pAck->EventContext = evnp->EventContext;
 
@@ -5704,9 +5713,9 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
                break;
        case MPI_EVENT_EVENT_CHANGE:
                if (evData0)
-                       ds = "Events(ON) Change";
+                       ds = "Events ON";
                else
-                       ds = "Events(OFF) Change";
+                       ds = "Events OFF";
                break;
        case MPI_EVENT_INTEGRATED_RAID:
        {
@@ -5777,8 +5786,27 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
                        break;
                case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
                        snprintf(evStr, EVENT_DESCR_STR_SZ,
-                           "SAS Device Status Change: No Persistancy "
-                           "Added: id=%d", id);
+                           "SAS Device Status Change: No Persistancy: id=%d", id);
+                       break;
+               case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: Internal Device Reset : id=%d", id);
+                       break;
+               case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: Internal Task Abort : id=%d", id);
+                       break;
+               case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: Internal Abort Task Set : id=%d", id);
+                       break;
+               case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: Internal Clear Task Set : id=%d", id);
+                       break;
+               case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
+                       snprintf(evStr, EVENT_DESCR_STR_SZ,
+                           "SAS Device Status Change: Internal Query Task : id=%d", id);
                        break;
                default:
                        snprintf(evStr, EVENT_DESCR_STR_SZ,
@@ -6034,7 +6062,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
  *     @ioc: Pointer to MPT_ADAPTER structure
  *     @log_info: U32 LogInfo reply word from the IOC
  *
- *     Refer to lsi/fc_log.h.
+ *     Refer to lsi/mpi_log_fc.h.
  */
 static void
 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
@@ -6131,8 +6159,10 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
                "Invalid SAS Address",                          /* 01h */
                NULL,                                           /* 02h */
                "Invalid Page",                                 /* 03h */
-               NULL,                                           /* 04h */
-               "Task Terminated"                               /* 05h */
+               "Diag Message Error",                           /* 04h */
+               "Task Terminated",                              /* 05h */
+               "Enclosure Management",                         /* 06h */
+               "Target Mode"                                   /* 07h */
        };
        static char *pl_code_str[] = {
                NULL,                                           /* 00h */
@@ -6158,7 +6188,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
                "IO Executed",                                  /* 14h */
                "Persistant Reservation Out Not Affiliation Owner", /* 15h */
                "Open Transmit DMA Abort",                      /* 16h */
-               NULL,                                           /* 17h */
+               "IO Device Missing Delay Retry",                /* 17h */
                NULL,                                           /* 18h */
                NULL,                                           /* 19h */
                NULL,                                           /* 1Ah */
@@ -6238,7 +6268,7 @@ static void
 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
 {
        u32 status = ioc_status & MPI_IOCSTATUS_MASK;
-       char *desc = "";
+       char *desc = NULL;
 
        switch (status) {
        case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
@@ -6348,7 +6378,7 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
                desc = "Others";
                break;
        }
-       if (desc != "")
+       if (desc != NULL)
                printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
 }
 
@@ -6386,7 +6416,6 @@ EXPORT_SYMBOL(mpt_alloc_fw_memory);
 EXPORT_SYMBOL(mpt_free_fw_memory);
 EXPORT_SYMBOL(mptbase_sas_persist_operation);
 
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *     fusion_init - Fusion MPT base driver initialization routine.
index a5ce10b..d4cb144 100644 (file)
@@ -75,8 +75,8 @@
 #define COPYRIGHT      "Copyright (c) 1999-2005 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON       "3.04.00"
-#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-3.04.00"
+#define MPT_LINUX_VERSION_COMMON       "3.04.01"
+#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-3.04.01"
 #define WHAT_MAGIC_STRING              "@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -307,8 +307,8 @@ typedef struct _SYSIF_REGS
        u32     HostIndex;      /* 50     Host Index register        */
        u32     Reserved4[15];  /* 54-8F                             */
        u32     Fubar;          /* 90     For Fubar usage            */
-       u32     Reserved5[1050];/* 94-10F8                           */
-       u32     Reset_1078;     /* 10FC   Reset 1078                 */
+       u32     Reserved5[1050];/* 94-10F8                           */
+       u32     Reset_1078;     /* 10FC   Reset 1078                 */
 } SYSIF_REGS;
 
 /*
@@ -363,6 +363,7 @@ typedef struct _VirtDevice {
 #define MPT_TARGET_FLAGS_VALID_56      0x10
 #define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20
 #define MPT_TARGET_FLAGS_RAID_COMPONENT        0x40
+#define MPT_TARGET_FLAGS_LED_ON                0x80
 
 /*
  *     /proc/mpt interface
@@ -634,7 +635,6 @@ typedef struct _MPT_ADAPTER
        u16                      handle;
        int                      sas_index; /* index refrencing */
        MPT_SAS_MGMT             sas_mgmt;
-       int                      num_ports;
        struct work_struct       sas_persist_task;
 
        struct work_struct       fc_setup_reset_work;
@@ -644,7 +644,6 @@ typedef struct _MPT_ADAPTER
        struct work_struct       fc_rescan_work;
        char                     fc_rescan_work_q_name[KOBJ_NAME_LEN];
        struct workqueue_struct *fc_rescan_work_q;
-       u8              port_serial_number;
 } MPT_ADAPTER;
 
 /*
@@ -982,7 +981,7 @@ typedef struct _MPT_SCSI_HOST {
        wait_queue_head_t         scandv_waitq;
        int                       scandv_wait_done;
        long                      last_queue_full;
-       u8                        mpt_pq_filter;
+       u16                       tm_iocstatus;
 } MPT_SCSI_HOST;
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
index b4967bb..30975cc 100644 (file)
@@ -2332,7 +2332,7 @@ done_free_mem:
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* Prototype Routine for the HP HOST INFO command.
+/* Prototype Routine for the HOST INFO command.
  *
  * Outputs:    None.
  * Return:     0 if successful
@@ -2568,7 +2568,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* Prototype Routine for the HP TARGET INFO command.
+/* Prototype Routine for the TARGET INFO command.
  *
  * Outputs:    None.
  * Return:     0 if successful
index a2f8a97..0439418 100644 (file)
@@ -354,9 +354,6 @@ struct mpt_ioctl_command32 {
 
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *     HP Specific IOCTL Defines and Structures
- */
 
 #define CPQFCTS_IOC_MAGIC 'Z'
 #define HP_IOC_MAGIC 'Z'
@@ -364,8 +361,6 @@ struct mpt_ioctl_command32 {
 #define HP_GETHOSTINFO1                _IOR(HP_IOC_MAGIC, 20, hp_host_info_rev0_t)
 #define HP_GETTARGETINFO       _IOR(HP_IOC_MAGIC, 21, hp_target_info_t)
 
-/* All HP IOCTLs must include this header
- */
 typedef struct _hp_header {
        unsigned int iocnum;
        unsigned int host;
index a8f2fa9..90da7d6 100644 (file)
@@ -77,10 +77,6 @@ MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
 
 /* Command line args */
-static int mpt_pq_filter = 0;
-module_param(mpt_pq_filter, int, 0);
-MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
-
 #define MPTFC_DEV_LOSS_TMO (60)
 static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;    /* reasonable default */
 module_param(mptfc_dev_loss_tmo, int, 0);
@@ -513,8 +509,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
 
        if (vtarget->num_luns == 0) {
                vtarget->ioc_id = hd->ioc->id;
-               vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
-                                 MPT_TARGET_FLAGS_VALID_INQUIRY;
+               vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
                hd->Targets[sdev->id] = vtarget;
        }
 
@@ -1129,13 +1124,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        hd->timer.data = (unsigned long) hd;
        hd->timer.function = mptscsih_timer_expired;
 
-       hd->mpt_pq_filter = mpt_pq_filter;
-
-       ddvprintk((MYIOC_s_INFO_FMT
-               "mpt_pq_filter %x\n",
-               ioc->name, 
-               mpt_pq_filter));
-
        init_waitqueue_head(&hd->scandv_waitq);
        hd->scandv_wait_done = 0;
        hd->last_queue_full = 0;
index f7bd8b1..f66f220 100644 (file)
 #define my_VERSION     MPT_LINUX_VERSION_COMMON
 #define MYNAM          "mptsas"
 
+/*
+ * Reserved channel for integrated raid
+ */
+#define MPTSAS_RAID_CHANNEL    1
+
 MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
 
-static int mpt_pq_filter;
-module_param(mpt_pq_filter, int, 0);
-MODULE_PARM_DESC(mpt_pq_filter,
-               "Enable peripheral qualifier filter: enable=1  "
-               "(default=0)");
-
 static int mpt_pt_clear;
 module_param(mpt_pt_clear, int, 0);
 MODULE_PARM_DESC(mpt_pt_clear,
-               "Clear persistency table: enable=1  "
+               " Clear persistency table: enable=1  "
                "(default=MPTSCSIH_PT_CLEAR=0)");
 
 static int     mptsasDoneCtx = -1;
@@ -144,7 +143,6 @@ struct mptsas_devinfo {
  * Specific details on ports, wide/narrow
  */
 struct mptsas_portinfo_details{
-       u8      port_id;        /* port number provided to transport */
        u16     num_phys;       /* number of phys belong to this port */
        u64     phy_bitmask;    /* TODO, extend support for 255 phys */
        struct sas_rphy *rphy;  /* transport layer rphy object */
@@ -350,10 +348,10 @@ mptsas_port_delete(struct mptsas_portinfo_details * port_details)
        port_info = port_details->port_info;
        phy_info = port_info->phy_info;
 
-       dsaswideprintk((KERN_DEBUG "%s: [%p]: port=%02d num_phys=%02d "
+       dsaswideprintk((KERN_DEBUG "%s: [%p]: num_phys=%02d "
                "bitmask=0x%016llX\n",
-               __FUNCTION__, port_details, port_details->port_id,
-               port_details->num_phys, port_details->phy_bitmask));
+               __FUNCTION__, port_details, port_details->num_phys,
+                   port_details->phy_bitmask));
 
        for (i = 0; i < port_info->num_phys; i++, phy_info++) {
                if(phy_info->port_details != port_details)
@@ -462,9 +460,8 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
                 * phy be removed by firmware events.
                 */
                dsaswideprintk((KERN_DEBUG
-                       "%s: [%p]: port=%d deleting phy = %d\n",
-                       __FUNCTION__, port_details,
-                       port_details->port_id, i));
+                       "%s: [%p]: deleting phy = %d\n",
+                       __FUNCTION__, port_details, i));
                port_details->num_phys--;
                port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
                memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
@@ -493,7 +490,6 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
                                goto out;
                        port_details->num_phys = 1;
                        port_details->port_info = port_info;
-                       port_details->port_id = ioc->port_serial_number++;
                        if (phy_info->phy_id < 64 )
                                port_details->phy_bitmask |=
                                    (1 << phy_info->phy_id);
@@ -525,12 +521,8 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
                                    mptsas_get_port(phy_info_cmp);
                                port_details->starget =
                                    mptsas_get_starget(phy_info_cmp);
-                               port_details->port_id =
-                                       phy_info_cmp->port_details->port_id;
                                port_details->num_phys =
                                        phy_info_cmp->port_details->num_phys;
-//                             port_info->port_serial_number--;
-                               ioc->port_serial_number--;
                                if (!phy_info_cmp->port_details->num_phys)
                                        kfree(phy_info_cmp->port_details);
                        } else
@@ -554,11 +546,11 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
                if (!port_details)
                        continue;
                dsaswideprintk((KERN_DEBUG
-                       "%s: [%p]: phy_id=%02d port_id=%02d num_phys=%02d "
+                       "%s: [%p]: phy_id=%02d num_phys=%02d "
                        "bitmask=0x%016llX\n",
                        __FUNCTION__,
-                       port_details, i, port_details->port_id,
-                       port_details->num_phys, port_details->phy_bitmask));
+                       port_details, i, port_details->num_phys,
+                       port_details->phy_bitmask));
                dsaswideprintk((KERN_DEBUG"\t\tport = %p rphy=%p\n",
                        port_details->port, port_details->rphy));
        }
@@ -651,16 +643,13 @@ mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
 static int
 mptsas_slave_configure(struct scsi_device *sdev)
 {
-       struct Scsi_Host        *host = sdev->host;
-       MPT_SCSI_HOST           *hd = (MPT_SCSI_HOST *)host->hostdata;
 
-       /*
-        * RAID volumes placed beyond the last expected port.
-        * Ignore sending sas mode pages in that case..
-        */
-       if (sdev->channel < hd->ioc->num_ports)
-               sas_read_port_mode_page(sdev);
+       if (sdev->channel == MPTSAS_RAID_CHANNEL)
+               goto out;
+
+       sas_read_port_mode_page(sdev);
 
+ out:
        return mptscsih_slave_configure(sdev);
 }
 
@@ -689,10 +678,7 @@ mptsas_target_alloc(struct scsi_target *starget)
 
        hd->Targets[target_id] = vtarget;
 
-       /*
-        * RAID volumes placed beyond the last expected port.
-        */
-       if (starget->channel == hd->ioc->num_ports)
+       if (starget->channel == MPTSAS_RAID_CHANNEL)
                goto out;
 
        rphy = dev_to_rphy(starget->dev.parent);
@@ -743,7 +729,7 @@ mptsas_target_destroy(struct scsi_target *starget)
        if (!starget->hostdata)
                return;
 
-       if (starget->channel == hd->ioc->num_ports)
+       if (starget->channel == MPTSAS_RAID_CHANNEL)
                goto out;
 
        rphy = dev_to_rphy(starget->dev.parent);
@@ -783,10 +769,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
        starget = scsi_target(sdev);
        vdev->vtarget = starget->hostdata;
 
-       /*
-        * RAID volumes placed beyond the last expected port.
-        */
-       if (sdev->channel == hd->ioc->num_ports)
+       if (sdev->channel == MPTSAS_RAID_CHANNEL)
                goto out;
 
        rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
@@ -1608,11 +1591,7 @@ static int mptsas_probe_one_phy(struct device *dev,
        if (phy_info->sas_port_add_phy) {
 
                if (!port) {
-                       port = sas_port_alloc(dev,
-                           phy_info->port_details->port_id);
-                       dsaswideprintk((KERN_DEBUG
-                           "sas_port_alloc: port=%p dev=%p port_id=%d\n",
-                           port, dev, phy_info->port_details->port_id));
+                       port = sas_port_alloc_num(dev);
                        if (!port) {
                                error = -ENOMEM;
                                goto out;
@@ -1625,6 +1604,9 @@ static int mptsas_probe_one_phy(struct device *dev,
                                goto out;
                        }
                        mptsas_set_port(phy_info, port);
+                       dsaswideprintk((KERN_DEBUG
+                           "sas_port_alloc: port=%p dev=%p port_id=%d\n",
+                           port, dev, port->port_identifier));
                }
                dsaswideprintk((KERN_DEBUG "sas_port_add_phy: phy_id=%d\n",
                    phy_info->phy_id));
@@ -1736,7 +1718,6 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
                hba = NULL;
        }
        mutex_unlock(&ioc->sas_topology_mutex);
-       ioc->num_ports = port_info->num_phys;
 
        for (i = 0; i < port_info->num_phys; i++) {
                mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
@@ -1939,7 +1920,8 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
                                        expander_sas_address)
                                        continue;
 #ifdef MPT_DEBUG_SAS_WIDE
-                               dev_printk(KERN_DEBUG, &port->dev, "delete\n");
+                               dev_printk(KERN_DEBUG, &port->dev,
+                                   "delete port (%d)\n", port->port_identifier);
 #endif
                                sas_port_delete(port);
                                mptsas_port_delete(phy_info->port_details);
@@ -1984,7 +1966,7 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
        if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
                goto out;
        for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
-               scsi_add_device(ioc->sh, ioc->num_ports,
+               scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
                    ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
        }
  out:
@@ -2185,7 +2167,8 @@ mptsas_hotplug_work(void *arg)
                       ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
 
 #ifdef MPT_DEBUG_SAS_WIDE
-               dev_printk(KERN_DEBUG, &port->dev, "delete\n");
+               dev_printk(KERN_DEBUG, &port->dev,
+                   "delete port (%d)\n", port->port_identifier);
 #endif
                sas_port_delete(port);
                mptsas_port_delete(phy_info->port_details);
@@ -2289,35 +2272,26 @@ mptsas_hotplug_work(void *arg)
                mptsas_set_rphy(phy_info, rphy);
                break;
        case MPTSAS_ADD_RAID:
-               sdev = scsi_device_lookup(
-                       ioc->sh,
-                       ioc->num_ports,
-                       ev->id,
-                       0);
+               sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
+                   ev->id, 0);
                if (sdev) {
                        scsi_device_put(sdev);
                        break;
                }
                printk(MYIOC_s_INFO_FMT
                       "attaching raid volume, channel %d, id %d\n",
-                      ioc->name, ioc->num_ports, ev->id);
-               scsi_add_device(ioc->sh,
-                       ioc->num_ports,
-                       ev->id,
-                       0);
+                      ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
+               scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0);
                mpt_findImVolumes(ioc);
                break;
        case MPTSAS_DEL_RAID:
-               sdev = scsi_device_lookup(
-                       ioc->sh,
-                       ioc->num_ports,
-                       ev->id,
-                       0);
+               sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
+                   ev->id, 0);
                if (!sdev)
                        break;
                printk(MYIOC_s_INFO_FMT
                       "removing raid volume, channel %d, id %d\n",
-                      ioc->name, ioc->num_ports, ev->id);
+                      ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
                vdevice = sdev->hostdata;
                vdevice->vtarget->deleted = 1;
                mptsas_target_reset(ioc, vdevice->vtarget);
@@ -2723,7 +2697,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        hd->timer.data = (unsigned long) hd;
        hd->timer.function = mptscsih_timer_expired;
 
-       hd->mpt_pq_filter = mpt_pq_filter;
        ioc->sas_data.ptClear = mpt_pt_clear;
 
        if (ioc->sas_data.ptClear==1) {
@@ -2731,12 +2704,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                    ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
        }
 
-       ddvprintk((MYIOC_s_INFO_FMT
-               "mpt_pq_filter %x mpt_pq_filter %x\n",
-               ioc->name,
-               mpt_pq_filter,
-               mpt_pq_filter));
-
        init_waitqueue_head(&hd->scandv_waitq);
        hd->scandv_wait_done = 0;
        hd->last_queue_full = 0;
index 8242b16..30524dc 100644 (file)
@@ -66,6 +66,7 @@
 
 #include "mptbase.h"
 #include "mptscsih.h"
+#include "lsi/mpi_log_sas.h"
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #define my_NAME                "Fusion MPT SCSI Host driver"
@@ -127,7 +128,7 @@ static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
 static void    mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
 static int     mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
 static int     mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
-static u32     SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
+static int     SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
 
 static int     mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
 
@@ -497,6 +498,34 @@ nextSGEset:
        return SUCCESS;
 } /* mptscsih_AddSGE() */
 
+static void
+mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
+    U32 SlotStatus)
+{
+       MPT_FRAME_HDR *mf;
+       SEPRequest_t     *SEPMsg;
+
+       if (ioc->bus_type == FC)
+               return;
+
+       if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
+               dfailprintk((MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
+                   ioc->name,__FUNCTION__));
+               return;
+       }
+
+       SEPMsg = (SEPRequest_t *)mf;
+       SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
+       SEPMsg->Bus = vtarget->bus_id;
+       SEPMsg->TargetID = vtarget->target_id;
+       SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
+       SEPMsg->SlotStatus = SlotStatus;
+       devtverboseprintk((MYIOC_s_WARN_FMT
+           "Sending SEP cmd=%x id=%d bus=%d\n",
+           ioc->name, SlotStatus, SEPMsg->TargetID, SEPMsg->Bus));
+       mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *     mptscsih_io_done - Main SCSI IO callback routine registered to
@@ -520,6 +549,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
        SCSIIORequest_t *pScsiReq;
        SCSIIOReply_t   *pScsiReply;
        u16              req_idx, req_idx_MR;
+       VirtDevice       *vdev;
+       VirtTarget       *vtarget;
 
        hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
 
@@ -538,6 +569,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
        }
 
        sc = hd->ScsiLookup[req_idx];
+       hd->ScsiLookup[req_idx] = NULL;
        if (sc == NULL) {
                MPIHeader_t *hdr = (MPIHeader_t *)mf;
 
@@ -553,6 +585,12 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                return 1;
        }
 
+       if ((unsigned char *)mf != sc->host_scribble) {
+               mptscsih_freeChainBuffers(ioc, req_idx);
+               return 1;
+       }
+
+       sc->host_scribble = NULL;
        sc->result = DID_OK << 16;              /* Set default reply as OK */
        pScsiReq = (SCSIIORequest_t *) mf;
        pScsiReply = (SCSIIOReply_t *) mr;
@@ -640,10 +678,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 
                        if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
                                hd->sel_timeout[pScsiReq->TargetID]++;
+
+                       vdev = sc->device->hostdata;
+                       if (!vdev)
+                               break;
+                       vtarget = vdev->vtarget;
+                       if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
+                               mptscsih_issue_sep_command(ioc, vtarget,
+                                   MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
+                               vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
+                       }
                        break;
 
-               case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:        /* 0x0048 */
                case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:         /* 0x004B */
+                       if ( ioc->bus_type == SAS ) {
+                               u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
+                               if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
+                                       u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
+                                       log_info &=SAS_LOGINFO_MASK;
+                                       if (log_info == SAS_LOGINFO_NEXUS_LOSS) {
+                                               sc->result = (DID_BUS_BUSY << 16);
+                                               break;
+                                       }
+                               }
+                       }
+
+                       /*
+                        * Allow non-SAS & non-NEXUS_LOSS to drop into below code
+                        */
+
+               case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:        /* 0x0048 */
                case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:         /* 0x004C */
                        /* Linux handles an unsolicited DID_RESET better
                         * than an unsolicited DID_ABORT.
@@ -658,7 +722,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                                sc->result=DID_SOFT_ERROR << 16;
                        else /* Sufficient data transfer occurred */
                                sc->result = (DID_OK << 16) | scsi_status;
-                       dreplyprintk((KERN_NOTICE 
+                       dreplyprintk((KERN_NOTICE
                            "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
                        break;
 
@@ -784,8 +848,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
                                sc->request_bufflen, sc->sc_data_direction);
        }
 
-       hd->ScsiLookup[req_idx] = NULL;
-
        sc->scsi_done(sc);              /* Issue the command callback */
 
        /* Free Chain buffers */
@@ -827,9 +889,17 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
                        dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
                                        mf, SCpnt));
 
+                       /* Free Chain buffers */
+                       mptscsih_freeChainBuffers(ioc, ii);
+
+                       /* Free Message frames */
+                       mpt_free_msg_frame(ioc, mf);
+
+                       if ((unsigned char *)mf != SCpnt->host_scribble)
+                               continue;
+
                        /* Set status, free OS resources (SG DMA buffers)
                         * Do OS callback
-                        * Free driver resources (chain, msg buffers)
                         */
                        if (SCpnt->use_sg) {
                                pci_unmap_sg(ioc->pcidev,
@@ -845,12 +915,6 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
                        SCpnt->result = DID_RESET << 16;
                        SCpnt->host_scribble = NULL;
 
-                       /* Free Chain buffers */
-                       mptscsih_freeChainBuffers(ioc, ii);
-
-                       /* Free Message frames */
-                       mpt_free_msg_frame(ioc, mf);
-
                        SCpnt->scsi_done(SCpnt);        /* Issue the command callback */
                }
        }
@@ -887,10 +951,10 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
                if ((sc = hd->ScsiLookup[ii]) != NULL) {
 
                        mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
-
+                       if (mf == NULL)
+                               continue;
                        dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
                                        hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
-
                        if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
                                continue;
 
@@ -899,6 +963,8 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
                        hd->ScsiLookup[ii] = NULL;
                        mptscsih_freeChainBuffers(hd->ioc, ii);
                        mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
+                       if ((unsigned char *)mf != sc->host_scribble)
+                               continue;
                        if (sc->use_sg) {
                                pci_unmap_sg(hd->ioc->pcidev,
                                (struct scatterlist *) sc->request_buffer,
@@ -1341,8 +1407,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
                        goto fail;
        }
 
+       SCpnt->host_scribble = (unsigned char *)mf;
        hd->ScsiLookup[my_idx] = SCpnt;
-       SCpnt->host_scribble = NULL;
 
        mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
        dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
@@ -1529,6 +1595,12 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
                rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
        }
 
+       /*
+        * Check IOCStatus from TM reply message
+        */
+        if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS)
+               rc = FAILED;
+
        dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
 
        return rc;
@@ -1654,6 +1726,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
        int              scpnt_idx;
        int              retval;
        VirtDevice       *vdev;
+       ulong            sn = SCpnt->serial_number;
 
        /* If we can't locate our host adapter structure, return FAILED status.
         */
@@ -1707,6 +1780,11 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
                vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
                ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
 
+       if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
+           SCpnt->serial_number == sn) {
+               retval = FAILED;
+       }
+
        printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
                hd->ioc->name,
                ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
@@ -2023,6 +2101,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
                DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
 
                iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
+               hd->tm_iocstatus = iocstatus;
                dtmprintk((MYIOC_s_WARN_FMT "  SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
                        ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
                /* Error?  (anything non-zero?) */
@@ -2401,6 +2480,13 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
                                ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
 
                                ioc->eventContext++;
+                               if (hd->ioc->pcidev->vendor ==
+                                   PCI_VENDOR_ID_IBM) {
+                                       mptscsih_issue_sep_command(hd->ioc,
+                                           vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
+                                       vdev->vtarget->tflags |=
+                                           MPT_TARGET_FLAGS_LED_ON;
+                               }
                        }
                }
        } else {
@@ -2409,7 +2495,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
        }
 }
 
-static u32
+static int
 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
 {
        MPT_SCSI_HOST *hd;
index 0a1ff76..e4cc3dd 100644 (file)
@@ -83,10 +83,6 @@ static int mpt_saf_te = MPTSCSIH_SAF_TE;
 module_param(mpt_saf_te, int, 0);
 MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1  (default=MPTSCSIH_SAF_TE=0)");
 
-static int mpt_pq_filter = 0;
-module_param(mpt_pq_filter, int, 0);
-MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
-
 static void mptspi_write_offset(struct scsi_target *, int);
 static void mptspi_write_width(struct scsi_target *, int);
 static int mptspi_write_spi_device_pg1(struct scsi_target *,
@@ -1047,14 +1043,12 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        hd->timer.function = mptscsih_timer_expired;
 
        ioc->spi_data.Saf_Te = mpt_saf_te;
-       hd->mpt_pq_filter = mpt_pq_filter;
 
        hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
        ddvprintk((MYIOC_s_INFO_FMT
-               "saf_te %x mpt_pq_filter %x\n",
+               "saf_te %x\n",
                ioc->name,
-               mpt_saf_te,
-               mpt_pq_filter));
+               mpt_saf_te));
        ioc->spi_data.noQas = 0;
 
        init_waitqueue_head(&hd->scandv_waitq);
index 36d5117..2146cf7 100644 (file)
@@ -132,6 +132,7 @@ static int __init dummy_init_module(void)
        for (i = 0; i < numdummies && !err; i++)
                err = dummy_init_one(i); 
        if (err) { 
+               i--;
                while (--i >= 0)
                        dummy_free_one(i);
        }
index f411bbb..d304297 100644 (file)
@@ -110,6 +110,9 @@ struct e1000_adapter;
 #define E1000_MIN_RXD                       80
 #define E1000_MAX_82544_RXD               4096
 
+/* this is the size past which hardware will drop packets when setting LPE=0 */
+#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
+
 /* Supported Rx Buffer Sizes */
 #define E1000_RXBUFFER_128   128    /* Used for packet split */
 #define E1000_RXBUFFER_256   256    /* Used for packet split */
index 6d3d419..da62db8 100644 (file)
@@ -36,7 +36,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-#define DRV_VERSION "7.1.9-k2"DRIVERNAPI
+#define DRV_VERSION "7.1.9-k4"DRIVERNAPI
 char e1000_driver_version[] = DRV_VERSION;
 static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
 
@@ -1068,7 +1068,7 @@ e1000_sw_init(struct e1000_adapter *adapter)
 
        pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
 
-       adapter->rx_buffer_len = MAXIMUM_ETHERNET_FRAME_SIZE;
+       adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
        adapter->rx_ps_bsize0 = E1000_RXBUFFER_128;
        hw->max_frame_size = netdev->mtu +
                             ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
@@ -3148,7 +3148,6 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
                adapter->rx_buffer_len = E1000_RXBUFFER_16384;
 
        /* adjust allocation if LPE protects us, and we aren't using SBP */
-#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
        if (!adapter->hw.tbi_compatibility_on &&
            ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) ||
             (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
@@ -3387,8 +3386,8 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
                E1000_WRITE_REG(hw, IMC, ~0);
                E1000_WRITE_FLUSH(hw);
        }
-       if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0])))
-               __netif_rx_schedule(&adapter->polling_netdev[0]);
+       if (likely(netif_rx_schedule_prep(netdev)))
+               __netif_rx_schedule(netdev);
        else
                e1000_irq_enable(adapter);
 #else
@@ -3431,34 +3430,26 @@ e1000_clean(struct net_device *poll_dev, int *budget)
 {
        struct e1000_adapter *adapter;
        int work_to_do = min(*budget, poll_dev->quota);
-       int tx_cleaned = 0, i = 0, work_done = 0;
+       int tx_cleaned = 0, work_done = 0;
 
        /* Must NOT use netdev_priv macro here. */
        adapter = poll_dev->priv;
 
        /* Keep link state information with original netdev */
-       if (!netif_carrier_ok(adapter->netdev))
+       if (!netif_carrier_ok(poll_dev))
                goto quit_polling;
 
-       while (poll_dev != &adapter->polling_netdev[i]) {
-               i++;
-               BUG_ON(i == adapter->num_rx_queues);
+       /* e1000_clean is called per-cpu.  This lock protects
+        * tx_ring[0] from being cleaned by multiple cpus
+        * simultaneously.  A failure obtaining the lock means
+        * tx_ring[0] is currently being cleaned anyway. */
+       if (spin_trylock(&adapter->tx_queue_lock)) {
+               tx_cleaned = e1000_clean_tx_irq(adapter,
+                                               &adapter->tx_ring[0]);
+               spin_unlock(&adapter->tx_queue_lock);
        }
 
-       if (likely(adapter->num_tx_queues == 1)) {
-               /* e1000_clean is called per-cpu.  This lock protects
-                * tx_ring[0] from being cleaned by multiple cpus
-                * simultaneously.  A failure obtaining the lock means
-                * tx_ring[0] is currently being cleaned anyway. */
-               if (spin_trylock(&adapter->tx_queue_lock)) {
-                       tx_cleaned = e1000_clean_tx_irq(adapter,
-                                                       &adapter->tx_ring[0]);
-                       spin_unlock(&adapter->tx_queue_lock);
-               }
-       } else
-               tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[i]);
-
-       adapter->clean_rx(adapter, &adapter->rx_ring[i],
+       adapter->clean_rx(adapter, &adapter->rx_ring[0],
                          &work_done, work_to_do);
 
        *budget -= work_done;
@@ -3466,7 +3457,7 @@ e1000_clean(struct net_device *poll_dev, int *budget)
 
        /* If no Tx and not enough Rx work done, exit the polling mode */
        if ((!tx_cleaned && (work_done == 0)) ||
-          !netif_running(adapter->netdev)) {
+          !netif_running(poll_dev)) {
 quit_polling:
                netif_rx_complete(poll_dev);
                e1000_irq_enable(adapter);
@@ -3681,6 +3672,9 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
 
                length = le16_to_cpu(rx_desc->length);
 
+               /* adjust length to remove Ethernet CRC */
+               length -= 4;
+
                if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
                        /* All receives must fit into a single buffer */
                        E1000_DBG("%s: Receive packet consumed multiple"
@@ -3885,8 +3879,9 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
                        pci_dma_sync_single_for_device(pdev,
                                ps_page_dma->ps_page_dma[0],
                                PAGE_SIZE, PCI_DMA_FROMDEVICE);
+                       /* remove the CRC */
+                       l1 -= 4;
                        skb_put(skb, l1);
-                       length += l1;
                        goto copydone;
                } /* if */
                }
@@ -3905,6 +3900,10 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
                        skb->truesize += length;
                }
 
+               /* strip the ethernet crc, problem is we're using pages now so
+                * this whole operation can get a little cpu intensive */
+               pskb_trim(skb, skb->len - 4);
+
 copydone:
                e1000_rx_checksum(adapter, staterr,
                                  le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb);
@@ -4752,6 +4751,7 @@ static void
 e1000_netpoll(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+
        disable_irq(adapter->pdev->irq);
        e1000_intr(adapter->pdev->irq, netdev, NULL);
        e1000_clean_tx_irq(adapter, adapter->tx_ring);
index 3a42afa..43e3f33 100644 (file)
@@ -271,6 +271,7 @@ static int __init ifb_init_module(void)
        for (i = 0; i < numifbs && !err; i++)
                err = ifb_init_one(i); 
        if (err) { 
+               i--;
                while (--i >= 0)
                        ifb_free_one(i);
        }
index 07ca948..c3e52c8 100644 (file)
@@ -620,7 +620,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
                return -ENXIO;
        }
        dev_info(&mgp->pdev->dev, "handoff confirmed\n");
-       myri10ge_dummy_rdma(mgp, mgp->tx.boundary != 4096);
+       myri10ge_dummy_rdma(mgp, 1);
 
        return 0;
 }
index 82200bf..7de9a07 100644 (file)
@@ -516,10 +516,7 @@ static int skge_set_pauseparam(struct net_device *dev,
 /* Chip internal frequency for clock calculations */
 static inline u32 hwkhz(const struct skge_hw *hw)
 {
-       if (hw->chip_id == CHIP_ID_GENESIS)
-               return 53215; /* or:  53.125 MHz */
-       else
-               return 78215; /* or:  78.125 MHz */
+       return (hw->chip_id == CHIP_ID_GENESIS) ? 53125 : 78125;
 }
 
 /* Chip HZ to microseconds */
index d98f28c..de91609 100644 (file)
@@ -50,7 +50,7 @@
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
-#define DRV_VERSION            "1.4"
+#define DRV_VERSION            "1.5"
 #define PFX                    DRV_NAME " "
 
 /*
@@ -2204,9 +2204,6 @@ static int sky2_poll(struct net_device *dev0, int *budget)
        int work_done = 0;
        u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
 
-       if (!~status)
-               goto out;
-
        if (status & Y2_IS_HW_ERR)
                sky2_hw_intr(hw);
 
@@ -2243,7 +2240,7 @@ static int sky2_poll(struct net_device *dev0, int *budget)
 
        if (sky2_more_work(hw))
                return 1;
-out:
+
        netif_rx_complete(dev0);
 
        sky2_read32(hw, B0_Y2_SP_LISR);
index fb1d5a8..647f62e 100644 (file)
@@ -84,7 +84,7 @@ MODULE_DEVICE_TABLE(pci, spider_net_pci_tbl);
  *
  * returns the content of the specified SMMIO register.
  */
-static u32
+static inline u32
 spider_net_read_reg(struct spider_net_card *card, u32 reg)
 {
        u32 value;
@@ -101,7 +101,7 @@ spider_net_read_reg(struct spider_net_card *card, u32 reg)
  * @reg: register to write to
  * @value: value to write into the specified SMMIO register
  */
-static void
+static inline void
 spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value)
 {
        value = cpu_to_le32(value);
@@ -259,39 +259,10 @@ spider_net_get_mac_address(struct net_device *netdev)
  *
  * returns the status as in the dmac_cmd_status field of the descriptor
  */
-static enum spider_net_descr_status
+static inline int
 spider_net_get_descr_status(struct spider_net_descr *descr)
 {
-       u32 cmd_status;
-
-       cmd_status = descr->dmac_cmd_status;
-       cmd_status >>= SPIDER_NET_DESCR_IND_PROC_SHIFT;
-       /* no need to mask out any bits, as cmd_status is 32 bits wide only
-        * (and unsigned) */
-       return cmd_status;
-}
-
-/**
- * spider_net_set_descr_status -- sets the status of a descriptor
- * @descr: descriptor to change
- * @status: status to set in the descriptor
- *
- * changes the status to the specified value. Doesn't change other bits
- * in the status
- */
-static void
-spider_net_set_descr_status(struct spider_net_descr *descr,
-                           enum spider_net_descr_status status)
-{
-       u32 cmd_status;
-       /* read the status */
-       cmd_status = descr->dmac_cmd_status;
-       /* clean the upper 4 bits */
-       cmd_status &= SPIDER_NET_DESCR_IND_PROC_MASKO;
-       /* add the status to it */
-       cmd_status |= ((u32)status)<<SPIDER_NET_DESCR_IND_PROC_SHIFT;
-       /* and write it back */
-       descr->dmac_cmd_status = cmd_status;
+       return descr->dmac_cmd_status & SPIDER_NET_DESCR_IND_PROC_MASK;
 }
 
 /**
@@ -328,24 +299,23 @@ spider_net_free_chain(struct spider_net_card *card,
 static int
 spider_net_init_chain(struct spider_net_card *card,
                       struct spider_net_descr_chain *chain,
-                      struct spider_net_descr *start_descr, int no)
+                      struct spider_net_descr *start_descr,
+                      int direction, int no)
 {
        int i;
        struct spider_net_descr *descr;
        dma_addr_t buf;
 
-       atomic_set(&card->rx_chain_refill,0);
-
        descr = start_descr;
        memset(descr, 0, sizeof(*descr) * no);
 
        /* set up the hardware pointers in each descriptor */
        for (i=0; i<no; i++, descr++) {
-               spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE);
+               descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE;
 
                buf = pci_map_single(card->pdev, descr,
                                     SPIDER_NET_DESCR_SIZE,
-                                    PCI_DMA_BIDIRECTIONAL);
+                                    direction);
 
                if (buf == DMA_ERROR_CODE)
                        goto iommu_error;
@@ -360,10 +330,11 @@ spider_net_init_chain(struct spider_net_card *card,
        start_descr->prev = descr-1;
 
        descr = start_descr;
-       for (i=0; i < no; i++, descr++) {
-               descr->next_descr_addr = descr->next->bus_addr;
-       }
+       if (direction == PCI_DMA_FROMDEVICE)
+               for (i=0; i < no; i++, descr++)
+                       descr->next_descr_addr = descr->next->bus_addr;
 
+       spin_lock_init(&chain->lock);
        chain->head = start_descr;
        chain->tail = start_descr;
 
@@ -375,7 +346,7 @@ iommu_error:
                if (descr->bus_addr)
                        pci_unmap_single(card->pdev, descr->bus_addr,
                                         SPIDER_NET_DESCR_SIZE,
-                                        PCI_DMA_BIDIRECTIONAL);
+                                        direction);
        return -ENOMEM;
 }
 
@@ -396,7 +367,7 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card)
                        dev_kfree_skb(descr->skb);
                        pci_unmap_single(card->pdev, descr->buf_addr,
                                         SPIDER_NET_MAX_FRAME,
-                                        PCI_DMA_BIDIRECTIONAL);
+                                        PCI_DMA_FROMDEVICE);
                }
                descr = descr->next;
        }
@@ -446,15 +417,16 @@ spider_net_prepare_rx_descr(struct spider_net_card *card,
                skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset);
        /* io-mmu-map the skb */
        buf = pci_map_single(card->pdev, descr->skb->data,
-                            SPIDER_NET_MAX_FRAME, PCI_DMA_BIDIRECTIONAL);
+                       SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE);
        descr->buf_addr = buf;
        if (buf == DMA_ERROR_CODE) {
                dev_kfree_skb_any(descr->skb);
                if (netif_msg_rx_err(card) && net_ratelimit())
                        pr_err("Could not iommu-map rx buffer\n");
-               spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE);
+               descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE;
        } else {
-               descr->dmac_cmd_status = SPIDER_NET_DMAC_RX_CARDOWNED;
+               descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED |
+                                        SPIDER_NET_DMAC_NOINTR_COMPLETE;
        }
 
        return error;
@@ -468,7 +440,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card,
  * chip by writing to the appropriate register. DMA is enabled in
  * spider_net_enable_rxdmac.
  */
-static void
+static inline void
 spider_net_enable_rxchtails(struct spider_net_card *card)
 {
        /* assume chain is aligned correctly */
@@ -483,7 +455,7 @@ spider_net_enable_rxchtails(struct spider_net_card *card)
  * spider_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
  * in the GDADMACCNTR register
  */
-static void
+static inline void
 spider_net_enable_rxdmac(struct spider_net_card *card)
 {
        wmb();
@@ -500,23 +472,24 @@ spider_net_enable_rxdmac(struct spider_net_card *card)
 static void
 spider_net_refill_rx_chain(struct spider_net_card *card)
 {
-       struct spider_net_descr_chain *chain;
-
-       chain = &card->rx_chain;
+       struct spider_net_descr_chain *chain = &card->rx_chain;
+       unsigned long flags;
 
        /* one context doing the refill (and a second context seeing that
         * and omitting it) is ok. If called by NAPI, we'll be called again
         * as spider_net_decode_one_descr is called several times. If some
         * interrupt calls us, the NAPI is about to clean up anyway. */
-       if (atomic_inc_return(&card->rx_chain_refill) == 1)
-               while (spider_net_get_descr_status(chain->head) ==
-                      SPIDER_NET_DESCR_NOT_IN_USE) {
-                       if (spider_net_prepare_rx_descr(card, chain->head))
-                               break;
-                       chain->head = chain->head->next;
-               }
+       if (!spin_trylock_irqsave(&chain->lock, flags))
+               return;
+
+       while (spider_net_get_descr_status(chain->head) ==
+                       SPIDER_NET_DESCR_NOT_IN_USE) {
+               if (spider_net_prepare_rx_descr(card, chain->head))
+                       break;
+               chain->head = chain->head->next;
+       }
 
-       atomic_dec(&card->rx_chain_refill);
+       spin_unlock_irqrestore(&chain->lock, flags);
 }
 
 /**
@@ -554,111 +527,6 @@ error:
 }
 
 /**
- * spider_net_release_tx_descr - processes a used tx descriptor
- * @card: card structure
- * @descr: descriptor to release
- *
- * releases a used tx descriptor (unmapping, freeing of skb)
- */
-static void
-spider_net_release_tx_descr(struct spider_net_card *card,
-                           struct spider_net_descr *descr)
-{
-       struct sk_buff *skb;
-
-       /* unmap the skb */
-       skb = descr->skb;
-       pci_unmap_single(card->pdev, descr->buf_addr, skb->len,
-                        PCI_DMA_BIDIRECTIONAL);
-
-       dev_kfree_skb_any(skb);
-
-       /* set status to not used */
-       spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE);
-}
-
-/**
- * spider_net_release_tx_chain - processes sent tx descriptors
- * @card: adapter structure
- * @brutal: if set, don't care about whether descriptor seems to be in use
- *
- * returns 0 if the tx ring is empty, otherwise 1.
- *
- * spider_net_release_tx_chain releases the tx descriptors that spider has
- * finished with (if non-brutal) or simply release tx descriptors (if brutal).
- * If some other context is calling this function, we return 1 so that we're
- * scheduled again (if we were scheduled) and will not loose initiative.
- */
-static int
-spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
-{
-       struct spider_net_descr_chain *tx_chain = &card->tx_chain;
-       enum spider_net_descr_status status;
-
-       if (atomic_inc_return(&card->tx_chain_release) != 1) {
-               atomic_dec(&card->tx_chain_release);
-               return 1;
-       }
-
-       for (;;) {
-               status = spider_net_get_descr_status(tx_chain->tail);
-               switch (status) {
-               case SPIDER_NET_DESCR_CARDOWNED:
-                       if (!brutal)
-                               goto out;
-                       /* fallthrough, if we release the descriptors
-                        * brutally (then we don't care about
-                        * SPIDER_NET_DESCR_CARDOWNED) */
-               case SPIDER_NET_DESCR_RESPONSE_ERROR:
-               case SPIDER_NET_DESCR_PROTECTION_ERROR:
-               case SPIDER_NET_DESCR_FORCE_END:
-                       if (netif_msg_tx_err(card))
-                               pr_err("%s: forcing end of tx descriptor "
-                                      "with status x%02x\n",
-                                      card->netdev->name, status);
-                       card->netdev_stats.tx_dropped++;
-                       break;
-
-               case SPIDER_NET_DESCR_COMPLETE:
-                       card->netdev_stats.tx_packets++;
-                       card->netdev_stats.tx_bytes +=
-                               tx_chain->tail->skb->len;
-                       break;
-
-               default: /* any other value (== SPIDER_NET_DESCR_NOT_IN_USE) */
-                       goto out;
-               }
-               spider_net_release_tx_descr(card, tx_chain->tail);
-               tx_chain->tail = tx_chain->tail->next;
-       }
-out:
-       atomic_dec(&card->tx_chain_release);
-
-       netif_wake_queue(card->netdev);
-
-       if (status == SPIDER_NET_DESCR_CARDOWNED)
-               return 1;
-       return 0;
-}
-
-/**
- * spider_net_cleanup_tx_ring - cleans up the TX ring
- * @card: card structure
- *
- * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use
- * interrupts to cleanup our TX ring) and returns sent packets to the stack
- * by freeing them
- */
-static void
-spider_net_cleanup_tx_ring(struct spider_net_card *card)
-{
-       if ( (spider_net_release_tx_chain(card, 0)) &&
-             (card->netdev->flags & IFF_UP) ) {
-               mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER);
-       }
-}
-
-/**
  * spider_net_get_multicast_hash - generates hash for multicast filter table
  * @addr: multicast address
  *
@@ -761,97 +629,6 @@ spider_net_disable_rxdmac(struct spider_net_card *card)
 }
 
 /**
- * spider_net_stop - called upon ifconfig down
- * @netdev: interface device structure
- *
- * always returns 0
- */
-int
-spider_net_stop(struct net_device *netdev)
-{
-       struct spider_net_card *card = netdev_priv(netdev);
-
-       tasklet_kill(&card->rxram_full_tl);
-       netif_poll_disable(netdev);
-       netif_carrier_off(netdev);
-       netif_stop_queue(netdev);
-       del_timer_sync(&card->tx_timer);
-
-       /* disable/mask all interrupts */
-       spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
-       spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
-       spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
-
-       /* free_irq(netdev->irq, netdev);*/
-       free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev);
-
-       spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
-                            SPIDER_NET_DMA_TX_FEND_VALUE);
-
-       /* turn off DMA, force end */
-       spider_net_disable_rxdmac(card);
-
-       /* release chains */
-       spider_net_release_tx_chain(card, 1);
-
-       spider_net_free_chain(card, &card->tx_chain);
-       spider_net_free_chain(card, &card->rx_chain);
-
-       return 0;
-}
-
-/**
- * spider_net_get_next_tx_descr - returns the next available tx descriptor
- * @card: device structure to get descriptor from
- *
- * returns the address of the next descriptor, or NULL if not available.
- */
-static struct spider_net_descr *
-spider_net_get_next_tx_descr(struct spider_net_card *card)
-{
-       /* check, if head points to not-in-use descr */
-       if ( spider_net_get_descr_status(card->tx_chain.head) ==
-            SPIDER_NET_DESCR_NOT_IN_USE ) {
-               return card->tx_chain.head;
-       } else {
-               return NULL;
-       }
-}
-
-/**
- * spider_net_set_txdescr_cmdstat - sets the tx descriptor command field
- * @descr: descriptor structure to fill out
- * @skb: packet to consider
- *
- * fills out the command and status field of the descriptor structure,
- * depending on hardware checksum settings.
- */
-static void
-spider_net_set_txdescr_cmdstat(struct spider_net_descr *descr,
-                              struct sk_buff *skb)
-{
-       /* make sure the other fields in the descriptor are written */
-       wmb();
-
-       if (skb->ip_summed != CHECKSUM_HW) {
-               descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS;
-               return;
-       }
-
-       /* is packet ip?
-        * if yes: tcp? udp? */
-       if (skb->protocol == htons(ETH_P_IP)) {
-               if (skb->nh.iph->protocol == IPPROTO_TCP)
-                       descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_TCPCS;
-               else if (skb->nh.iph->protocol == IPPROTO_UDP)
-                       descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_UDPCS;
-               else /* the stack should checksum non-tcp and non-udp
-                       packets on his own: NETIF_F_IP_CSUM */
-                       descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS;
-       }
-}
-
-/**
  * spider_net_prepare_tx_descr - fill tx descriptor with skb data
  * @card: card structure
  * @descr: descriptor structure to fill out
@@ -864,13 +641,12 @@ spider_net_set_txdescr_cmdstat(struct spider_net_descr *descr,
  */
 static int
 spider_net_prepare_tx_descr(struct spider_net_card *card,
-                           struct spider_net_descr *descr,
                            struct sk_buff *skb)
 {
+       struct spider_net_descr *descr = card->tx_chain.head;
        dma_addr_t buf;
 
-       buf = pci_map_single(card->pdev, skb->data,
-                            skb->len, PCI_DMA_BIDIRECTIONAL);
+       buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
        if (buf == DMA_ERROR_CODE) {
                if (netif_msg_tx_err(card) && net_ratelimit())
                        pr_err("could not iommu-map packet (%p, %i). "
@@ -880,10 +656,101 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
 
        descr->buf_addr = buf;
        descr->buf_size = skb->len;
+       descr->next_descr_addr = 0;
        descr->skb = skb;
        descr->data_status = 0;
 
-       spider_net_set_txdescr_cmdstat(descr,skb);
+       descr->dmac_cmd_status =
+                       SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS;
+       if (skb->protocol == htons(ETH_P_IP))
+               switch (skb->nh.iph->protocol) {
+               case IPPROTO_TCP:
+                       descr->dmac_cmd_status |= SPIDER_NET_DMAC_TCP;
+                       break;
+               case IPPROTO_UDP:
+                       descr->dmac_cmd_status |= SPIDER_NET_DMAC_UDP;
+                       break;
+               }
+
+       descr->prev->next_descr_addr = descr->bus_addr;
+
+       return 0;
+}
+
+/**
+ * spider_net_release_tx_descr - processes a used tx descriptor
+ * @card: card structure
+ * @descr: descriptor to release
+ *
+ * releases a used tx descriptor (unmapping, freeing of skb)
+ */
+static inline void
+spider_net_release_tx_descr(struct spider_net_card *card)
+{
+       struct spider_net_descr *descr = card->tx_chain.tail;
+       struct sk_buff *skb;
+
+       card->tx_chain.tail = card->tx_chain.tail->next;
+       descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE;
+
+       /* unmap the skb */
+       skb = descr->skb;
+       pci_unmap_single(card->pdev, descr->buf_addr, skb->len,
+                       PCI_DMA_TODEVICE);
+       dev_kfree_skb_any(skb);
+}
+
+/**
+ * spider_net_release_tx_chain - processes sent tx descriptors
+ * @card: adapter structure
+ * @brutal: if set, don't care about whether descriptor seems to be in use
+ *
+ * returns 0 if the tx ring is empty, otherwise 1.
+ *
+ * spider_net_release_tx_chain releases the tx descriptors that spider has
+ * finished with (if non-brutal) or simply release tx descriptors (if brutal).
+ * If some other context is calling this function, we return 1 so that we're
+ * scheduled again (if we were scheduled) and will not loose initiative.
+ */
+static int
+spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
+{
+       struct spider_net_descr_chain *chain = &card->tx_chain;
+       int status;
+
+       spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR);
+
+       while (chain->tail != chain->head) {
+               status = spider_net_get_descr_status(chain->tail);
+               switch (status) {
+               case SPIDER_NET_DESCR_COMPLETE:
+                       card->netdev_stats.tx_packets++;
+                       card->netdev_stats.tx_bytes += chain->tail->skb->len;
+                       break;
+
+               case SPIDER_NET_DESCR_CARDOWNED:
+                       if (!brutal)
+                               return 1;
+                       /* fallthrough, if we release the descriptors
+                        * brutally (then we don't care about
+                        * SPIDER_NET_DESCR_CARDOWNED) */
+
+               case SPIDER_NET_DESCR_RESPONSE_ERROR:
+               case SPIDER_NET_DESCR_PROTECTION_ERROR:
+               case SPIDER_NET_DESCR_FORCE_END:
+                       if (netif_msg_tx_err(card))
+                               pr_err("%s: forcing end of tx descriptor "
+                                      "with status x%02x\n",
+                                      card->netdev->name, status);
+                       card->netdev_stats.tx_errors++;
+                       break;
+
+               default:
+                       card->netdev_stats.tx_dropped++;
+                       return 1;
+               }
+               spider_net_release_tx_descr(card);
+       }
 
        return 0;
 }
@@ -896,18 +763,32 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
  * spider_net_kick_tx_dma writes the current tx chain head as start address
  * of the tx descriptor chain and enables the transmission DMA engine
  */
-static void
-spider_net_kick_tx_dma(struct spider_net_card *card,
-                      struct spider_net_descr *descr)
+static inline void
+spider_net_kick_tx_dma(struct spider_net_card *card)
 {
-       /* this is the only descriptor in the output chain.
-        * Enable TX DMA */
+       struct spider_net_descr *descr;
 
-       spider_net_write_reg(card, SPIDER_NET_GDTDCHA,
-                            descr->bus_addr);
+       if (spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR) &
+                       SPIDER_NET_TX_DMA_EN)
+               goto out;
 
-       spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
-                            SPIDER_NET_DMA_TX_VALUE);
+       descr = card->tx_chain.tail;
+       for (;;) {
+               if (spider_net_get_descr_status(descr) ==
+                               SPIDER_NET_DESCR_CARDOWNED) {
+                       spider_net_write_reg(card, SPIDER_NET_GDTDCHA,
+                                       descr->bus_addr);
+                       spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
+                                       SPIDER_NET_DMA_TX_VALUE);
+                       break;
+               }
+               if (descr == card->tx_chain.head)
+                       break;
+               descr = descr->next;
+       }
+
+out:
+       mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER);
 }
 
 /**
@@ -915,47 +796,69 @@ spider_net_kick_tx_dma(struct spider_net_card *card,
  * @skb: packet to send out
  * @netdev: interface device structure
  *
- * returns 0 on success, <0 on failure
+ * returns 0 on success, !0 on failure
  */
 static int
 spider_net_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
        struct spider_net_card *card = netdev_priv(netdev);
-       struct spider_net_descr *descr;
+       struct spider_net_descr_chain *chain = &card->tx_chain;
+       struct spider_net_descr *descr = chain->head;
+       unsigned long flags;
        int result;
 
+       spin_lock_irqsave(&chain->lock, flags);
+
        spider_net_release_tx_chain(card, 0);
 
-       descr = spider_net_get_next_tx_descr(card);
+       if (chain->head->next == chain->tail->prev) {
+               card->netdev_stats.tx_dropped++;
+               result = NETDEV_TX_LOCKED;
+               goto out;
+       }
 
-       if (!descr)
-               goto error;
+       if (spider_net_get_descr_status(descr) != SPIDER_NET_DESCR_NOT_IN_USE) {
+               result = NETDEV_TX_LOCKED;
+               goto out;
+       }
 
-       result = spider_net_prepare_tx_descr(card, descr, skb);
-       if (result)
-               goto error;
+       if (spider_net_prepare_tx_descr(card, skb) != 0) {
+               card->netdev_stats.tx_dropped++;
+               result = NETDEV_TX_BUSY;
+               goto out;
+       }
+
+       result = NETDEV_TX_OK;
 
+       spider_net_kick_tx_dma(card);
        card->tx_chain.head = card->tx_chain.head->next;
 
-       if (spider_net_get_descr_status(descr->prev) !=
-           SPIDER_NET_DESCR_CARDOWNED) {
-               /* make sure the current descriptor is in memory. Then
-                * kicking it on again makes sense, if the previous is not
-                * card-owned anymore. Check the previous descriptor twice
-                * to omit an mb() in heavy traffic cases */
-               mb();
-               if (spider_net_get_descr_status(descr->prev) !=
-                   SPIDER_NET_DESCR_CARDOWNED)
-                       spider_net_kick_tx_dma(card, descr);
-       }
+out:
+       spin_unlock_irqrestore(&chain->lock, flags);
+       netif_wake_queue(netdev);
+       return result;
+}
 
-       mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER);
+/**
+ * spider_net_cleanup_tx_ring - cleans up the TX ring
+ * @card: card structure
+ *
+ * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use
+ * interrupts to cleanup our TX ring) and returns sent packets to the stack
+ * by freeing them
+ */
+static void
+spider_net_cleanup_tx_ring(struct spider_net_card *card)
+{
+       unsigned long flags;
 
-       return NETDEV_TX_OK;
+       spin_lock_irqsave(&card->tx_chain.lock, flags);
 
-error:
-       card->netdev_stats.tx_dropped++;
-       return NETDEV_TX_BUSY;
+       if ((spider_net_release_tx_chain(card, 0) != 0) &&
+           (card->netdev->flags & IFF_UP))
+               spider_net_kick_tx_dma(card);
+
+       spin_unlock_irqrestore(&card->tx_chain.lock, flags);
 }
 
 /**
@@ -1002,7 +905,7 @@ spider_net_pass_skb_up(struct spider_net_descr *descr,
 
        /* unmap descriptor */
        pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME,
-                        PCI_DMA_BIDIRECTIONAL);
+                       PCI_DMA_FROMDEVICE);
 
        /* the cases we'll throw away the packet immediately */
        if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) {
@@ -1067,14 +970,11 @@ spider_net_pass_skb_up(struct spider_net_descr *descr,
 static int
 spider_net_decode_one_descr(struct spider_net_card *card, int napi)
 {
-       enum spider_net_descr_status status;
-       struct spider_net_descr *descr;
-       struct spider_net_descr_chain *chain;
+       struct spider_net_descr_chain *chain = &card->rx_chain;
+       struct spider_net_descr *descr = chain->tail;
+       int status;
        int result;
 
-       chain = &card->rx_chain;
-       descr = chain->tail;
-
        status = spider_net_get_descr_status(descr);
 
        if (status == SPIDER_NET_DESCR_CARDOWNED) {
@@ -1103,7 +1003,7 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi)
                               card->netdev->name, status);
                card->netdev_stats.rx_dropped++;
                pci_unmap_single(card->pdev, descr->buf_addr,
-                                SPIDER_NET_MAX_FRAME, PCI_DMA_BIDIRECTIONAL);
+                               SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE);
                dev_kfree_skb_irq(descr->skb);
                goto refill;
        }
@@ -1119,7 +1019,7 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi)
        /* ok, we've got a packet in descr */
        result = spider_net_pass_skb_up(descr, card, napi);
 refill:
-       spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE);
+       descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE;
        /* change the descriptor state: */
        if (!napi)
                spider_net_refill_rx_chain(card);
@@ -1291,21 +1191,6 @@ spider_net_set_mac(struct net_device *netdev, void *p)
 }
 
 /**
- * spider_net_enable_txdmac - enables a TX DMA controller
- * @card: card structure
- *
- * spider_net_enable_txdmac enables the TX DMA controller by setting the
- * descriptor chain tail address
- */
-static void
-spider_net_enable_txdmac(struct spider_net_card *card)
-{
-       /* assume chain is aligned correctly */
-       spider_net_write_reg(card, SPIDER_NET_GDTDCHA,
-                            card->tx_chain.tail->bus_addr);
-}
-
-/**
  * spider_net_handle_rxram_full - cleans up RX ring upon RX RAM full interrupt
  * @card: card structure
  *
@@ -1653,7 +1538,6 @@ spider_net_enable_card(struct spider_net_card *card)
                { SPIDER_NET_GMRWOLCTRL, 0 },
                { SPIDER_NET_GTESTMD, 0x10000000 },
                { SPIDER_NET_GTTQMSK, 0x00400040 },
-               { SPIDER_NET_GTESTMD, 0 },
 
                { SPIDER_NET_GMACINTEN, 0 },
 
@@ -1692,9 +1576,6 @@ spider_net_enable_card(struct spider_net_card *card)
 
        spider_net_write_reg(card, SPIDER_NET_GRXDMAEN, SPIDER_NET_WOL_VALUE);
 
-       /* set chain tail adress for TX chain */
-       spider_net_enable_txdmac(card);
-
        spider_net_write_reg(card, SPIDER_NET_GMACLENLMT,
                             SPIDER_NET_LENLMT_VALUE);
        spider_net_write_reg(card, SPIDER_NET_GMACMODE,
@@ -1709,6 +1590,9 @@ spider_net_enable_card(struct spider_net_card *card)
                             SPIDER_NET_INT1_MASK_VALUE);
        spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK,
                             SPIDER_NET_INT2_MASK_VALUE);
+
+       spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
+                            SPIDER_NET_GDTDCEIDIS);
 }
 
 /**
@@ -1728,10 +1612,12 @@ spider_net_open(struct net_device *netdev)
 
        result = -ENOMEM;
        if (spider_net_init_chain(card, &card->tx_chain,
-                         card->descr, tx_descriptors))
+                       card->descr,
+                       PCI_DMA_TODEVICE, tx_descriptors))
                goto alloc_tx_failed;
        if (spider_net_init_chain(card, &card->rx_chain,
-                         card->descr + tx_descriptors, rx_descriptors))
+                       card->descr + tx_descriptors,
+                       PCI_DMA_FROMDEVICE, rx_descriptors))
                goto alloc_rx_failed;
 
        /* allocate rx skbs */
@@ -1938,7 +1824,7 @@ spider_net_workaround_rxramfull(struct spider_net_card *card)
        /* empty sequencer data */
        for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS;
             sequencer++) {
-               spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT +
+               spider_net_write_reg(card, SPIDER_NET_GSnPRGADR +
                                     sequencer * 8, 0x0);
                for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) {
                        spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT +
@@ -1955,6 +1841,49 @@ spider_net_workaround_rxramfull(struct spider_net_card *card)
 }
 
 /**
+ * spider_net_stop - called upon ifconfig down
+ * @netdev: interface device structure
+ *
+ * always returns 0
+ */
+int
+spider_net_stop(struct net_device *netdev)
+{
+       struct spider_net_card *card = netdev_priv(netdev);
+
+       tasklet_kill(&card->rxram_full_tl);
+       netif_poll_disable(netdev);
+       netif_carrier_off(netdev);
+       netif_stop_queue(netdev);
+       del_timer_sync(&card->tx_timer);
+
+       /* disable/mask all interrupts */
+       spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
+       spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
+       spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
+
+       /* free_irq(netdev->irq, netdev);*/
+       free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev);
+
+       spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
+                            SPIDER_NET_DMA_TX_FEND_VALUE);
+
+       /* turn off DMA, force end */
+       spider_net_disable_rxdmac(card);
+
+       /* release chains */
+       if (spin_trylock(&card->tx_chain.lock)) {
+               spider_net_release_tx_chain(card, 1);
+               spin_unlock(&card->tx_chain.lock);
+       }
+
+       spider_net_free_chain(card, &card->tx_chain);
+       spider_net_free_chain(card, &card->rx_chain);
+
+       return 0;
+}
+
+/**
  * spider_net_tx_timeout_task - task scheduled by the watchdog timeout
  * function (to be called not under interrupt status)
  * @data: data, is interface device structure
@@ -1982,7 +1911,7 @@ spider_net_tx_timeout_task(void *data)
                goto out;
 
        spider_net_open(netdev);
-       spider_net_kick_tx_dma(card, card->tx_chain.head);
+       spider_net_kick_tx_dma(card);
        netif_device_attach(netdev);
 
 out:
@@ -2065,7 +1994,6 @@ spider_net_setup_netdev(struct spider_net_card *card)
 
        pci_set_drvdata(card->pdev, netdev);
 
-       atomic_set(&card->tx_chain_release,0);
        card->rxram_full_tl.data = (unsigned long) card;
        card->rxram_full_tl.func =
                (void (*)(unsigned long)) spider_net_handle_rxram_full;
@@ -2079,7 +2007,7 @@ spider_net_setup_netdev(struct spider_net_card *card)
 
        spider_net_setup_netdev_ops(netdev);
 
-       netdev->features = NETIF_F_HW_CSUM;
+       netdev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX;
        /* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
         *              NETIF_F_HW_VLAN_FILTER */
 
index 3b8d951..f6dcf18 100644 (file)
@@ -208,7 +208,10 @@ extern char spider_net_driver_name[];
 #define SPIDER_NET_DMA_RX_VALUE                0x80000000
 #define SPIDER_NET_DMA_RX_FEND_VALUE   0x00030003
 /* to set TX_DMA_EN */
-#define SPIDER_NET_DMA_TX_VALUE                0x80000000
+#define SPIDER_NET_TX_DMA_EN           0x80000000
+#define SPIDER_NET_GDTDCEIDIS          0x00000002
+#define SPIDER_NET_DMA_TX_VALUE                SPIDER_NET_TX_DMA_EN | \
+                                       SPIDER_NET_GDTDCEIDIS
 #define SPIDER_NET_DMA_TX_FEND_VALUE   0x00030003
 
 /* SPIDER_NET_UA_DESCR_VALUE is OR'ed with the unicast address */
@@ -329,55 +332,23 @@ enum spider_net_int2_status {
                                  (~SPIDER_NET_TXINT) & \
                                  (~SPIDER_NET_RXINT) )
 
-#define SPIDER_NET_GPREXEC             0x80000000
-#define SPIDER_NET_GPRDAT_MASK         0x0000ffff
+#define SPIDER_NET_GPREXEC                     0x80000000
+#define SPIDER_NET_GPRDAT_MASK                 0x0000ffff
 
-/* descriptor bits
- *
- * 1010                                        descriptor ready
- *     0                               descr in middle of chain
- *      000                            fixed to 0
- *
- *         0                           no interrupt on completion
- *          000                                fixed to 0
- *             1                       no ipsec processing
- *              1                      last descriptor for this frame
- *               00                    no checksum
- *               10                    tcp checksum
- *               11                    udp checksum
- *
- *                 00                  fixed to 0
- *                   0                 fixed to 0
- *                    0                        no interrupt on response errors
- *                     0               no interrupt on invalid descr
- *                      0              no interrupt on dma process termination
- *                       0             no interrupt on descr chain end
- *                        0            no interrupt on descr complete
- *
- *                         000         fixed to 0
- *                            0                response error interrupt status
- *                             0       invalid descr status
- *                              0      dma termination status
- *                               0     descr chain end status
- *                                0    descr complete status */
-#define SPIDER_NET_DMAC_CMDSTAT_NOCS   0xa00c0000
-#define SPIDER_NET_DMAC_CMDSTAT_TCPCS  0xa00e0000
-#define SPIDER_NET_DMAC_CMDSTAT_UDPCS  0xa00f0000
-#define SPIDER_NET_DESCR_IND_PROC_SHIFT        28
-#define SPIDER_NET_DESCR_IND_PROC_MASKO        0x0fffffff
-
-/* descr ready, descr is in middle of chain, get interrupt on completion */
-#define SPIDER_NET_DMAC_RX_CARDOWNED   0xa0800000
-
-enum spider_net_descr_status {
-       SPIDER_NET_DESCR_COMPLETE               = 0x00, /* used in rx and tx */
-       SPIDER_NET_DESCR_RESPONSE_ERROR         = 0x01, /* used in rx and tx */
-       SPIDER_NET_DESCR_PROTECTION_ERROR       = 0x02, /* used in rx and tx */
-       SPIDER_NET_DESCR_FRAME_END              = 0x04, /* used in rx */
-       SPIDER_NET_DESCR_FORCE_END              = 0x05, /* used in rx and tx */
-       SPIDER_NET_DESCR_CARDOWNED              = 0x0a, /* used in rx and tx */
-       SPIDER_NET_DESCR_NOT_IN_USE /* any other value */
-};
+#define SPIDER_NET_DMAC_NOINTR_COMPLETE                0x00800000
+#define SPIDER_NET_DMAC_NOCS                   0x00040000
+#define SPIDER_NET_DMAC_TCP                    0x00020000
+#define SPIDER_NET_DMAC_UDP                    0x00030000
+#define SPIDER_NET_TXDCEST                     0x08000000
+
+#define SPIDER_NET_DESCR_IND_PROC_MASK         0xF0000000
+#define SPIDER_NET_DESCR_COMPLETE              0x00000000 /* used in rx and tx */
+#define SPIDER_NET_DESCR_RESPONSE_ERROR                0x10000000 /* used in rx and tx */
+#define SPIDER_NET_DESCR_PROTECTION_ERROR      0x20000000 /* used in rx and tx */
+#define SPIDER_NET_DESCR_FRAME_END             0x40000000 /* used in rx */
+#define SPIDER_NET_DESCR_FORCE_END             0x50000000 /* used in rx and tx */
+#define SPIDER_NET_DESCR_CARDOWNED             0xA0000000 /* used in rx and tx */
+#define SPIDER_NET_DESCR_NOT_IN_USE            0xF0000000
 
 struct spider_net_descr {
        /* as defined by the hardware */
@@ -398,7 +369,7 @@ struct spider_net_descr {
 } __attribute__((aligned(32)));
 
 struct spider_net_descr_chain {
-       /* we walk from tail to head */
+       spinlock_t lock;
        struct spider_net_descr *head;
        struct spider_net_descr *tail;
 };
@@ -453,8 +424,6 @@ struct spider_net_card {
 
        struct spider_net_descr_chain tx_chain;
        struct spider_net_descr_chain rx_chain;
-       atomic_t rx_chain_refill;
-       atomic_t tx_chain_release;
 
        struct net_device_stats netdev_stats;
 
index 8673fd4..c6f5bc3 100644 (file)
@@ -3255,12 +3255,7 @@ static void __devexit happy_meal_pci_remove(struct pci_dev *pdev)
 }
 
 static struct pci_device_id happymeal_pci_ids[] = {
-       {
-         .vendor       = PCI_VENDOR_ID_SUN,
-         .device       = PCI_DEVICE_ID_SUN_HAPPYMEAL,
-         .subvendor    = PCI_ANY_ID,
-         .subdevice    = PCI_ANY_ID,
-       },
+       { PCI_DEVICE(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_HAPPYMEAL) },
        { }                     /* Terminating entry */
 };
 
@@ -3275,7 +3270,7 @@ static struct pci_driver hme_pci_driver = {
 
 static int __init happy_meal_pci_init(void)
 {
-       return pci_module_init(&hme_pci_driver);
+       return pci_register_driver(&hme_pci_driver);
 }
 
 static void happy_meal_pci_exit(void)
index 1ef9fd3..0e3fdf7 100644 (file)
@@ -1537,7 +1537,7 @@ static int __init sparc_lance_init(void)
 {
        if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) ||
            (idprom->id_machtype == (SM_SUN4|SM_4_470))) {
-               memset(&sun4_sdev, 0, sizeof(sdev));
+               memset(&sun4_sdev, 0, sizeof(struct sbus_dev));
                sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr;
                sun4_sdev.irqs[0] = 6;
                return sparc_lance_probe_one(&sun4_sdev, NULL, NULL);
@@ -1547,16 +1547,16 @@ static int __init sparc_lance_init(void)
 
 static int __exit sunlance_sun4_remove(void)
 {
-       struct lance_private *lp = dev_get_drvdata(&sun4_sdev->dev);
+       struct lance_private *lp = dev_get_drvdata(&sun4_sdev.ofdev.dev);
        struct net_device *net_dev = lp->dev;
 
        unregister_netdevice(net_dev);
 
-       lance_free_hwresources(root_lance_dev);
+       lance_free_hwresources(lp);
 
        free_netdev(net_dev);
 
-       dev_set_drvdata(&sun4_sdev->dev, NULL);
+       dev_set_drvdata(&sun4_sdev.ofdev.dev, NULL);
 
        return 0;
 }
index ce6f3be..1b8138f 100644 (file)
@@ -68,8 +68,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.62"
-#define DRV_MODULE_RELDATE     "June 30, 2006"
+#define DRV_MODULE_VERSION     "3.63"
+#define DRV_MODULE_RELDATE     "July 25, 2006"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -3590,6 +3590,28 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id,
 static int tg3_init_hw(struct tg3 *, int);
 static int tg3_halt(struct tg3 *, int, int);
 
+/* Restart hardware after configuration changes, self-test, etc.
+ * Invoked with tp->lock held.
+ */
+static int tg3_restart_hw(struct tg3 *tp, int reset_phy)
+{
+       int err;
+
+       err = tg3_init_hw(tp, reset_phy);
+       if (err) {
+               printk(KERN_ERR PFX "%s: Failed to re-initialize device, "
+                      "aborting.\n", tp->dev->name);
+               tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+               tg3_full_unlock(tp);
+               del_timer_sync(&tp->timer);
+               tp->irq_sync = 0;
+               netif_poll_enable(tp->dev);
+               dev_close(tp->dev);
+               tg3_full_lock(tp, 0);
+       }
+       return err;
+}
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void tg3_poll_controller(struct net_device *dev)
 {
@@ -3630,13 +3652,15 @@ static void tg3_reset_task(void *_data)
        }
 
        tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
-       tg3_init_hw(tp, 1);
+       if (tg3_init_hw(tp, 1))
+               goto out;
 
        tg3_netif_start(tp);
 
        if (restart_timer)
                mod_timer(&tp->timer, jiffies + 1);
 
+out:
        tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK;
 
        tg3_full_unlock(tp);
@@ -4124,6 +4148,7 @@ static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
 static int tg3_change_mtu(struct net_device *dev, int new_mtu)
 {
        struct tg3 *tp = netdev_priv(dev);
+       int err;
 
        if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp))
                return -EINVAL;
@@ -4144,13 +4169,14 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
 
        tg3_set_mtu(dev, tp, new_mtu);
 
-       tg3_init_hw(tp, 0);
+       err = tg3_restart_hw(tp, 0);
 
-       tg3_netif_start(tp);
+       if (!err)
+               tg3_netif_start(tp);
 
        tg3_full_unlock(tp);
 
-       return 0;
+       return err;
 }
 
 /* Free up pending packets in all rx/tx rings.
@@ -4232,7 +4258,7 @@ static void tg3_free_rings(struct tg3 *tp)
  * end up in the driver.  tp->{tx,}lock are held and thus
  * we may not sleep.
  */
-static void tg3_init_rings(struct tg3 *tp)
+static int tg3_init_rings(struct tg3 *tp)
 {
        u32 i;
 
@@ -4281,18 +4307,38 @@ static void tg3_init_rings(struct tg3 *tp)
 
        /* Now allocate fresh SKBs for each rx ring. */
        for (i = 0; i < tp->rx_pending; i++) {
-               if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD,
-                                    -1, i) < 0)
+               if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD, -1, i) < 0) {
+                       printk(KERN_WARNING PFX
+                              "%s: Using a smaller RX standard ring, "
+                              "only %d out of %d buffers were allocated "
+                              "successfully.\n",
+                              tp->dev->name, i, tp->rx_pending);
+                       if (i == 0)
+                               return -ENOMEM;
+                       tp->rx_pending = i;
                        break;
+               }
        }
 
        if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
                for (i = 0; i < tp->rx_jumbo_pending; i++) {
                        if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO,
-                                            -1, i) < 0)
+                                            -1, i) < 0) {
+                               printk(KERN_WARNING PFX
+                                      "%s: Using a smaller RX jumbo ring, "
+                                      "only %d out of %d buffers were "
+                                      "allocated successfully.\n",
+                                      tp->dev->name, i, tp->rx_jumbo_pending);
+                               if (i == 0) {
+                                       tg3_free_rings(tp);
+                                       return -ENOMEM;
+                               }
+                               tp->rx_jumbo_pending = i;
                                break;
+                       }
                }
        }
+       return 0;
 }
 
 /*
@@ -5815,6 +5861,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
 {
        struct tg3 *tp = netdev_priv(dev);
        struct sockaddr *addr = p;
+       int err = 0;
 
        if (!is_valid_ether_addr(addr->sa_data))
                return -EINVAL;
@@ -5832,9 +5879,9 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
                tg3_full_lock(tp, 1);
 
                tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
-               tg3_init_hw(tp, 0);
-
-               tg3_netif_start(tp);
+               err = tg3_restart_hw(tp, 0);
+               if (!err)
+                       tg3_netif_start(tp);
                tg3_full_unlock(tp);
        } else {
                spin_lock_bh(&tp->lock);
@@ -5842,7 +5889,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
                spin_unlock_bh(&tp->lock);
        }
 
-       return 0;
+       return err;
 }
 
 /* tp->lock is held. */
@@ -5942,7 +5989,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
         * can only do this after the hardware has been
         * successfully reset.
         */
-       tg3_init_rings(tp);
+       err = tg3_init_rings(tp);
+       if (err)
+               return err;
 
        /* This value is determined during the probe time DMA
         * engine test, tg3_test_dma.
@@ -7956,7 +8005,7 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *
 static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 {
        struct tg3 *tp = netdev_priv(dev);
-       int irq_sync = 0;
+       int irq_sync = 0, err = 0;
   
        if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) ||
            (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) ||
@@ -7980,13 +8029,14 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
 
        if (netif_running(dev)) {
                tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
-               tg3_init_hw(tp, 1);
-               tg3_netif_start(tp);
+               err = tg3_restart_hw(tp, 1);
+               if (!err)
+                       tg3_netif_start(tp);
        }
 
        tg3_full_unlock(tp);
   
-       return 0;
+       return err;
 }
   
 static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
@@ -8001,7 +8051,7 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam
 static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
 {
        struct tg3 *tp = netdev_priv(dev);
-       int irq_sync = 0;
+       int irq_sync = 0, err = 0;
   
        if (netif_running(dev)) {
                tg3_netif_stop(tp);
@@ -8025,13 +8075,14 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
 
        if (netif_running(dev)) {
                tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
-               tg3_init_hw(tp, 1);
-               tg3_netif_start(tp);
+               err = tg3_restart_hw(tp, 1);
+               if (!err)
+                       tg3_netif_start(tp);
        }
 
        tg3_full_unlock(tp);
   
-       return 0;
+       return err;
 }
   
 static u32 tg3_get_rx_csum(struct net_device *dev)
@@ -8666,7 +8717,9 @@ static int tg3_test_loopback(struct tg3 *tp)
        if (!netif_running(tp->dev))
                return TG3_LOOPBACK_FAILED;
 
-       tg3_reset_hw(tp, 1);
+       err = tg3_reset_hw(tp, 1);
+       if (err)
+               return TG3_LOOPBACK_FAILED;
 
        if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK))
                err |= TG3_MAC_LOOPBACK_FAILED;
@@ -8740,8 +8793,8 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
                tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
                if (netif_running(dev)) {
                        tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
-                       tg3_init_hw(tp, 1);
-                       tg3_netif_start(tp);
+                       if (!tg3_restart_hw(tp, 1))
+                               tg3_netif_start(tp);
                }
 
                tg3_full_unlock(tp);
@@ -11699,7 +11752,8 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
                tg3_full_lock(tp, 0);
 
                tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
-               tg3_init_hw(tp, 1);
+               if (tg3_restart_hw(tp, 1))
+                       goto out;
 
                tp->timer.expires = jiffies + tp->timer_offset;
                add_timer(&tp->timer);
@@ -11707,6 +11761,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
                netif_device_attach(dev);
                tg3_netif_start(tp);
 
+out:
                tg3_full_unlock(tp);
        }
 
@@ -11733,16 +11788,19 @@ static int tg3_resume(struct pci_dev *pdev)
        tg3_full_lock(tp, 0);
 
        tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
-       tg3_init_hw(tp, 1);
+       err = tg3_restart_hw(tp, 1);
+       if (err)
+               goto out;
 
        tp->timer.expires = jiffies + tp->timer_offset;
        add_timer(&tp->timer);
 
        tg3_netif_start(tp);
 
+out:
        tg3_full_unlock(tp);
 
-       return 0;
+       return err;
 }
 
 static struct pci_driver tg3_driver = {
index 2c09ec9..435e91e 100644 (file)
@@ -197,7 +197,6 @@ static int c101_open(struct net_device *dev)
        sca_out(IE0_TXINT, MSCI0_OFFSET + IE0, port);
 
        set_carrier(port);
-       printk(KERN_DEBUG "0x%X\n", sca_in(MSCI1_OFFSET + ST3, port));
 
        /* enable MSCI1 CDCD interrupt */
        sca_out(IE1_CDCD, MSCI1_OFFSET + IE1, port);
@@ -449,4 +448,5 @@ module_exit(c101_cleanup);
 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
 MODULE_DESCRIPTION("Moxa C101 serial port driver");
 MODULE_LICENSE("GPL v2");
-module_param(hw, charp, 0444); /* hw=irq,ram:irq,... */
+module_param(hw, charp, 0444);
+MODULE_PARM_DESC(hw, "irq,ram:irq,...");
index b81263e..fbaab5b 100644 (file)
@@ -107,6 +107,7 @@ int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
                dev->hard_header = NULL;
                dev->type = ARPHRD_PPP;
                dev->addr_len = 0;
+               netif_dormant_off(dev);
                return 0;
        }
 
index 9456d31..f15aa6b 100644 (file)
@@ -82,6 +82,7 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr)
                dev->type = ARPHRD_RAWHDLC;
                dev->flags = IFF_POINTOPOINT | IFF_NOARP;
                dev->addr_len = 0;
+               netif_dormant_off(dev);
                return 0;
        }
 
index b1285cc..d188498 100644 (file)
@@ -100,6 +100,7 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
                dev->tx_queue_len = old_qlen;
                memcpy(dev->dev_addr, "\x00\x01", 2);
                 get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2);
+               netif_dormant_off(dev);
                return 0;
        }
 
index 07e5eef..a867fb4 100644 (file)
@@ -212,6 +212,7 @@ int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr)
                dev->hard_header = NULL;
                dev->type = ARPHRD_X25;
                dev->addr_len = 0;
+               netif_dormant_off(dev);
                return 0;
        }
 
index e013b81..dcf46ad 100644 (file)
@@ -564,4 +564,5 @@ module_exit(n2_cleanup);
 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
 MODULE_DESCRIPTION("RISCom/N2 serial port driver");
 MODULE_LICENSE("GPL v2");
-module_param(hw, charp, 0444); /* hw=io,irq,ram,ports:io,irq,... */
+module_param(hw, charp, 0444);
+MODULE_PARM_DESC(hw, "io,irq,ram,ports:io,irq,...");
index fa9d2c4..2e8ac99 100644 (file)
@@ -447,6 +447,7 @@ config AIRO_CS
        tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
        depends on NET_RADIO && PCMCIA && (BROKEN || !M32R)
        select CRYPTO
+       select CRYPTO_AES
        ---help---
          This is the standard Linux driver to support Cisco/Aironet PCMCIA
          802.11 wireless cards.  This driver is the same as the Aironet
index 3889f79..df317c1 100644 (file)
@@ -3701,7 +3701,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
        }
        if (sec->flags & SEC_AUTH_MODE) {
                secinfo->auth_mode = sec->auth_mode;
-               dprintk(", .auth_mode = %d\n", sec->auth_mode);
+               dprintk(", .auth_mode = %d", sec->auth_mode);
        }
        dprintk("\n");
        if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED &&
index d6ed578..317ace7 100644 (file)
@@ -2875,7 +2875,7 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev,
        if (orinoco_lock(priv, &flags) != 0)
                return -EBUSY;
 
-       if (erq->pointer) {
+       if (erq->length > 0) {
                if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
                        index = priv->tx_key;
 
@@ -2918,7 +2918,7 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev,
        if (erq->flags & IW_ENCODE_RESTRICTED)
                restricted = 1;
 
-       if (erq->pointer) {
+       if (erq->pointer && erq->length > 0) {
                priv->keys[index].len = cpu_to_le16(xlen);
                memset(priv->keys[index].data, 0,
                       sizeof(priv->keys[index].data));
index 662ecc8..c52e9bc 100644 (file)
@@ -1820,6 +1820,8 @@ static int zd1201_probe(struct usb_interface *interface,
            zd->dev->name);
 
        usb_set_intfdata(interface, zd);
+       zd1201_enable(zd);      /* zd1201 likes to startup enabled, */
+       zd1201_disable(zd);     /* interfering with all the wifis in range */
        return 0;
 
 err_net:
index 4cd879c..1140302 100644 (file)
@@ -304,6 +304,7 @@ static int __init xpram_setup_sizes(unsigned long pages)
 {
        unsigned long mem_needed;
        unsigned long mem_auto;
+       unsigned long long size;
        int mem_auto_no;
        int i;
 
@@ -321,9 +322,19 @@ static int __init xpram_setup_sizes(unsigned long pages)
        mem_needed = 0;
        mem_auto_no = 0;
        for (i = 0; i < xpram_devs; i++) {
-               if (sizes[i])
-                       xpram_sizes[i] =
-                               (memparse(sizes[i], &sizes[i]) + 3) & -4UL;
+               if (sizes[i]) {
+                       size = simple_strtoull(sizes[i], &sizes[i], 0);
+                       switch (sizes[i][0]) {
+                       case 'g':
+                       case 'G':
+                               size <<= 20;
+                               break;
+                       case 'm':
+                       case 'M':
+                               size <<= 10;
+                       }
+                       xpram_sizes[i] = (size + 3) & -4UL;
+               }
                if (xpram_sizes[i])
                        mem_needed += xpram_sizes[i];
                else
index 95e285b..7a84014 100644 (file)
@@ -1106,10 +1106,10 @@ raw3270_delete_device(struct raw3270 *rp)
 
        /* Remove from device chain. */
        mutex_lock(&raw3270_mutex);
-       if (rp->clttydev)
+       if (rp->clttydev && !IS_ERR(rp->clttydev))
                class_device_destroy(class3270,
                                     MKDEV(IBM_TTY3270_MAJOR, rp->minor));
-       if (rp->cltubdev)
+       if (rp->cltubdev && !IS_ERR(rp->cltubdev))
                class_device_destroy(class3270,
                                     MKDEV(IBM_FS3270_MAJOR, rp->minor));
        list_del_init(&rp->list);
@@ -1173,21 +1173,37 @@ static struct attribute_group raw3270_attr_group = {
        .attrs = raw3270_attrs,
 };
 
-static void
-raw3270_create_attributes(struct raw3270 *rp)
+static int raw3270_create_attributes(struct raw3270 *rp)
 {
-       //FIXME: check return code
-       sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
-       rp->clttydev =
-               class_device_create(class3270, NULL,
-                                   MKDEV(IBM_TTY3270_MAJOR, rp->minor),
-                                   &rp->cdev->dev, "tty%s",
-                                   rp->cdev->dev.bus_id);
-       rp->cltubdev =
-               class_device_create(class3270, NULL,
-                                   MKDEV(IBM_FS3270_MAJOR, rp->minor),
-                                   &rp->cdev->dev, "tub%s",
-                                   rp->cdev->dev.bus_id);
+       int rc;
+
+       rc = sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
+       if (rc)
+               goto out;
+
+       rp->clttydev = class_device_create(class3270, NULL,
+                                          MKDEV(IBM_TTY3270_MAJOR, rp->minor),
+                                          &rp->cdev->dev, "tty%s",
+                                          rp->cdev->dev.bus_id);
+       if (IS_ERR(rp->clttydev)) {
+               rc = PTR_ERR(rp->clttydev);
+               goto out_ttydev;
+       }
+
+       rp->cltubdev = class_device_create(class3270, NULL,
+                                          MKDEV(IBM_FS3270_MAJOR, rp->minor),
+                                          &rp->cdev->dev, "tub%s",
+                                          rp->cdev->dev.bus_id);
+       if (!IS_ERR(rp->cltubdev))
+               goto out;
+
+       rc = PTR_ERR(rp->cltubdev);
+       class_device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
+
+out_ttydev:
+       sysfs_remove_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
+out:
+       return rc;
 }
 
 /*
@@ -1255,7 +1271,9 @@ raw3270_set_online (struct ccw_device *cdev)
        rc = raw3270_reset_device(rp);
        if (rc)
                goto failure;
-       raw3270_create_attributes(rp);
+       rc = raw3270_create_attributes(rp);
+       if (rc)
+               goto failure;
        set_bit(RAW3270_FLAGS_READY, &rp->flags);
        mutex_lock(&raw3270_mutex);
        list_for_each_entry(np, &raw3270_notifier, list)
index a5c68e6..643b6d0 100644 (file)
@@ -76,14 +76,22 @@ struct tape_class_device *register_tape_dev(
                                device,
                                "%s", tcd->device_name
                        );
-       sysfs_create_link(
+       rc = PTR_ERR(tcd->class_device);
+       if (rc)
+               goto fail_with_cdev;
+       rc = sysfs_create_link(
                &device->kobj,
                &tcd->class_device->kobj,
                tcd->mode_name
        );
+       if (rc)
+               goto fail_with_class_device;
 
        return tcd;
 
+fail_with_class_device:
+       class_device_destroy(tape_class, tcd->char_device->dev);
+
 fail_with_cdev:
        cdev_del(tcd->char_device);
 
index 122b4d8..2826aed 100644 (file)
@@ -543,20 +543,24 @@ int
 tape_generic_probe(struct ccw_device *cdev)
 {
        struct tape_device *device;
+       int ret;
 
        device = tape_alloc_device();
        if (IS_ERR(device))
                return -ENODEV;
-       PRINT_INFO("tape device %s found\n", cdev->dev.bus_id);
+       ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
+       ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
+       if (ret) {
+               tape_put_device(device);
+               PRINT_ERR("probe failed for tape device %s\n", cdev->dev.bus_id);
+               return ret;
+       }
        cdev->dev.driver_data = device;
+       cdev->handler = __tape_do_irq;
        device->cdev = cdev;
        device->cdev_id = busid_to_int(cdev->dev.bus_id);
-       cdev->handler = __tape_do_irq;
-
-       ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
-       sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
-
-       return 0;
+       PRINT_INFO("tape device %s found\n", cdev->dev.bus_id);
+       return ret;
 }
 
 static inline void
index f26a2ee..3cba6c9 100644 (file)
@@ -152,7 +152,6 @@ ccwgroup_create(struct device *root,
        struct ccwgroup_device *gdev;
        int i;
        int rc;
-       int del_drvdata;
 
        if (argc > 256) /* disallow dumb users */
                return -EINVAL;
@@ -163,7 +162,6 @@ ccwgroup_create(struct device *root,
 
        atomic_set(&gdev->onoff, 0);
 
-       del_drvdata = 0;
        for (i = 0; i < argc; i++) {
                gdev->cdev[i] = get_ccwdev_by_busid(cdrv, argv[i]);
 
@@ -180,10 +178,8 @@ ccwgroup_create(struct device *root,
                        rc = -EINVAL;
                        goto free_dev;
                }
-       }
-       for (i = 0; i < argc; i++)
                gdev->cdev[i]->dev.driver_data = gdev;
-       del_drvdata = 1;
+       }
 
        gdev->creator_id = creator_id;
        gdev->count = argc;
@@ -226,9 +222,9 @@ error:
 free_dev:
        for (i = 0; i < argc; i++)
                if (gdev->cdev[i]) {
-                       put_device(&gdev->cdev[i]->dev);
-                       if (del_drvdata)
+                       if (gdev->cdev[i]->dev.driver_data == gdev)
                                gdev->cdev[i]->dev.driver_data = NULL;
+                       put_device(&gdev->cdev[i]->dev);
                }
        kfree(gdev);
        return rc;
index 0df3af1..828b2d3 100644 (file)
@@ -1068,6 +1068,7 @@ cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr,
        if (count) {
                interval = cmb_data->last_update -
                        cdev->private->cmb_start_time;
+               interval = (interval * 1000) >> 12;
                interval /= count;
        } else
                interval = -1;
index ac6e0c7..7a39e0b 100644 (file)
@@ -152,7 +152,8 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev)
                if (cdev->private->iretry) {
                        cdev->private->iretry--;
                        ret = cio_halt(sch);
-                       return (ret == 0) ? -EBUSY : ret;
+                       if (ret != -EBUSY)
+                               return (ret == 0) ? -EBUSY : ret;
                }
                /* halt io unsuccessful. */
                cdev->private->iretry = 255;    /* 255 clear retries. */
index 20c8eb1..8a4b581 100644 (file)
@@ -2686,9 +2686,17 @@ static struct attribute_group ctc_attr_group = {
 static int
 ctc_add_attributes(struct device *dev)
 {
-       device_create_file(dev, &dev_attr_loglevel);
-       device_create_file(dev, &dev_attr_stats);
-       return 0;
+       int rc;
+
+       rc = device_create_file(dev, &dev_attr_loglevel);
+       if (rc)
+               goto out;
+       rc = device_create_file(dev, &dev_attr_stats);
+       if (!rc)
+               goto out;
+       device_remove_file(dev, &dev_attr_loglevel);
+out:
+       return rc;
 }
 
 static void
@@ -2901,7 +2909,12 @@ ctc_new_device(struct ccwgroup_device *cgdev)
                goto out;
        }
 
-       ctc_add_attributes(&cgdev->dev);
+       if (ctc_add_attributes(&cgdev->dev)) {
+               ctc_netdev_unregister(dev);
+               dev->priv = NULL;
+               ctc_free_netdevice(dev, 1);
+               goto out;
+       }
 
        strlcpy(privptr->fsm->name, dev->name, sizeof (privptr->fsm->name));
 
index 103c414..5fff1f9 100644 (file)
@@ -8451,10 +8451,11 @@ __qeth_reboot_event_card(struct device *dev, void *data)
 static int
 qeth_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
+       int ret;
 
-       driver_for_each_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
-                              __qeth_reboot_event_card);
-       return NOTIFY_DONE;
+       ret = driver_for_each_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
+                                    __qeth_reboot_event_card);
+       return ret ? NOTIFY_BAD : NOTIFY_DONE;
 }
 
 
index 16b5977..935952e 100644 (file)
@@ -233,7 +233,7 @@ static void __init build_one_sbus(struct device_node *dp, int num_sbus)
        sbus->ofdev.node = dp;
        sbus->ofdev.dev.parent = NULL;
        sbus->ofdev.dev.bus = &sbus_bus_type;
-       strcpy(sbus->ofdev.dev.bus_id, dp->path_component_name);
+       sprintf(sbus->ofdev.dev.bus_id, "sbus%d", num_sbus);
 
        if (of_device_register(&sbus->ofdev) != 0)
                printk(KERN_DEBUG "sbus: device registration error for %s!\n",
index c690c2b..acf2927 100644 (file)
@@ -3451,12 +3451,12 @@ create_cmd (Scsi_Cmnd *cmd) {
     for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4, 
        cmd_dataout += 4, ++i) {
        u32 vbuf = cmd->use_sg
-           ? (u32)page_address(((struct scatterlist *)cmd->buffer)[i].page)+
-             ((struct scatterlist *)cmd->buffer)[i].offset
+           ? (u32)page_address(((struct scatterlist *)cmd->request_buffer)[i].page)+
+             ((struct scatterlist *)cmd->request_buffer)[i].offset
            : (u32)(cmd->request_buffer);
        u32 bbuf = virt_to_bus((void *)vbuf);
        u32 count = cmd->use_sg ?
-           ((struct scatterlist *)cmd->buffer)[i].length :
+           ((struct scatterlist *)cmd->request_buffer)[i].length :
            cmd->request_bufflen;
 
        /*
@@ -5417,7 +5417,7 @@ insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
 
            if ((buffers = cmd->use_sg)) {
                for (offset = 0, 
-                       segment = (struct scatterlist *) cmd->buffer;
+                       segment = (struct scatterlist *) cmd->request_buffer;
                     buffers && !((found = ((ptr >= (char *)page_address(segment->page)+segment->offset) && 
                            (ptr < ((char *)page_address(segment->page)+segment->offset+segment->length)))));
                     --buffers, offset += segment->length, ++segment)
index 8a4659e..bdc6bb2 100644 (file)
@@ -911,7 +911,7 @@ static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp)
                        sp->SCp.ptr =
                                (char *) virt_to_phys(sp->request_buffer);
        } else {
-               sp->SCp.buffer = (struct scatterlist *) sp->buffer;
+               sp->SCp.buffer = (struct scatterlist *) sp->request_buffer;
                sp->SCp.buffers_residual = sp->use_sg - 1;
                sp->SCp.this_residual = sp->SCp.buffer->length;
                if (esp->dma_mmu_get_scsi_sgl)
@@ -2152,29 +2152,23 @@ static int esp_do_data_finale(struct NCR_ESP *esp,
  */
 static int esp_should_clear_sync(Scsi_Cmnd *sp)
 {
-       unchar cmd1 = sp->cmnd[0];
-       unchar cmd2 = sp->data_cmnd[0];
+       unchar cmd = sp->cmnd[0];
 
        /* These cases are for spinning up a disk and
         * waiting for that spinup to complete.
         */
-       if(cmd1 == START_STOP ||
-          cmd2 == START_STOP)
+       if(cmd == START_STOP)
                return 0;
 
-       if(cmd1 == TEST_UNIT_READY ||
-          cmd2 == TEST_UNIT_READY)
+       if(cmd == TEST_UNIT_READY)
                return 0;
 
        /* One more special case for SCSI tape drives,
         * this is what is used to probe the device for
         * completion of a rewind or tape load operation.
         */
-       if(sp->device->type == TYPE_TAPE) {
-               if(cmd1 == MODE_SENSE ||
-                  cmd2 == MODE_SENSE)
-                       return 0;
-       }
+       if(sp->device->type == TYPE_TAPE && cmd == MODE_SENSE)
+               return 0;
 
        return 1;
 }
index a06f547..d05681f 100644 (file)
@@ -114,7 +114,7 @@ MODULE_DESCRIPTION("NCR Dual700 SCSI Driver");
 MODULE_LICENSE("GPL");
 module_param(NCR_D700, charp, 0);
 
-static __u8 __initdata id_array[2*(MCA_MAX_SLOT_NR + 1)] =
+static __u8 __devinitdata id_array[2*(MCA_MAX_SLOT_NR + 1)] =
        { [0 ... 2*(MCA_MAX_SLOT_NR + 1)-1] = 7 };
 
 #ifdef MODULE
@@ -173,7 +173,7 @@ struct NCR_D700_private {
        char                    pad;
 };
 
-static int 
+static int __devinit
 NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq,
                   int slot, u32 region, int differential)
 {
@@ -243,7 +243,7 @@ NCR_D700_intr(int irq, void *data, struct pt_regs *regs)
  * essentially connectecd to the MCA bus independently, it is easier
  * to set them up as two separate host adapters, rather than one
  * adapter with two channels */
-static int
+static int __devinit
 NCR_D700_probe(struct device *dev)
 {
        struct NCR_D700_private *p;
@@ -329,7 +329,7 @@ NCR_D700_probe(struct device *dev)
        for (i = 0; i < 2; i++) {
                int err;
 
-               if ((err = NCR_D700_probe_one(p, i, slot, irq,
+               if ((err = NCR_D700_probe_one(p, i, irq, slot,
                                              offset_addr + (0x80 * i),
                                              differential)) != 0)
                        printk("D700: SIOP%d: probe failed, error = %d\n",
@@ -349,7 +349,7 @@ NCR_D700_probe(struct device *dev)
        return 0;
 }
 
-static void
+static void __devexit
 NCR_D700_remove_one(struct Scsi_Host *host)
 {
        scsi_remove_host(host);
@@ -359,7 +359,7 @@ NCR_D700_remove_one(struct Scsi_Host *host)
        release_region(host->base, 64);
 }
 
-static int
+static int __devexit
 NCR_D700_remove(struct device *dev)
 {
        struct NCR_D700_private *p = dev_get_drvdata(dev);
@@ -380,7 +380,7 @@ static struct mca_driver NCR_D700_driver = {
                .name           = "NCR_D700",
                .bus            = &mca_bus_type,
                .probe          = NCR_D700_probe,
-               .remove         = NCR_D700_remove,
+               .remove         = __devexit_p(NCR_D700_remove),
        },
 };
 
index 36e63f8..f974869 100644 (file)
@@ -551,6 +551,11 @@ struct aha152x_hostdata {
 struct aha152x_scdata {
        Scsi_Cmnd *next;        /* next sc in queue */
        struct semaphore *sem;  /* semaphore to block on */
+       unsigned char cmd_len;
+       unsigned char cmnd[MAX_COMMAND_SIZE];
+       unsigned short use_sg;
+       unsigned request_bufflen;
+       void *request_buffer;
 };
 
 
@@ -1006,11 +1011,20 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int p
                        return FAILED;
                }
        } else {
+               struct aha152x_scdata *sc;
+
                SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC);
                if(SCpnt->host_scribble==0) {
                        printk(ERR_LEAD "allocation failed\n", CMDINFO(SCpnt));
                        return FAILED;
                }
+
+               sc = SCDATA(SCpnt);
+               memcpy(sc->cmnd, SCpnt->cmnd, sizeof(sc->cmnd));
+               sc->request_buffer  = SCpnt->request_buffer;
+               sc->request_bufflen = SCpnt->request_bufflen;
+               sc->use_sg          = SCpnt->use_sg;
+               sc->cmd_len         = SCpnt->cmd_len;
        }
 
        SCNEXT(SCpnt)           = NULL;
@@ -1165,6 +1179,10 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
        DECLARE_MUTEX_LOCKED(sem);
        struct timer_list timer;
        int ret, issued, disconnected;
+       unsigned char old_cmd_len = SCpnt->cmd_len;
+       unsigned short old_use_sg = SCpnt->use_sg;
+       void *old_buffer = SCpnt->request_buffer;
+       unsigned old_bufflen = SCpnt->request_bufflen;
        unsigned long flags;
 
 #if defined(AHA152X_DEBUG)
@@ -1198,11 +1216,11 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
        add_timer(&timer);
        down(&sem);
        del_timer(&timer);
-       
-       SCpnt->cmd_len         = SCpnt->old_cmd_len;
-       SCpnt->use_sg          = SCpnt->old_use_sg;
-       SCpnt->request_buffer  = SCpnt->buffer;
-               SCpnt->request_bufflen = SCpnt->bufflen;
+
+       SCpnt->cmd_len         = old_cmd_len;
+       SCpnt->use_sg          = old_use_sg;
+       SCpnt->request_buffer  = old_buffer;
+               SCpnt->request_bufflen = old_bufflen;
 
        DO_LOCK(flags);
 
@@ -1565,6 +1583,9 @@ static void busfree_run(struct Scsi_Host *shpnt)
 #endif
 
                if(DONE_SC->SCp.phase & check_condition) {
+                       struct scsi_cmnd *cmd = HOSTDATA(shpnt)->done_SC;
+                       struct aha152x_scdata *sc = SCDATA(cmd);
+
 #if 0
                        if(HOSTDATA(shpnt)->debug & debug_eh) {
                                printk(ERR_LEAD "received sense: ", CMDINFO(DONE_SC));
@@ -1573,13 +1594,13 @@ static void busfree_run(struct Scsi_Host *shpnt)
 #endif
 
                        /* restore old command */
-                       memcpy((void *) DONE_SC->cmnd, (void *) DONE_SC->data_cmnd, sizeof(DONE_SC->data_cmnd));
-                       DONE_SC->request_buffer  = DONE_SC->buffer;
-                       DONE_SC->request_bufflen = DONE_SC->bufflen;
-                       DONE_SC->use_sg          = DONE_SC->old_use_sg;
-                       DONE_SC->cmd_len         = DONE_SC->old_cmd_len;
+                       memcpy(cmd->cmnd, sc->cmnd, sizeof(sc->cmnd));
+                       cmd->request_buffer  = sc->request_buffer;
+                       cmd->request_bufflen = sc->request_bufflen;
+                       cmd->use_sg          = sc->use_sg;
+                       cmd->cmd_len         = sc->cmd_len;
 
-                       DONE_SC->SCp.Status = 0x02;
+                       cmd->SCp.Status = 0x02;
 
                        HOSTDATA(shpnt)->commands--;
                        if (!HOSTDATA(shpnt)->commands)
index a1e8ca7..653818d 100644 (file)
@@ -7289,7 +7289,7 @@ ahd_reset_cmds_pending(struct ahd_softc *ahd)
        ahd->flags &= ~AHD_UPDATE_PEND_CMDS;
 }
 
-void
+static void
 ahd_done_with_status(struct ahd_softc *ahd, struct scb *scb, uint32_t status)
 {
        cam_status ostat;
index b244c71..998999c 100644 (file)
@@ -243,25 +243,6 @@ ahd_print_path(struct ahd_softc *ahd, struct scb *scb)
 static uint32_t aic79xx_no_reset;
 
 /*
- * Certain PCI motherboards will scan PCI devices from highest to lowest,
- * others scan from lowest to highest, and they tend to do all kinds of
- * strange things when they come into contact with PCI bridge chips.  The
- * net result of all this is that the PCI card that is actually used to boot
- * the machine is very hard to detect.  Most motherboards go from lowest
- * PCI slot number to highest, and the first SCSI controller found is the
- * one you boot from.  The only exceptions to this are when a controller
- * has its BIOS disabled.  So, we by default sort all of our SCSI controllers
- * from lowest PCI slot number to highest PCI slot number.  We also force
- * all controllers with their BIOS disabled to the end of the list.  This
- * works on *almost* all computers.  Where it doesn't work, we have this
- * option.  Setting this option to non-0 will reverse the order of the sort
- * to highest first, then lowest, but will still leave cards with their BIOS
- * disabled at the very end.  That should fix everyone up unless there are
- * really strange cirumstances.
- */
-static uint32_t aic79xx_reverse_scan;
-
-/*
  * Should we force EXTENDED translation on a controller.
  *     0 == Use whatever is in the SEEPROM or default to off
  *     1 == Use whatever is in the SEEPROM or default to on
@@ -350,7 +331,6 @@ MODULE_PARM_DESC(aic79xx,
 "                              periodically to prevent tag starvation.\n"
 "                              This may be required by some older disk\n"
 "                              or drives/RAID arrays.\n"
-"      reverse_scan            Sort PCI devices highest Bus/Slot to lowest\n"
 "      tag_info:<tag_str>      Set per-target tag depth\n"
 "      global_tag_depth:<int>  Global tag depth for all targets on all buses\n"
 "      slewrate:<slewrate_list>Set the signal slew rate (0-15).\n"
@@ -1031,7 +1011,6 @@ aic79xx_setup(char *s)
 #ifdef AHD_DEBUG
                { "debug", &ahd_debug },
 #endif
-               { "reverse_scan", &aic79xx_reverse_scan },
                { "periodic_otag", &aic79xx_periodic_otag },
                { "pci_parity", &aic79xx_pci_parity },
                { "seltime", &aic79xx_seltime },
index debf3e2..aa4be8a 100644 (file)
@@ -353,7 +353,6 @@ MODULE_PARM_DESC(aic7xxx,
 "                              periodically to prevent tag starvation.\n"
 "                              This may be required by some older disk\n"
 "                              drives or RAID arrays.\n"
-"      reverse_scan            Sort PCI devices highest Bus/Slot to lowest\n"
 "      tag_info:<tag_str>      Set per-target tag depth\n"
 "      global_tag_depth:<int>  Global tag depth for every target\n"
 "                              on every bus\n"
index 3e1053f..4cf7afc 100644 (file)
@@ -2427,7 +2427,7 @@ int fas216_eh_abort(Scsi_Cmnd *SCpnt)
        info->stats.aborts += 1;
 
        printk(KERN_WARNING "scsi%d: abort command ", info->host->host_no);
-       __scsi_print_command(SCpnt->data_cmnd);
+       __scsi_print_command(SCpnt->cmnd);
 
        print_debug_list();
        fas216_dumpstate(info);
index 94b1261..19745a3 100644 (file)
@@ -105,9 +105,6 @@ enum {
        PIIX_FLAG_SCR           = (1 << 26), /* SCR available */
        PIIX_FLAG_AHCI          = (1 << 27), /* AHCI possible */
        PIIX_FLAG_CHECKINTR     = (1 << 28), /* make sure PCI INTx enabled */
-       PIIX_FLAG_COMBINED      = (1 << 29), /* combined mode possible */
-       /* ICH6/7 use different scheme for map value */
-       PIIX_FLAG_COMBINED_ICH6 = PIIX_FLAG_COMBINED | (1 << 30),
 
        /* combined mode.  if set, PATA is channel 0.
         * if clear, PATA is channel 1.
@@ -126,6 +123,7 @@ enum {
        ich6_sata               = 4,
        ich6_sata_ahci          = 5,
        ich6m_sata_ahci         = 6,
+       ich8_sata_ahci          = 7,
 
        /* constants for mapping table */
        P0                      = 0,  /* port 0 */
@@ -141,11 +139,19 @@ enum {
 
 struct piix_map_db {
        const u32 mask;
+       const u16 port_enable;
+       const int present_shift;
        const int map[][4];
 };
 
+struct piix_host_priv {
+       const int *map;
+       const struct piix_map_db *map_db;
+};
+
 static int piix_init_one (struct pci_dev *pdev,
                                    const struct pci_device_id *ent);
+static void piix_host_stop(struct ata_host_set *host_set);
 static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev);
 static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
 static void piix_pata_error_handler(struct ata_port *ap);
@@ -186,11 +192,11 @@ static const struct pci_device_id piix_pci_tbl[] = {
        /* Enterprise Southbridge 2 (where's the datasheet?) */
        { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
        /* SATA Controller 1 IDE (ICH8, no datasheet yet) */
-       { 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+       { 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
        /* SATA Controller 2 IDE (ICH8, ditto) */
-       { 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+       { 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
        /* Mobile SATA Controller IDE (ICH8M, ditto) */
-       { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
+       { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
 
        { }     /* terminate list */
 };
@@ -254,7 +260,7 @@ static const struct ata_port_operations piix_pata_ops = {
 
        .port_start             = ata_port_start,
        .port_stop              = ata_port_stop,
-       .host_stop              = ata_host_stop,
+       .host_stop              = piix_host_stop,
 };
 
 static const struct ata_port_operations piix_sata_ops = {
@@ -284,11 +290,13 @@ static const struct ata_port_operations piix_sata_ops = {
 
        .port_start             = ata_port_start,
        .port_stop              = ata_port_stop,
-       .host_stop              = ata_host_stop,
+       .host_stop              = piix_host_stop,
 };
 
-static struct piix_map_db ich5_map_db = {
+static const struct piix_map_db ich5_map_db = {
        .mask = 0x7,
+       .port_enable = 0x3,
+       .present_shift = 4,
        .map = {
                /* PM   PS   SM   SS       MAP  */
                {  P0,  NA,  P1,  NA }, /* 000b */
@@ -302,8 +310,10 @@ static struct piix_map_db ich5_map_db = {
        },
 };
 
-static struct piix_map_db ich6_map_db = {
+static const struct piix_map_db ich6_map_db = {
        .mask = 0x3,
+       .port_enable = 0xf,
+       .present_shift = 4,
        .map = {
                /* PM   PS   SM   SS       MAP */
                {  P0,  P2,  P1,  P3 }, /* 00b */
@@ -313,8 +323,10 @@ static struct piix_map_db ich6_map_db = {
        },
 };
 
-static struct piix_map_db ich6m_map_db = {
+static const struct piix_map_db ich6m_map_db = {
        .mask = 0x3,
+       .port_enable = 0x5,
+       .present_shift = 4,
        .map = {
                /* PM   PS   SM   SS       MAP */
                {  P0,  P2,  RV,  RV }, /* 00b */
@@ -324,6 +336,28 @@ static struct piix_map_db ich6m_map_db = {
        },
 };
 
+static const struct piix_map_db ich8_map_db = {
+       .mask = 0x3,
+       .port_enable = 0x3,
+       .present_shift = 8,
+       .map = {
+               /* PM   PS   SM   SS       MAP */
+               {  P0,  NA,  P1,  NA }, /* 00b (hardwired) */
+               {  RV,  RV,  RV,  RV },
+               {  RV,  RV,  RV,  RV }, /* 10b (never) */
+               {  RV,  RV,  RV,  RV },
+       },
+};
+
+static const struct piix_map_db *piix_map_db_table[] = {
+       [ich5_sata]             = &ich5_map_db,
+       [esb_sata]              = &ich5_map_db,
+       [ich6_sata]             = &ich6_map_db,
+       [ich6_sata_ahci]        = &ich6_map_db,
+       [ich6m_sata_ahci]       = &ich6m_map_db,
+       [ich8_sata_ahci]        = &ich8_map_db,
+};
+
 static struct ata_port_info piix_port_info[] = {
        /* piix4_pata */
        {
@@ -356,63 +390,69 @@ static struct ata_port_info piix_port_info[] = {
        /* ich5_sata */
        {
                .sht            = &piix_sht,
-               .host_flags     = ATA_FLAG_SATA | PIIX_FLAG_COMBINED |
-                                 PIIX_FLAG_CHECKINTR,
+               .host_flags     = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &piix_sata_ops,
-               .private_data   = &ich5_map_db,
        },
 
        /* i6300esb_sata */
        {
                .sht            = &piix_sht,
-               .host_flags     = ATA_FLAG_SATA | PIIX_FLAG_COMBINED |
+               .host_flags     = ATA_FLAG_SATA |
                                  PIIX_FLAG_CHECKINTR | PIIX_FLAG_IGNORE_PCS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &piix_sata_ops,
-               .private_data   = &ich5_map_db,
        },
 
        /* ich6_sata */
        {
                .sht            = &piix_sht,
-               .host_flags     = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
+               .host_flags     = ATA_FLAG_SATA |
                                  PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &piix_sata_ops,
-               .private_data   = &ich6_map_db,
        },
 
        /* ich6_sata_ahci */
        {
                .sht            = &piix_sht,
-               .host_flags     = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
+               .host_flags     = ATA_FLAG_SATA |
                                  PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
                                  PIIX_FLAG_AHCI,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &piix_sata_ops,
-               .private_data   = &ich6_map_db,
        },
 
        /* ich6m_sata_ahci */
        {
                .sht            = &piix_sht,
-               .host_flags     = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 |
+               .host_flags     = ATA_FLAG_SATA |
+                                 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
+                                 PIIX_FLAG_AHCI,
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .udma_mask      = 0x7f, /* udma0-6 */
+               .port_ops       = &piix_sata_ops,
+       },
+
+       /* ich8_sata_ahci */
+       {
+               .sht            = &piix_sht,
+               .host_flags     = ATA_FLAG_SATA |
                                  PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
                                  PIIX_FLAG_AHCI,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &piix_sata_ops,
-               .private_data   = &ich6m_map_db,
        },
 };
 
@@ -508,46 +548,29 @@ static void piix_pata_error_handler(struct ata_port *ap)
 static int piix_sata_prereset(struct ata_port *ap)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
-       const unsigned int *map = ap->host_set->private_data;
+       struct piix_host_priv *hpriv = ap->host_set->private_data;
+       const unsigned int *map = hpriv->map;
        int base = 2 * ap->hard_port_no;
-       unsigned int present_mask = 0;
+       unsigned int present = 0;
        int port, i;
-       u8 pcs;
+       u16 pcs;
 
-       pci_read_config_byte(pdev, ICH5_PCS, &pcs);
+       pci_read_config_word(pdev, ICH5_PCS, &pcs);
        DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base);
 
-       /* enable all ports on this ap and wait for them to settle */
-       for (i = 0; i < 2; i++) {
-               port = map[base + i];
-               if (port >= 0)
-                       pcs |= 1 << port;
-       }
-
-       pci_write_config_byte(pdev, ICH5_PCS, pcs);
-       msleep(100);
-
-       /* let's see which devices are present */
-       pci_read_config_byte(pdev, ICH5_PCS, &pcs);
-
        for (i = 0; i < 2; i++) {
                port = map[base + i];
                if (port < 0)
                        continue;
-               if (ap->flags & PIIX_FLAG_IGNORE_PCS || pcs & 1 << (4 + port))
-                       present_mask |= 1 << i;
-               else
-                       pcs &= ~(1 << port);
+               if ((ap->flags & PIIX_FLAG_IGNORE_PCS) ||
+                   (pcs & 1 << (hpriv->map_db->present_shift + port)))
+                       present = 1;
        }
 
-       /* disable offline ports on non-AHCI controllers */
-       if (!(ap->flags & PIIX_FLAG_AHCI))
-               pci_write_config_byte(pdev, ICH5_PCS, pcs);
-
        DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n",
                ap->id, pcs, present_mask);
 
-       if (!present_mask) {
+       if (!present) {
                ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n");
                ap->eh_context.i.action &= ~ATA_EH_RESET_MASK;
                return 0;
@@ -761,10 +784,27 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
        return no_piix_dma;
 }
 
+static void __devinit piix_init_pcs(struct pci_dev *pdev,
+                                   const struct piix_map_db *map_db)
+{
+       u16 pcs, new_pcs;
+
+       pci_read_config_word(pdev, ICH5_PCS, &pcs);
+
+       new_pcs = pcs | map_db->port_enable;
+
+       if (new_pcs != pcs) {
+               DPRINTK("updating PCS from 0x%x to 0x%x\n", pcs, new_pcs);
+               pci_write_config_word(pdev, ICH5_PCS, new_pcs);
+               msleep(150);
+       }
+}
+
 static void __devinit piix_init_sata_map(struct pci_dev *pdev,
-                                        struct ata_port_info *pinfo)
+                                        struct ata_port_info *pinfo,
+                                        const struct piix_map_db *map_db)
 {
-       struct piix_map_db *map_db = pinfo[0].private_data;
+       struct piix_host_priv *hpriv = pinfo[0].private_data;
        const unsigned int *map;
        int i, invalid_map = 0;
        u8 map_value;
@@ -805,8 +845,8 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev,
                dev_printk(KERN_ERR, &pdev->dev,
                           "invalid MAP value %u\n", map_value);
 
-       pinfo[0].private_data = (void *)map;
-       pinfo[1].private_data = (void *)map;
+       hpriv->map = map;
+       hpriv->map_db = map_db;
 }
 
 /**
@@ -829,6 +869,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        static int printed_version;
        struct ata_port_info port_info[2];
        struct ata_port_info *ppinfo[2] = { &port_info[0], &port_info[1] };
+       struct piix_host_priv *hpriv;
        unsigned long host_flags;
 
        if (!printed_version++)
@@ -839,8 +880,14 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (!in_module_init)
                return -ENODEV;
 
+       hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL);
+       if (!hpriv)
+               return -ENOMEM;
+
        port_info[0] = piix_port_info[ent->driver_data];
        port_info[1] = piix_port_info[ent->driver_data];
+       port_info[0].private_data = hpriv;
+       port_info[1].private_data = hpriv;
 
        host_flags = port_info[0].host_flags;
 
@@ -855,8 +902,11 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 
        /* Initialize SATA map */
-       if (host_flags & ATA_FLAG_SATA)
-               piix_init_sata_map(pdev, port_info);
+       if (host_flags & ATA_FLAG_SATA) {
+               piix_init_sata_map(pdev, port_info,
+                                  piix_map_db_table[ent->driver_data]);
+               piix_init_pcs(pdev, piix_map_db_table[ent->driver_data]);
+       }
 
        /* On ICH5, some BIOSen disable the interrupt using the
         * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3.
@@ -879,6 +929,13 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        return ata_pci_init_one(pdev, ppinfo, 2);
 }
 
+static void piix_host_stop(struct ata_host_set *host_set)
+{
+       if (host_set->next == NULL)
+               kfree(host_set->private_data);
+       ata_host_stop(host_set);
+}
+
 static int __init piix_init(void)
 {
        int rc;
index 007a14e..e397129 100644 (file)
@@ -507,7 +507,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd *cmd)
      */
 
     if (cmd->use_sg) {
-       cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
+       cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
        cmd->SCp.buffers_residual = cmd->use_sg - 1;
        cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page)+
                       cmd->SCp.buffer->offset;
index dddd2ac..61f6024 100644 (file)
@@ -5,6 +5,7 @@
  * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002)
  *   by D. Gilbert and aeb (20020609)
  * Additions for SPC-3 T10/1416-D Rev 21 22 Sept 2004, D. Gilbert 20041025
+ * Update to SPC-4 T10/1713-D Rev 5a, 14 June 2006, D. Gilbert 20060702
  */
 
 #include <linux/blkdev.h>
@@ -36,55 +37,56 @@ static const char * cdb_byte0_names[] = {
 /* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense",
 /* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL,
            "Reasssign Blocks",
-/* 08-0d */ "Read (6)", NULL, "Write (6)", "Seek (6)", NULL, NULL,
+/* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL,
 /* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry",  
-/* 13-16 */ "Verify (6)", "Recover Buffered Data", "Mode Select (6)",
-           "Reserve (6)",
-/* 17-1a */ "Release (6)", "Copy", "Erase", "Mode Sense (6)", 
+/* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)",
+           "Reserve(6)",
+/* 17-1a */ "Release(6)", "Copy", "Erase", "Mode Sense(6)",
 /* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic", 
 /* 1e-1f */ "Prevent/Allow Medium Removal", NULL,
 /* 20-22 */  NULL, NULL, NULL,
 /* 23-28 */ "Read Format Capacities", "Set Window",
-           "Read Capacity (10)", NULL, NULL, "Read (10)", 
-/* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase (10)", 
-            "Read updated block", 
-/* 2e-31 */ "Write Verify (10)", "Verify (10)", "Search High", "Search Equal", 
+           "Read Capacity(10)", NULL, NULL, "Read(10)",
+/* 29-2d */ "Read Generation", "Write(10)", "Seek(10)", "Erase(10)",
+            "Read updated block",
+/* 2e-31 */ "Write Verify(10)", "Verify(10)", "Search High", "Search Equal",
 /* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position", 
-/* 35-37 */ "Synchronize Cache (10)", "Lock/Unlock Cache (10)",
+/* 35-37 */ "Synchronize Cache(10)", "Lock/Unlock Cache(10)",
            "Read Defect Data(10)", 
 /* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", 
             "Read Buffer", 
-/* 3d-3f */ "Update Block", "Read Long (10)",  "Write Long (10)",
-/* 40-41 */ "Change Definition", "Write Same (10)",
+/* 3d-3f */ "Update Block", "Read Long(10)",  "Write Long(10)",
+/* 40-41 */ "Change Definition", "Write Same(10)",
 /* 42-48 */ "Read sub-channel", "Read TOC/PMA/ATIP", "Read density support",
-            "Play audio (10)", "Get configuration", "Play audio msf",
+            "Play audio(10)", "Get configuration", "Play audio msf",
             "Play audio track/index",
-/* 49-4f */ "Play track relative (10)", "Get event status notification",
+/* 49-4f */ "Play track relative(10)", "Get event status notification",
             "Pause/resume", "Log Select", "Log Sense", "Stop play/scan",
             NULL,
 /* 50-55 */ "Xdwrite", "Xpwrite, Read disk info", "Xdread, Read track info",
-            "Reserve track", "Send OPC info", "Mode Select (10)",
-/* 56-5b */ "Reserve (10)", "Release (10)", "Repair track", "Read master cue",
-            "Mode Sense (10)", "Close track/session",
+            "Reserve track", "Send OPC info", "Mode Select(10)",
+/* 56-5b */ "Reserve(10)", "Release(10)", "Repair track", "Read master cue",
+            "Mode Sense(10)", "Close track/session",
 /* 5c-5f */ "Read buffer capacity", "Send cue sheet", "Persistent reserve in",
             "Persistent reserve out",
 /* 60-67 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 /* 68-6f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 /* 70-77 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 /* 78-7f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Variable length",
-/* 80-84 */ "Xdwrite (16)", "Rebuild (16)", "Regenerate (16)", "Extended copy",
+/* 80-84 */ "Xdwrite(16)", "Rebuild(16)", "Regenerate(16)", "Extended copy",
             "Receive copy results",
-/* 85-89 */ "Memory Export In (16)", "Access control in", "Access control out",
-            "Read (16)", "Memory Export Out (16)",
-/* 8a-8f */ "Write (16)", NULL, "Read attributes", "Write attributes",
-            "Write and verify (16)", "Verify (16)",
-/* 90-94 */ "Pre-fetch (16)", "Synchronize cache (16)",
-            "Lock/unlock cache (16)", "Write same (16)", NULL,
+/* 85-89 */ "ATA command pass through(16)", "Access control in",
+           "Access control out", "Read(16)", "Memory Export Out(16)",
+/* 8a-8f */ "Write(16)", NULL, "Read attributes", "Write attributes",
+            "Write and verify(16)", "Verify(16)",
+/* 90-94 */ "Pre-fetch(16)", "Synchronize cache(16)",
+            "Lock/unlock cache(16)", "Write same(16)", NULL,
 /* 95-99 */ NULL, NULL, NULL, NULL, NULL,
-/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in (16)",
-            "Service action out (16)",
-/* a0-a5 */ "Report luns", "Blank", "Send event", "Maintenance in",
-            "Maintenance out", "Move medium/play audio(12)",
+/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in(16)",
+            "Service action out(16)",
+/* a0-a5 */ "Report luns", "ATA command pass through(12)/Blank",
+            "Security protocol in", "Maintenance in", "Maintenance out",
+           "Move medium/play audio(12)",
 /* a6-a9 */ "Exchange medium", "Move medium attached", "Read(12)",
             "Play track relative(12)",
 /* aa-ae */ "Write(12)", NULL, "Erase(12), Get Performance",
@@ -92,12 +94,12 @@ static const char * cdb_byte0_names[] = {
 /* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)",
 /* b2-b4 */ "Search data low(12)", "Set limits(12)",
             "Read element status attached",
-/* b5-b6 */ "Request volume element address", "Send volume tag, set streaming",
+/* b5-b6 */ "Security protocol out", "Send volume tag, set streaming",
 /* b7-b9 */ "Read defect data(12)", "Read element status", "Read CD msf",
 /* ba-bc */ "Redundancy group (in), Scan",
-            "Redundancy group (out), Set cd-rom speed", "Spare in, Play cd",
-/* bd-bf */ "Spare out, Mechanism status", "Volume set in, Read cd",
-            "Volume set out, Send DVD structure",
+            "Redundancy group (out), Set cd-rom speed", "Spare (in), Play cd",
+/* bd-bf */ "Spare (out), Mechanism status", "Volume set (in), Read cd",
+            "Volume set (out), Send DVD structure",
 };
 
 struct value_name_pair {
@@ -112,6 +114,7 @@ static const struct value_name_pair maint_in_arr[] = {
        {0xc, "Report supported operation codes"},
        {0xd, "Report supported task management functions"},
        {0xe, "Report priority"},
+       {0xf, "Report timestamp"},
 };
 #define MAINT_IN_SZ ARRAY_SIZE(maint_in_arr)
 
@@ -120,6 +123,7 @@ static const struct value_name_pair maint_out_arr[] = {
        {0xa, "Set target port groups"},
        {0xb, "Change aliases"},
        {0xe, "Set priority"},
+       {0xe, "Set timestamp"},
 };
 #define MAINT_OUT_SZ ARRAY_SIZE(maint_out_arr)
 
@@ -427,6 +431,7 @@ static struct error_info additional[] =
        {0x001A, "Rewind operation in progress"},
        {0x001B, "Set capacity operation in progress"},
        {0x001C, "Verify operation in progress"},
+       {0x001D, "ATA pass through information available"},
 
        {0x0100, "No index/sector signal"},
 
@@ -438,7 +443,7 @@ static struct error_info additional[] =
 
        {0x0400, "Logical unit not ready, cause not reportable"},
        {0x0401, "Logical unit is in process of becoming ready"},
-       {0x0402, "Logical unit not ready, initializing cmd. required"},
+       {0x0402, "Logical unit not ready, initializing command required"},
        {0x0403, "Logical unit not ready, manual intervention required"},
        {0x0404, "Logical unit not ready, format in progress"},
        {0x0405, "Logical unit not ready, rebuild in progress"},
@@ -478,6 +483,9 @@ static struct error_info additional[] =
        {0x0B00, "Warning"},
        {0x0B01, "Warning - specified temperature exceeded"},
        {0x0B02, "Warning - enclosure degraded"},
+       {0x0B03, "Warning - background self-test failed"},
+       {0x0B04, "Warning - background pre-scan detected medium error"},
+       {0x0B05, "Warning - background medium scan detected medium error"},
 
        {0x0C00, "Write error"},
        {0x0C01, "Write error - recovered with auto reallocation"},
@@ -493,6 +501,7 @@ static struct error_info additional[] =
        {0x0C0B, "Auxiliary memory write error"},
        {0x0C0C, "Write error - unexpected unsolicited data"},
        {0x0C0D, "Write error - not enough unsolicited data"},
+       {0x0C0F, "Defects in error window"},
 
        {0x0D00, "Error detected by third party temporary initiator"},
        {0x0D01, "Third party device failure"},
@@ -504,11 +513,12 @@ static struct error_info additional[] =
        {0x0E00, "Invalid information unit"},
        {0x0E01, "Information unit too short"},
        {0x0E02, "Information unit too long"},
+       {0x0E03, "Invalid field in command information unit"},
 
        {0x1000, "Id CRC or ECC error"},
-       {0x1001, "Data block guard check failed"},
-       {0x1002, "Data block application tag check failed"},
-       {0x1003, "Data block reference tag check failed"},
+       {0x1001, "Logical block guard check failed"},
+       {0x1002, "Logical block application tag check failed"},
+       {0x1003, "Logical block reference tag check failed"},
 
        {0x1100, "Unrecovered read error"},
        {0x1101, "Read retries exhausted"},
@@ -530,6 +540,7 @@ static struct error_info additional[] =
        {0x1111, "Read error - loss of streaming"},
        {0x1112, "Auxiliary memory read error"},
        {0x1113, "Read error - failed retransmission request"},
+       {0x1114, "Read error - lba marked bad by application client"},
 
        {0x1200, "Address mark not found for id field"},
 
@@ -610,11 +621,14 @@ static struct error_info additional[] =
        {0x2100, "Logical block address out of range"},
        {0x2101, "Invalid element address"},
        {0x2102, "Invalid address for write"},
+       {0x2103, "Invalid write crossing layer jump"},
 
        {0x2200, "Illegal function (use 20 00, 24 00, or 26 00)"},
 
        {0x2400, "Invalid field in cdb"},
        {0x2401, "CDB decryption error"},
+       {0x2402, "Obsolete"},
+       {0x2403, "Obsolete"},
        {0x2404, "Security audit value frozen"},
        {0x2405, "Security working key frozen"},
        {0x2406, "Nonce not unique"},
@@ -637,7 +651,10 @@ static struct error_info additional[] =
        {0x260C, "Invalid operation for copy source or destination"},
        {0x260D, "Copy segment granularity violation"},
        {0x260E, "Invalid parameter while port is enabled"},
-       {0x260F, "Invalid data-out buffer integrity"},
+       {0x260F, "Invalid data-out buffer integrity check value"},
+       {0x2610, "Data decryption key fail limit reached"},
+       {0x2611, "Incomplete key-associated data set"},
+       {0x2612, "Vendor specific key reference not found"},
 
        {0x2700, "Write protected"},
        {0x2701, "Hardware write protected"},
@@ -649,6 +666,7 @@ static struct error_info additional[] =
 
        {0x2800, "Not ready to ready change, medium may have changed"},
        {0x2801, "Import or export element accessed"},
+       {0x2802, "Format-layer may have changed"},
 
        {0x2900, "Power on, reset, or bus device reset occurred"},
        {0x2901, "Power on occurred"},
@@ -669,6 +687,11 @@ static struct error_info additional[] =
        {0x2A07, "Implicit asymmetric access state transition failed"},
        {0x2A08, "Priority changed"},
        {0x2A09, "Capacity data has changed"},
+       {0x2A10, "Timestamp changed"},
+       {0x2A11, "Data encryption parameters changed by another i_t nexus"},
+       {0x2A12, "Data encryption parameters changed by vendor specific "
+                "event"},
+       {0x2A13, "Data encryption key instance counter has changed"},
 
        {0x2B00, "Copy cannot execute since host cannot disconnect"},
 
@@ -690,6 +713,7 @@ static struct error_info additional[] =
        {0x2E00, "Insufficient time for operation"},
 
        {0x2F00, "Commands cleared by another initiator"},
+       {0x2F01, "Commands cleared by power loss notification"},
 
        {0x3000, "Incompatible medium installed"},
        {0x3001, "Cannot read medium - unknown format"},
@@ -702,7 +726,8 @@ static struct error_info additional[] =
        {0x3008, "Cannot write - application code mismatch"},
        {0x3009, "Current session not fixated for append"},
        {0x300A, "Cleaning request rejected"},
-       {0x300C, "WORM medium, overwrite attempted"},
+       {0x300C, "WORM medium - overwrite attempted"},
+       {0x300D, "WORM medium - integrity check"},
        {0x3010, "Medium not formatted"},
 
        {0x3100, "Medium format corrupted"},
@@ -790,6 +815,9 @@ static struct error_info additional[] =
        {0x3F0F, "Echo buffer overwritten"},
        {0x3F10, "Medium loadable"},
        {0x3F11, "Medium auxiliary memory accessible"},
+       {0x3F12, "iSCSI IP address added"},
+       {0x3F13, "iSCSI IP address removed"},
+       {0x3F14, "iSCSI IP address changed"},
 /*
  *     {0x40NN, "Ram failure"},
  *     {0x40NN, "Diagnostic failure on component nn"},
@@ -799,6 +827,7 @@ static struct error_info additional[] =
        {0x4300, "Message error"},
 
        {0x4400, "Internal target failure"},
+       {0x4471, "ATA device failed set features"},
 
        {0x4500, "Select or reselect failure"},
 
@@ -807,9 +836,10 @@ static struct error_info additional[] =
        {0x4700, "Scsi parity error"},
        {0x4701, "Data phase CRC error detected"},
        {0x4702, "Scsi parity error detected during st data phase"},
-       {0x4703, "Information unit CRC error detected"},
+       {0x4703, "Information unit iuCRC error detected"},
        {0x4704, "Asynchronous information protection error detected"},
        {0x4705, "Protocol service CRC error"},
+       {0x4706, "Phy test function in progress"},
        {0x477f, "Some commands cleared by iSCSI Protocol event"},
 
        {0x4800, "Initiator detected error message received"},
@@ -844,6 +874,8 @@ static struct error_info additional[] =
        {0x5300, "Media load or eject failed"},
        {0x5301, "Unload tape failure"},
        {0x5302, "Medium removal prevented"},
+       {0x5303, "Medium removal prevented by data transfer element"},
+       {0x5304, "Medium thread or unthread failure"},
 
        {0x5400, "Scsi to host system interface failure"},
 
@@ -855,6 +887,7 @@ static struct error_info additional[] =
        {0x5505, "Insufficient access control resources"},
        {0x5506, "Auxiliary memory out of space"},
        {0x5507, "Quota error"},
+       {0x5508, "Maximum number of supplemental decryption keys exceeded"},
 
        {0x5700, "Unable to recover table-of-contents"},
 
@@ -1004,6 +1037,7 @@ static struct error_info additional[] =
        {0x6708, "Assign failure occurred"},
        {0x6709, "Multiply assigned logical unit"},
        {0x670A, "Set target port groups command failed"},
+       {0x670B, "ATA device feature not enabled"},
 
        {0x6800, "Logical unit not configured"},
 
@@ -1030,6 +1064,8 @@ static struct error_info additional[] =
        {0x6F03, "Read of scrambled sector without authentication"},
        {0x6F04, "Media region code is mismatched to logical unit region"},
        {0x6F05, "Drive region must be permanent/region reset count error"},
+       {0x6F06, "Insufficient block count for binding nonce recording"},
+       {0x6F07, "Conflict in binding nonce recording"},
 /*
  *     {0x70NN, "Decompression exception short algorithm id of nn"},
  */
@@ -1041,6 +1077,8 @@ static struct error_info additional[] =
        {0x7203, "Session fixation error - incomplete track in session"},
        {0x7204, "Empty or partially written reserved track"},
        {0x7205, "No more track reservations allowed"},
+       {0x7206, "RMZ extension is not allowed"},
+       {0x7207, "No more test zone extensions are allowed"},
 
        {0x7300, "Cd control error"},
        {0x7301, "Power calibration area almost full"},
@@ -1049,6 +1087,18 @@ static struct error_info additional[] =
        {0x7304, "Program memory area update failure"},
        {0x7305, "Program memory area is full"},
        {0x7306, "RMA/PMA is almost full"},
+       {0x7310, "Current power calibration area almost full"},
+       {0x7311, "Current power calibration area is full"},
+       {0x7317, "RDZ is full"},
+
+       {0x7400, "Security error"},
+       {0x7401, "Unable to decrypt data"},
+       {0x7402, "Unencrypted data encountered while decrypting"},
+       {0x7403, "Incorrect data encryption key"},
+       {0x7404, "Cryptographic integrity validation failed"},
+       {0x7405, "Error decrypting data"},
+       {0x7471, "Logical unit access not authorized"},
+
        {0, NULL}
 };
 
index 10573c2..98bd227 100644 (file)
@@ -1397,7 +1397,7 @@ static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
                        sp->SCp.ptr = NULL;
                }
        } else {
-               sp->SCp.buffer = (struct scatterlist *) sp->buffer;
+               sp->SCp.buffer = (struct scatterlist *) sp->request_buffer;
                sp->SCp.buffers_residual = sbus_map_sg(esp->sdev,
                                                       sp->SCp.buffer,
                                                       sp->use_sg,
@@ -1410,7 +1410,7 @@ static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
 static void esp_release_dmabufs(struct esp *esp, struct scsi_cmnd *sp)
 {
        if (sp->use_sg) {
-               sbus_unmap_sg(esp->sdev, sp->buffer, sp->use_sg,
+               sbus_unmap_sg(esp->sdev, sp->request_buffer, sp->use_sg,
                              sp->sc_data_direction);
        } else if (sp->request_bufflen) {
                sbus_unmap_single(esp->sdev,
@@ -2754,18 +2754,15 @@ static int esp_do_data_finale(struct esp *esp)
  */
 static int esp_should_clear_sync(struct scsi_cmnd *sp)
 {
-       u8 cmd1 = sp->cmnd[0];
-       u8 cmd2 = sp->data_cmnd[0];
+       u8 cmd = sp->cmnd[0];
 
        /* These cases are for spinning up a disk and
         * waiting for that spinup to complete.
         */
-       if (cmd1 == START_STOP ||
-           cmd2 == START_STOP)
+       if (cmd == START_STOP)
                return 0;
 
-       if (cmd1 == TEST_UNIT_READY ||
-           cmd2 == TEST_UNIT_READY)
+       if (cmd == TEST_UNIT_READY)
                return 0;
 
        /* One more special case for SCSI tape drives,
@@ -2773,8 +2770,7 @@ static int esp_should_clear_sync(struct scsi_cmnd *sp)
         * completion of a rewind or tape load operation.
         */
        if (sp->device->type == TYPE_TAPE) {
-               if (cmd1 == MODE_SENSE ||
-                   cmd2 == MODE_SENSE)
+               if (cmd == MODE_SENSE)
                        return 0;
        }
 
index 7eed0b0..6aeb5f0 100644 (file)
@@ -81,7 +81,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
        int rc;
 
        single_host_data = hostdata;
-       rc = viopath_open(viopath_hostLp, viomajorsubtype_scsi, 0);
+       rc = viopath_open(viopath_hostLp, viomajorsubtype_scsi, max_requests);
        if (rc < 0) {
                printk("viopath_open failed with rc %d in open_event_path\n",
                       rc);
index 242b887..ed22b96 100644 (file)
@@ -238,6 +238,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
        if (rc == 2) {
                /* Adapter is good, but other end is not ready */
                printk(KERN_WARNING "ibmvscsi: Partner adapter not ready\n");
+               retrc = 0;
        } else if (rc != 0) {
                printk(KERN_WARNING "ibmvscsi: Error %d opening adapter\n", rc);
                goto reg_crq_failed;
index 3fd8a96..bfac444 100644 (file)
@@ -257,7 +257,7 @@ static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
 static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
 {
     int sz = sp->use_sg - 1;
-    struct scatterlist *sg = (struct scatterlist *)sp->buffer;
+    struct scatterlist *sg = (struct scatterlist *)sp->request_buffer;
                        
     while(sz >= 0) {
        vdma_free(sg[sz].dma_address);
index f81691f..d44f9aa 100644 (file)
 
 struct lpfc_sli2_slim;
 
-#define LPFC_MAX_TARGET         256    /* max targets supported */
-#define LPFC_MAX_DISC_THREADS  64      /* max outstanding discovery els req */
-#define LPFC_MAX_NS_RETRY       3      /* max NameServer retries */
 
+#define LPFC_MAX_TARGET                256     /* max number of targets supported */
+#define LPFC_MAX_DISC_THREADS  64      /* max outstanding discovery els
+                                          requests */
+#define LPFC_MAX_NS_RETRY      3       /* Number of retry attempts to contact
+                                          the NameServer  before giving up. */
 #define LPFC_DFT_HBA_Q_DEPTH   2048    /* max cmds per hba */
 #define LPFC_LC_HBA_Q_DEPTH    1024    /* max cmds per low cost hba */
 #define LPFC_LP101_HBA_Q_DEPTH 128     /* max cmds per low cost hba */
@@ -41,7 +43,6 @@ struct lpfc_sli2_slim;
                             (( (u64)(high)<<16 ) << 16)|( (u64)(low))))
 /* Provide maximum configuration definitions. */
 #define LPFC_DRVR_TIMEOUT      16      /* driver iocb timeout value in sec */
-#define MAX_FCP_TARGET         256     /* max num of FCP targets supported */
 #define FC_MAX_ADPTMSG         64
 
 #define MAX_HBAEVT     32
index b62a72d..5c68cdd 100644 (file)
@@ -219,9 +219,19 @@ lpfc_issue_lip(struct Scsi_Host *host)
                return -ENOMEM;
 
        memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
-       lpfc_init_link(phba, pmboxq, phba->cfg_topology, phba->cfg_link_speed);
+       pmboxq->mb.mbxCommand = MBX_DOWN_LINK;
+       pmboxq->mb.mbxOwner = OWN_HOST;
+
        mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
 
+       if ((mbxstatus == MBX_SUCCESS) && (pmboxq->mb.mbxStatus == 0)) {
+               memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
+               lpfc_init_link(phba, pmboxq, phba->cfg_topology,
+                              phba->cfg_link_speed);
+               mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq,
+                                                    phba->fc_ratov * 2);
+       }
+
        if (mbxstatus == MBX_TIMEOUT)
                pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
        else
@@ -233,51 +243,53 @@ lpfc_issue_lip(struct Scsi_Host *host)
        return 0;
 }
 
-static ssize_t
-lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf)
+static int
+lpfc_selective_reset(struct lpfc_hba *phba)
 {
-       struct Scsi_Host *host = class_to_shost(cdev);
-       struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
-       return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
+       struct completion online_compl;
+       int status = 0;
+
+       init_completion(&online_compl);
+       lpfc_workq_post_event(phba, &status, &online_compl,
+                             LPFC_EVT_OFFLINE);
+       wait_for_completion(&online_compl);
+
+       if (status != 0)
+               return -EIO;
+
+       init_completion(&online_compl);
+       lpfc_workq_post_event(phba, &status, &online_compl,
+                             LPFC_EVT_ONLINE);
+       wait_for_completion(&online_compl);
+
+       if (status != 0)
+               return -EIO;
+
+       return 0;
 }
 
 static ssize_t
-lpfc_board_online_show(struct class_device *cdev, char *buf)
+lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count)
 {
        struct Scsi_Host *host = class_to_shost(cdev);
        struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+       int status = -EINVAL;
 
-       if (phba->fc_flag & FC_OFFLINE_MODE)
-               return snprintf(buf, PAGE_SIZE, "0\n");
+       if (strncmp(buf, "selective", sizeof("selective") - 1) == 0)
+               status = lpfc_selective_reset(phba);
+
+       if (status == 0)
+               return strlen(buf);
        else
-               return snprintf(buf, PAGE_SIZE, "1\n");
+               return status;
 }
 
 static ssize_t
-lpfc_board_online_store(struct class_device *cdev, const char *buf,
-                                                               size_t count)
+lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf)
 {
        struct Scsi_Host *host = class_to_shost(cdev);
        struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
-       struct completion online_compl;
-       int val=0, status=0;
-
-       if (sscanf(buf, "%d", &val) != 1)
-               return -EINVAL;
-
-       init_completion(&online_compl);
-
-       if (val)
-               lpfc_workq_post_event(phba, &status, &online_compl,
-                                                       LPFC_EVT_ONLINE);
-       else
-               lpfc_workq_post_event(phba, &status, &online_compl,
-                                                       LPFC_EVT_OFFLINE);
-       wait_for_completion(&online_compl);
-       if (!status)
-               return strlen(buf);
-       else
-               return -EIO;
+       return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
 }
 
 static ssize_t
@@ -532,10 +544,9 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,
                         NULL);
 static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
                         NULL);
-static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
-                        lpfc_board_online_show, lpfc_board_online_store);
 static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
                         lpfc_board_mode_show, lpfc_board_mode_store);
+static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);
 
 static int lpfc_poll = 0;
 module_param(lpfc_poll, int, 0);
@@ -695,12 +706,12 @@ LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
                 "during discovery");
 
 /*
-# lpfc_max_luns: maximum number of LUNs per target driver will support
-# Value range is [1,32768]. Default value is 256.
-# NOTE: The SCSI layer will scan each target for this many luns
+# lpfc_max_luns: maximum allowed LUN.
+# Value range is [0,65535]. Default value is 255.
+# NOTE: The SCSI layer might probe all allowed LUN on some old targets.
 */
-LPFC_ATTR_R(max_luns, 256, 1, 32768,
-            "Maximum number of LUNs per target driver will support");
+LPFC_ATTR_R(max_luns, 255, 0, 65535,
+            "Maximum allowed LUN");
 
 /*
 # lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
@@ -739,8 +750,8 @@ struct class_device_attribute *lpfc_host_attrs[] = {
        &class_device_attr_lpfc_max_luns,
        &class_device_attr_nport_evt_cnt,
        &class_device_attr_management_version,
-       &class_device_attr_board_online,
        &class_device_attr_board_mode,
+       &class_device_attr_issue_reset,
        &class_device_attr_lpfc_poll,
        &class_device_attr_lpfc_poll_tmo,
        NULL,
index ee22173..517e9e4 100644 (file)
@@ -147,6 +147,7 @@ int lpfc_sli_hba_setup(struct lpfc_hba *);
 int lpfc_sli_hba_down(struct lpfc_hba *);
 int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
 int lpfc_sli_handle_mb_event(struct lpfc_hba *);
+int lpfc_sli_flush_mbox_queue(struct lpfc_hba *);
 int lpfc_sli_handle_slow_ring_event(struct lpfc_hba *,
                                    struct lpfc_sli_ring *, uint32_t);
 void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
index 4126fd8..b89f6cb 100644 (file)
@@ -648,33 +648,32 @@ lpfc_more_plogi(struct lpfc_hba * phba)
 }
 
 static struct lpfc_nodelist *
-lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
+lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp,
                         struct lpfc_nodelist *ndlp)
 {
        struct lpfc_nodelist *new_ndlp;
-       struct lpfc_dmabuf *pcmd, *prsp;
        uint32_t *lp;
        struct serv_parm *sp;
        uint8_t name[sizeof (struct lpfc_name)];
        uint32_t rc;
 
-       pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
-       prsp = (struct lpfc_dmabuf *) pcmd->list.next;
        lp = (uint32_t *) prsp->virt;
        sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
+       memset(name, 0, sizeof (struct lpfc_name));
 
        /* Now we to find out if the NPort we are logging into, matches the WWPN
         * we have for that ndlp. If not, we have some work to do.
         */
        new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName);
 
-       memset(name, 0, sizeof (struct lpfc_name));
-       rc =  memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name));
-       if (!rc || (new_ndlp == ndlp)) {
+       if (new_ndlp == ndlp)
                return ndlp;
-       }
 
        if (!new_ndlp) {
+               rc =
+                  memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name));
+               if (!rc)
+                       return ndlp;
                new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
                if (!new_ndlp)
                        return ndlp;
@@ -683,17 +682,21 @@ lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
        }
 
        lpfc_unreg_rpi(phba, new_ndlp);
-       new_ndlp->nlp_prev_state = ndlp->nlp_state;
        new_ndlp->nlp_DID = ndlp->nlp_DID;
-       new_ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
-       lpfc_nlp_list(phba, new_ndlp, NLP_PLOGI_LIST);
+       new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
+       new_ndlp->nlp_state = ndlp->nlp_state;
+       lpfc_nlp_list(phba, new_ndlp, ndlp->nlp_flag & NLP_LIST_MASK);
 
        /* Move this back to NPR list */
-       lpfc_unreg_rpi(phba, ndlp);
-       ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
-       ndlp->nlp_state = NLP_STE_NPR_NODE;
-       lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
-
+       if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) {
+               lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
+       }
+       else {
+               lpfc_unreg_rpi(phba, ndlp);
+               ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
+               ndlp->nlp_state = NLP_STE_NPR_NODE;
+               lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
+       }
        return new_ndlp;
 }
 
@@ -703,6 +706,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
 {
        IOCB_t *irsp;
        struct lpfc_nodelist *ndlp;
+       struct lpfc_dmabuf *prsp;
        int disc, rc, did, type;
 
 
@@ -769,7 +773,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                }
        } else {
                /* Good status, call state machine */
-               ndlp = lpfc_plogi_confirm_nport(phba, cmdiocb, ndlp);
+               prsp = list_entry(((struct lpfc_dmabuf *)
+                       cmdiocb->context2)->list.next,
+                       struct lpfc_dmabuf, list);
+               ndlp = lpfc_plogi_confirm_nport(phba, prsp, ndlp);
                rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb,
                                        NLP_EVT_CMPL_PLOGI);
        }
@@ -3282,10 +3289,9 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
                } else
                        lpfc_sli_release_iocbq(phba, piocb);
        }
-       if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) {
-               phba->els_tmofunc.expires = jiffies + HZ * timeout;
-               add_timer(&phba->els_tmofunc);
-       }
+       if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt)
+               mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout);
+
        spin_unlock_irq(phba->host->host_lock);
 }
 
@@ -3442,6 +3448,8 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) {
                        ndlp->nlp_type |= NLP_FABRIC;
                }
+               ndlp->nlp_state = NLP_STE_UNUSED_NODE;
+               lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
        }
 
        phba->fc_stat.elsRcvFrame++;
@@ -3463,13 +3471,14 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                        rjt_err = 1;
                        break;
                }
+               ndlp = lpfc_plogi_confirm_nport(phba, mp, ndlp);
                lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI);
                break;
        case ELS_CMD_FLOGI:
                phba->fc_stat.elsRcvFLOGI++;
                lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode);
                if (newnode) {
-                       mempool_free( ndlp, phba->nlp_mem_pool);
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                }
                break;
        case ELS_CMD_LOGO:
@@ -3492,7 +3501,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                phba->fc_stat.elsRcvRSCN++;
                lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode);
                if (newnode) {
-                       mempool_free( ndlp, phba->nlp_mem_pool);
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                }
                break;
        case ELS_CMD_ADISC:
@@ -3535,28 +3544,28 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                phba->fc_stat.elsRcvLIRR++;
                lpfc_els_rcv_lirr(phba, elsiocb, ndlp);
                if (newnode) {
-                       mempool_free( ndlp, phba->nlp_mem_pool);
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                }
                break;
        case ELS_CMD_RPS:
                phba->fc_stat.elsRcvRPS++;
                lpfc_els_rcv_rps(phba, elsiocb, ndlp);
                if (newnode) {
-                       mempool_free( ndlp, phba->nlp_mem_pool);
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                }
                break;
        case ELS_CMD_RPL:
                phba->fc_stat.elsRcvRPL++;
                lpfc_els_rcv_rpl(phba, elsiocb, ndlp);
                if (newnode) {
-                       mempool_free( ndlp, phba->nlp_mem_pool);
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                }
                break;
        case ELS_CMD_RNID:
                phba->fc_stat.elsRcvRNID++;
                lpfc_els_rcv_rnid(phba, elsiocb, ndlp);
                if (newnode) {
-                       mempool_free( ndlp, phba->nlp_mem_pool);
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                }
                break;
        default:
@@ -3568,7 +3577,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
                                "%d:0115 Unknown ELS command x%x received from "
                                "NPORT x%x\n", phba->brd_no, cmd, did);
                if (newnode) {
-                       mempool_free( ndlp, phba->nlp_mem_pool);
+                       lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
                }
                break;
        }
index adb0860..4d6cf99 100644 (file)
@@ -1084,7 +1084,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
                fc_remote_port_rolechg(rport, rport_ids.roles);
 
        if ((rport->scsi_target_id != -1) &&
-               (rport->scsi_target_id < MAX_FCP_TARGET)) {
+               (rport->scsi_target_id < LPFC_MAX_TARGET)) {
                ndlp->nlp_sid = rport->scsi_target_id;
        }
 
@@ -1313,7 +1313,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
                        if ((rport_add == mapped) &&
                            ((!nlp->rport) ||
                             (nlp->rport->scsi_target_id == -1) ||
-                            (nlp->rport->scsi_target_id >= MAX_FCP_TARGET))) {
+                            (nlp->rport->scsi_target_id >= LPFC_MAX_TARGET))) {
                                nlp->nlp_state = NLP_STE_UNMAPPED_NODE;
                                spin_lock_irq(phba->host->host_lock);
                                nlp->nlp_flag |= NLP_TGT_NO_SCSIID;
index 81755a3..ef47b82 100644 (file)
@@ -71,6 +71,7 @@ lpfc_config_port_prep(struct lpfc_hba * phba)
        uint16_t offset = 0;
        static char licensed[56] =
                    "key unlock for use with gnu public licensed code only\0";
+       static int init_key = 1;
 
        pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
        if (!pmb) {
@@ -82,10 +83,13 @@ lpfc_config_port_prep(struct lpfc_hba * phba)
        phba->hba_state = LPFC_INIT_MBX_CMDS;
 
        if (lpfc_is_LC_HBA(phba->pcidev->device)) {
-               uint32_t *ptext = (uint32_t *) licensed;
+               if (init_key) {
+                       uint32_t *ptext = (uint32_t *) licensed;
 
-               for (i = 0; i < 56; i += sizeof (uint32_t), ptext++)
-                       *ptext = cpu_to_be32(*ptext);
+                       for (i = 0; i < 56; i += sizeof (uint32_t), ptext++)
+                               *ptext = cpu_to_be32(*ptext);
+                       init_key = 0;
+               }
 
                lpfc_read_nv(phba, pmb);
                memset((char*)mb->un.varRDnvp.rsvd3, 0,
@@ -405,19 +409,26 @@ lpfc_config_port_post(struct lpfc_hba * phba)
        }
        /* MBOX buffer will be freed in mbox compl */
 
-       i = 0;
+       return (0);
+}
+
+static int
+lpfc_discovery_wait(struct lpfc_hba *phba)
+{
+       int i = 0;
+
        while ((phba->hba_state != LPFC_HBA_READY) ||
               (phba->num_disc_nodes) || (phba->fc_prli_sent) ||
               ((phba->fc_map_cnt == 0) && (i<2)) ||
-              (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE)) {
+              (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE)) {
                /* Check every second for 30 retries. */
                i++;
                if (i > 30) {
-                       break;
+                       return -ETIMEDOUT;
                }
                if ((i >= 15) && (phba->hba_state <= LPFC_LINK_DOWN)) {
                        /* The link is down.  Set linkdown timeout */
-                       break;
+                       return -ETIMEDOUT;
                }
 
                /* Delay for 1 second to give discovery time to complete. */
@@ -425,12 +436,7 @@ lpfc_config_port_post(struct lpfc_hba * phba)
 
        }
 
-       /* Since num_disc_nodes keys off of PLOGI, delay a bit to let
-        * any potential PRLIs to flush thru the SLI sub-system.
-        */
-       msleep(50);
-
-       return (0);
+       return 0;
 }
 
 /************************************************************************/
@@ -1339,7 +1345,8 @@ lpfc_offline(struct lpfc_hba * phba)
        struct lpfc_sli_ring *pring;
        struct lpfc_sli *psli;
        unsigned long iflag;
-       int i = 0;
+       int i;
+       int cnt = 0;
 
        if (!phba)
                return 0;
@@ -1348,17 +1355,27 @@ lpfc_offline(struct lpfc_hba * phba)
                return 0;
 
        psli = &phba->sli;
-       pring = &psli->ring[psli->fcp_ring];
 
        lpfc_linkdown(phba);
+       lpfc_sli_flush_mbox_queue(phba);
 
-       /* The linkdown event takes 30 seconds to timeout. */
-       while (pring->txcmplq_cnt) {
-               mdelay(10);
-               if (i++ > 3000)
-                       break;
+       for (i = 0; i < psli->num_rings; i++) {
+               pring = &psli->ring[i];
+               /* The linkdown event takes 30 seconds to timeout. */
+               while (pring->txcmplq_cnt) {
+                       mdelay(10);
+                       if (cnt++ > 3000) {
+                               lpfc_printf_log(phba,
+                                       KERN_WARNING, LOG_INIT,
+                                       "%d:0466 Outstanding IO when "
+                                       "bringing Adapter offline\n",
+                                       phba->brd_no);
+                               break;
+                       }
+               }
        }
 
+
        /* stop all timers associated with this hba */
        lpfc_stop_timer(phba);
        phba->work_hba_events = 0;
@@ -1639,6 +1656,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
                goto out_free_irq;
        }
 
+       lpfc_discovery_wait(phba);
+
        if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
                spin_lock_irq(phba->host->host_lock);
                lpfc_poll_start_timer(phba);
index 0701765..066292d 100644 (file)
@@ -133,6 +133,11 @@ lpfc_mem_free(struct lpfc_hba * phba)
 
        pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
        pci_pool_destroy(phba->lpfc_mbuf_pool);
+
+       /* Free the iocb lookup array */
+       kfree(psli->iocbq_lookup);
+       psli->iocbq_lookup = NULL;
+
 }
 
 void *
index 27d60ad..bd0b0e2 100644 (file)
@@ -1110,6 +1110,17 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,
                                phba->brd_no,
                                did, mb->mbxStatus, phba->hba_state);
 
+               /*
+                * If RegLogin failed due to lack of HBA resources do not
+                * retry discovery.
+                */
+               if (mb->mbxStatus == MBXERR_RPI_FULL) {
+                       ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
+                       ndlp->nlp_state = NLP_STE_UNUSED_NODE;
+                       lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
+                       return ndlp->nlp_state;
+               }
+
                /* Put ndlp in npr list set plogi timer for 1 sec */
                mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
                spin_lock_irq(phba->host->host_lock);
index aea1ee4..a760a44 100644 (file)
@@ -153,22 +153,6 @@ static void
 lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
 {
        unsigned long iflag = 0;
-       /*
-        * There are only two special cases to consider.  (1) the scsi command
-        * requested scatter-gather usage or (2) the scsi command allocated
-        * a request buffer, but did not request use_sg.  There is a third
-        * case, but it does not require resource deallocation.
-        */
-       if ((psb->seg_cnt > 0) && (psb->pCmd->use_sg)) {
-               dma_unmap_sg(&phba->pcidev->dev, psb->pCmd->request_buffer,
-                               psb->seg_cnt, psb->pCmd->sc_data_direction);
-       } else {
-                if ((psb->nonsg_phys) && (psb->pCmd->request_bufflen)) {
-                       dma_unmap_single(&phba->pcidev->dev, psb->nonsg_phys,
-                                               psb->pCmd->request_bufflen,
-                                               psb->pCmd->sc_data_direction);
-                }
-       }
 
        spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
        psb->pCmd = NULL;
@@ -282,6 +266,27 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd)
 }
 
 static void
+lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
+{
+       /*
+        * There are only two special cases to consider.  (1) the scsi command
+        * requested scatter-gather usage or (2) the scsi command allocated
+        * a request buffer, but did not request use_sg.  There is a third
+        * case, but it does not require resource deallocation.
+        */
+       if ((psb->seg_cnt > 0) && (psb->pCmd->use_sg)) {
+               dma_unmap_sg(&phba->pcidev->dev, psb->pCmd->request_buffer,
+                               psb->seg_cnt, psb->pCmd->sc_data_direction);
+       } else {
+                if ((psb->nonsg_phys) && (psb->pCmd->request_bufflen)) {
+                       dma_unmap_single(&phba->pcidev->dev, psb->nonsg_phys,
+                                               psb->pCmd->request_bufflen,
+                                               psb->pCmd->sc_data_direction);
+                }
+       }
+}
+
+static void
 lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd)
 {
        struct scsi_cmnd *cmnd = lpfc_cmd->pCmd;
@@ -454,6 +459,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
        cmd->scsi_done(cmd);
 
        if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+               lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
                lpfc_release_scsi_buf(phba, lpfc_cmd);
                return;
        }
@@ -511,6 +517,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
                }
        }
 
+       lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
        lpfc_release_scsi_buf(phba, lpfc_cmd);
 }
 
@@ -609,6 +616,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd,
 static int
 lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
                             struct lpfc_scsi_buf *lpfc_cmd,
+                            unsigned int lun,
                             uint8_t task_mgmt_cmd)
 {
        struct lpfc_sli *psli;
@@ -627,8 +635,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
        piocb = &piocbq->iocb;
 
        fcp_cmnd = lpfc_cmd->fcp_cmnd;
-       int_to_scsilun(lpfc_cmd->pCmd->device->lun,
-                       &lpfc_cmd->fcp_cmnd->fcp_lun);
+       int_to_scsilun(lun, &lpfc_cmd->fcp_cmnd->fcp_lun);
        fcp_cmnd->fcpCntl2 = task_mgmt_cmd;
 
        piocb->ulpCommand = CMD_FCP_ICMND64_CR;
@@ -655,14 +662,16 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba,
 
 static int
 lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba,
-                   unsigned  tgt_id, struct lpfc_rport_data *rdata)
+                   unsigned  tgt_id, unsigned int lun,
+                   struct lpfc_rport_data *rdata)
 {
        struct lpfc_iocbq *iocbq;
        struct lpfc_iocbq *iocbqrsp;
        int ret;
 
        lpfc_cmd->rdata = rdata;
-       ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET);
+       ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun,
+                                          FCP_TARGET_RESET);
        if (!ret)
                return FAILED;
 
@@ -822,6 +831,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
        return 0;
 
  out_host_busy_free_buf:
+       lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
        lpfc_release_scsi_buf(phba, lpfc_cmd);
  out_host_busy:
        return SCSI_MLQUEUE_HOST_BUSY;
@@ -969,12 +979,12 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
        if (lpfc_cmd == NULL)
                goto out;
 
-       lpfc_cmd->pCmd = cmnd;
        lpfc_cmd->timeout = 60;
        lpfc_cmd->scsi_hba = phba;
        lpfc_cmd->rdata = rdata;
 
-       ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_LUN_RESET);
+       ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, cmnd->device->lun,
+                                          FCP_LUN_RESET);
        if (!ret)
                goto out_free_scsi_buf;
 
@@ -1001,7 +1011,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
        cmd_status = iocbqrsp->iocb.ulpStatus;
 
        lpfc_sli_release_iocbq(phba, iocbqrsp);
-       lpfc_release_scsi_buf(phba, lpfc_cmd);
 
        /*
         * All outstanding txcmplq I/Os should have been aborted by the device.
@@ -1040,6 +1049,8 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
        }
 
 out_free_scsi_buf:
+       lpfc_release_scsi_buf(phba, lpfc_cmd);
+
        lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
                        "%d:0713 SCSI layer issued LUN reset (%d, %d) "
                        "Data: x%x x%x x%x\n",
@@ -1070,7 +1081,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
 
        /* The lpfc_cmd storage is reused.  Set all loop invariants. */
        lpfc_cmd->timeout = 60;
-       lpfc_cmd->pCmd = cmnd;
        lpfc_cmd->scsi_hba = phba;
 
        /*
@@ -1078,7 +1088,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
         * targets known to the driver.  Should any target reset
         * fail, this routine returns failure to the midlayer.
         */
-       for (i = 0; i < MAX_FCP_TARGET; i++) {
+       for (i = 0; i < LPFC_MAX_TARGET; i++) {
                /* Search the mapped list for this target ID */
                match = 0;
                list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
@@ -1090,8 +1100,8 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
                if (!match)
                        continue;
 
-               ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba,
-                                         i, ndlp->rport->dd_data);
+               ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, i, cmnd->device->lun,
+                                         ndlp->rport->dd_data);
                if (ret != SUCCESS) {
                        lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
                                "%d:0713 Bus Reset on target %d failed\n",
index bb69a7a..350a625 100644 (file)
@@ -191,35 +191,12 @@ static int
 lpfc_sli_ringtxcmpl_put(struct lpfc_hba * phba,
                        struct lpfc_sli_ring * pring, struct lpfc_iocbq * piocb)
 {
-       uint16_t iotag;
-
        list_add_tail(&piocb->list, &pring->txcmplq);
        pring->txcmplq_cnt++;
        if (unlikely(pring->ringno == LPFC_ELS_RING))
                mod_timer(&phba->els_tmofunc,
                                        jiffies + HZ * (phba->fc_ratov << 1));
 
-       if (pring->fast_lookup) {
-               /* Setup fast lookup based on iotag for completion */
-               iotag = piocb->iocb.ulpIoTag;
-               if (iotag && (iotag < pring->fast_iotag))
-                       *(pring->fast_lookup + iotag) = piocb;
-               else {
-
-                       /* Cmd ring <ringno> put: iotag <iotag> greater then
-                          configured max <fast_iotag> wd0 <icmd> */
-                       lpfc_printf_log(phba,
-                                       KERN_ERR,
-                                       LOG_SLI,
-                                       "%d:0316 Cmd ring %d put: iotag x%x "
-                                       "greater then configured max x%x "
-                                       "wd0 x%x\n",
-                                       phba->brd_no,
-                                       pring->ringno, iotag,
-                                       pring->fast_iotag,
-                                       *(((uint32_t *)(&piocb->iocb)) + 7));
-               }
-       }
        return (0);
 }
 
@@ -601,7 +578,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba)
                        /* Stray Mailbox Interrupt, mbxCommand <cmd> mbxStatus
                           <status> */
                        lpfc_printf_log(phba,
-                                       KERN_ERR,
+                                       KERN_WARNING,
                                        LOG_MBOX | LOG_SLI,
                                        "%d:0304 Stray Mailbox Interrupt "
                                        "mbxCommand x%x mbxStatus x%x\n",
@@ -1570,8 +1547,8 @@ lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask)
 
 void lpfc_reset_barrier(struct lpfc_hba * phba)
 {
-       uint32_t resp_buf;
-       uint32_t mbox_buf;
+       uint32_t __iomem *resp_buf;
+       uint32_t __iomem *mbox_buf;
        volatile uint32_t mbox;
        uint32_t hc_copy;
        int  i;
@@ -1587,7 +1564,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba)
         * Tell the other part of the chip to suspend temporarily all
         * its DMA activity.
         */
-       resp_buf =  (uint32_t *)phba->MBslimaddr;
+       resp_buf = phba->MBslimaddr;
 
        /* Disable the error attention */
        hc_copy = readl(phba->HCregaddr);
@@ -1605,7 +1582,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba)
        ((MAILBOX_t *)&mbox)->mbxOwner = OWN_CHIP;
 
        writel(BARRIER_TEST_PATTERN, (resp_buf + 1));
-       mbox_buf = (uint32_t *)phba->MBslimaddr;
+       mbox_buf = phba->MBslimaddr;
        writel(mbox, mbox_buf);
 
        for (i = 0;
@@ -1805,7 +1782,7 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba)
                skip_post = 0;
                word0 = 0;      /* This is really setting up word1 */
        }
-       to_slim = (uint8_t *) phba->MBslimaddr + sizeof (uint32_t);
+       to_slim = phba->MBslimaddr + sizeof (uint32_t);
        writel(*(uint32_t *) mb, to_slim);
        readl(to_slim); /* flush */
 
@@ -2659,8 +2636,6 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
 
                INIT_LIST_HEAD(&(pring->txq));
 
-               kfree(pring->fast_lookup);
-               pring->fast_lookup = NULL;
        }
 
        spin_unlock_irqrestore(phba->host->host_lock, flags);
@@ -3110,6 +3085,24 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
        return retval;
 }
 
+int
+lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba)
+{
+       int i = 0;
+
+       while (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE && !phba->stopped) {
+               if (i++ > LPFC_MBOX_TMO * 1000)
+                       return 1;
+
+               if (lpfc_sli_handle_mb_event(phba) == 0)
+                       i = 0;
+
+               msleep(1);
+       }
+
+       return (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) ? 1 : 0;
+}
+
 irqreturn_t
 lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs)
 {
index a52d6c6..d8ef0d2 100644 (file)
@@ -135,8 +135,6 @@ struct lpfc_sli_ring {
        uint32_t fast_iotag;    /* max fastlookup based iotag           */
        uint32_t iotag_ctr;     /* keeps track of the next iotag to use */
        uint32_t iotag_max;     /* max iotag value to use               */
-       struct lpfc_iocbq ** fast_lookup; /* array of IOCB ptrs indexed by
-                                          iotag */
        struct list_head txq;
        uint16_t txq_cnt;       /* current length of queue */
        uint16_t txq_max;       /* max length */
index 6b73756..10e89c6 100644 (file)
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.1.6"
+#define LPFC_DRIVER_VERSION "8.1.7"
 
 #define LPFC_DRIVER_NAME "lpfc"
 
index 93edaa8..89ef34d 100644 (file)
@@ -378,7 +378,7 @@ static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd)
                int nseg;
 
                total = 0;
-               scl = (struct scatterlist *) cmd->buffer;
+               scl = (struct scatterlist *) cmd->request_buffer;
                nseg = pci_map_sg(state->pdev, scl, cmd->use_sg,
                                cmd->sc_data_direction);
                for (i = 0; i < nseg; ++i) {
index c887177..5572981 100644 (file)
@@ -1268,7 +1268,7 @@ static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd)
                if (cmd->use_sg > 0) {
                        int nseg;
                        total = 0;
-                       scl = (struct scatterlist *) cmd->buffer;
+                       scl = (struct scatterlist *) cmd->request_buffer;
                        off = ms->data_ptr;
                        nseg = pci_map_sg(ms->pdev, scl, cmd->use_sg,
                                          cmd->sc_data_direction);
index 7abf64d..0bd9c60 100644 (file)
@@ -169,8 +169,6 @@ int __init pluto_detect(struct scsi_host_template *tpnt)
                SCpnt->request->rq_status = RQ_SCSI_BUSY;
                
                SCpnt->done = pluto_detect_done;
-               SCpnt->bufflen = 256;
-               SCpnt->buffer = fcs[i].inquiry;
                SCpnt->request_bufflen = 256;
                SCpnt->request_buffer = fcs[i].inquiry;
                PLD(("set up %d %08lx\n", i, (long)SCpnt))
index 69e0551..5b2f074 100644 (file)
@@ -874,7 +874,7 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
        if (Cmnd->use_sg) {
                int sg_count;
 
-               sg = (struct scatterlist *) Cmnd->buffer;
+               sg = (struct scatterlist *) Cmnd->request_buffer;
                sg_count = sbus_map_sg(qpti->sdev, sg, Cmnd->use_sg, Cmnd->sc_data_direction);
 
                ds = cmd->dataseg;
@@ -1278,7 +1278,7 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti)
 
                if (Cmnd->use_sg) {
                        sbus_unmap_sg(qpti->sdev,
-                                     (struct scatterlist *)Cmnd->buffer,
+                                     (struct scatterlist *)Cmnd->request_buffer,
                                      Cmnd->use_sg,
                                      Cmnd->sc_data_direction);
                } else {
index 2ab7df0..b332cad 100644 (file)
@@ -346,7 +346,7 @@ void scsi_log_send(struct scsi_cmnd *cmd)
                        if (level > 3) {
                                printk(KERN_INFO "buffer = 0x%p, bufflen = %d,"
                                       " done = 0x%p, queuecommand 0x%p\n",
-                                       cmd->buffer, cmd->bufflen,
+                                       cmd->request_buffer, cmd->request_bufflen,
                                        cmd->done,
                                        sdev->host->hostt->queuecommand);
 
@@ -661,11 +661,6 @@ void __scsi_done(struct scsi_cmnd *cmd)
  */
 int scsi_retry_command(struct scsi_cmnd *cmd)
 {
-       /*
-        * Restore the SCSI command state.
-        */
-       scsi_setup_cmd_retry(cmd);
-
         /*
          * Zero the sense information from the last time we tried
          * this command.
@@ -711,10 +706,6 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
                                "Notifying upper driver of completion "
                                "(result %x)\n", cmd->result));
 
-       /*
-        * We can get here with use_sg=0, causing a panic in the upper level
-        */
-       cmd->use_sg = cmd->old_use_sg;
        cmd->done(cmd);
 }
 EXPORT_SYMBOL(scsi_finish_command);
index 9c63b00..a80303c 100644 (file)
@@ -286,7 +286,7 @@ static int inquiry_evpd_83(unsigned char * arr, int target_dev_id,
                           int dev_id_num, const char * dev_id_str,
                           int dev_id_str_len);
 static int inquiry_evpd_88(unsigned char * arr, int target_dev_id);
-static void do_create_driverfs_files(void);
+static int do_create_driverfs_files(void);
 static void do_remove_driverfs_files(void);
 
 static int sdebug_add_adapter(void);
@@ -2487,19 +2487,22 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp,
 DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show, 
            sdebug_add_host_store);
 
-static void do_create_driverfs_files(void)
+static int do_create_driverfs_files(void)
 {
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
-       driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
+       int ret;
+
+       ret = driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
+       ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
+       return ret;
 }
 
 static void do_remove_driverfs_files(void)
@@ -2522,6 +2525,7 @@ static int __init scsi_debug_init(void)
        unsigned int sz;
        int host_to_add;
        int k;
+       int ret;
 
        if (scsi_debug_dev_size_mb < 1)
                scsi_debug_dev_size_mb = 1;  /* force minimum 1 MB ramdisk */
@@ -2560,12 +2564,32 @@ static int __init scsi_debug_init(void)
        if (scsi_debug_num_parts > 0)
                sdebug_build_parts(fake_storep);
 
-       init_all_queued();
+       ret = device_register(&pseudo_primary);
+       if (ret < 0) {
+               printk(KERN_WARNING "scsi_debug: device_register error: %d\n",
+                       ret);
+               goto free_vm;
+       }
+       ret = bus_register(&pseudo_lld_bus);
+       if (ret < 0) {
+               printk(KERN_WARNING "scsi_debug: bus_register error: %d\n",
+                       ret);
+               goto dev_unreg;
+       }
+       ret = driver_register(&sdebug_driverfs_driver);
+       if (ret < 0) {
+               printk(KERN_WARNING "scsi_debug: driver_register error: %d\n",
+                       ret);
+               goto bus_unreg;
+       }
+       ret = do_create_driverfs_files();
+       if (ret < 0) {
+               printk(KERN_WARNING "scsi_debug: driver_create_file error: %d\n",
+                       ret);
+               goto del_files;
+       }
 
-       device_register(&pseudo_primary);
-       bus_register(&pseudo_lld_bus);
-       driver_register(&sdebug_driverfs_driver);
-       do_create_driverfs_files();
+       init_all_queued();
 
        sdebug_driver_template.proc_name = (char *)sdebug_proc_name;
 
@@ -2585,6 +2609,18 @@ static int __init scsi_debug_init(void)
                       scsi_debug_add_host);
        }
        return 0;
+
+del_files:
+       do_remove_driverfs_files();
+       driver_unregister(&sdebug_driverfs_driver);
+bus_unreg:
+       bus_unregister(&pseudo_lld_bus);
+dev_unreg:
+       device_unregister(&pseudo_primary);
+free_vm:
+       vfree(fake_storep);
+
+       return ret;
 }
 
 static void __exit scsi_debug_exit(void)
index 6683d59..6a5b731 100644 (file)
@@ -460,19 +460,67 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
  * Return value:
  *    SUCCESS or FAILED or NEEDS_RETRY
  **/
-static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
+static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout, int copy_sense)
 {
        struct scsi_device *sdev = scmd->device;
        struct Scsi_Host *shost = sdev->host;
+       int old_result = scmd->result;
        DECLARE_COMPLETION(done);
        unsigned long timeleft;
        unsigned long flags;
+       unsigned char old_cmnd[MAX_COMMAND_SIZE];
+       enum dma_data_direction old_data_direction;
+       unsigned short old_use_sg;
+       unsigned char old_cmd_len;
+       unsigned old_bufflen;
+       void *old_buffer;
        int rtn;
 
+       /*
+        * We need saved copies of a number of fields - this is because
+        * error handling may need to overwrite these with different values
+        * to run different commands, and once error handling is complete,
+        * we will need to restore these values prior to running the actual
+        * command.
+        */
+       old_buffer = scmd->request_buffer;
+       old_bufflen = scmd->request_bufflen;
+       memcpy(old_cmnd, scmd->cmnd, sizeof(scmd->cmnd));
+       old_data_direction = scmd->sc_data_direction;
+       old_cmd_len = scmd->cmd_len;
+       old_use_sg = scmd->use_sg;
+
+       if (copy_sense) {
+               int gfp_mask = GFP_ATOMIC;
+
+               if (shost->hostt->unchecked_isa_dma)
+                       gfp_mask |= __GFP_DMA;
+
+               scmd->sc_data_direction = DMA_FROM_DEVICE;
+               scmd->request_bufflen = 252;
+               scmd->request_buffer = kzalloc(scmd->request_bufflen, gfp_mask);
+               if (!scmd->request_buffer)
+                       return FAILED;
+       } else {
+               scmd->request_buffer = NULL;
+               scmd->request_bufflen = 0;
+               scmd->sc_data_direction = DMA_NONE;
+       }
+
+       scmd->underflow = 0;
+       scmd->use_sg = 0;
+       scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
+
        if (sdev->scsi_level <= SCSI_2)
                scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
                        (sdev->lun << 5 & 0xe0);
 
+       /*
+        * Zero the sense buffer.  The scsi spec mandates that any
+        * untransferred sense data should be interpreted as being zero.
+        */
+       memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
+
        shost->eh_action = &done;
 
        spin_lock_irqsave(shost->host_lock, flags);
@@ -522,6 +570,29 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
                rtn = FAILED;
        }
 
+
+       /*
+        * Last chance to have valid sense data.
+        */
+       if (copy_sense) {
+               if (!SCSI_SENSE_VALID(scmd)) {
+                       memcpy(scmd->sense_buffer, scmd->request_buffer,
+                              sizeof(scmd->sense_buffer));
+               }
+               kfree(scmd->request_buffer);
+       }
+
+
+       /*
+        * Restore original data
+        */
+       scmd->request_buffer = old_buffer;
+       scmd->request_bufflen = old_bufflen;
+       memcpy(scmd->cmnd, old_cmnd, sizeof(scmd->cmnd));
+       scmd->sc_data_direction = old_data_direction;
+       scmd->cmd_len = old_cmd_len;
+       scmd->use_sg = old_use_sg;
+       scmd->result = old_result;
        return rtn;
 }
 
@@ -537,56 +608,10 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
 static int scsi_request_sense(struct scsi_cmnd *scmd)
 {
        static unsigned char generic_sense[6] =
-       {REQUEST_SENSE, 0, 0, 0, 252, 0};
-       unsigned char *scsi_result;
-       int saved_result;
-       int rtn;
+               {REQUEST_SENSE, 0, 0, 0, 252, 0};
 
        memcpy(scmd->cmnd, generic_sense, sizeof(generic_sense));
-
-       scsi_result = kmalloc(252, GFP_ATOMIC | ((scmd->device->host->hostt->unchecked_isa_dma) ? __GFP_DMA : 0));
-
-
-       if (unlikely(!scsi_result)) {
-               printk(KERN_ERR "%s: cannot allocate scsi_result.\n",
-                      __FUNCTION__);
-               return FAILED;
-       }
-
-       /*
-        * zero the sense buffer.  some host adapters automatically always
-        * request sense, so it is not a good idea that
-        * scmd->request_buffer and scmd->sense_buffer point to the same
-        * address (db).  0 is not a valid sense code. 
-        */
-       memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
-       memset(scsi_result, 0, 252);
-
-       saved_result = scmd->result;
-       scmd->request_buffer = scsi_result;
-       scmd->request_bufflen = 252;
-       scmd->use_sg = 0;
-       scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
-       scmd->sc_data_direction = DMA_FROM_DEVICE;
-       scmd->underflow = 0;
-
-       rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT);
-
-       /* last chance to have valid sense data */
-       if(!SCSI_SENSE_VALID(scmd)) {
-               memcpy(scmd->sense_buffer, scmd->request_buffer,
-                      sizeof(scmd->sense_buffer));
-       }
-
-       kfree(scsi_result);
-
-       /*
-        * when we eventually call scsi_finish, we really wish to complete
-        * the original request, so let's restore the original data. (db)
-        */
-       scsi_setup_cmd_retry(scmd);
-       scmd->result = saved_result;
-       return rtn;
+       return scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 1);
 }
 
 /**
@@ -605,12 +630,6 @@ void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)
 {
        scmd->device->host->host_failed--;
        scmd->eh_eflags = 0;
-
-       /*
-        * set this back so that the upper level can correctly free up
-        * things.
-        */
-       scsi_setup_cmd_retry(scmd);
        list_move_tail(&scmd->eh_entry, done_q);
 }
 EXPORT_SYMBOL(scsi_eh_finish_cmd);
@@ -715,47 +734,26 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd)
 {
        static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
        int retry_cnt = 1, rtn;
-       int saved_result;
 
 retry_tur:
        memcpy(scmd->cmnd, tur_command, sizeof(tur_command));
 
-       /*
-        * zero the sense buffer.  the scsi spec mandates that any
-        * untransferred sense data should be interpreted as being zero.
-        */
-       memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
-
-       saved_result = scmd->result;
-       scmd->request_buffer = NULL;
-       scmd->request_bufflen = 0;
-       scmd->use_sg = 0;
-       scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
-       scmd->underflow = 0;
-       scmd->sc_data_direction = DMA_NONE;
 
-       rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT);
+       rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 0);
 
-       /*
-        * when we eventually call scsi_finish, we really wish to complete
-        * the original request, so let's restore the original data. (db)
-        */
-       scsi_setup_cmd_retry(scmd);
-       scmd->result = saved_result;
-
-       /*
-        * hey, we are done.  let's look to see what happened.
-        */
        SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n",
                __FUNCTION__, scmd, rtn));
-       if (rtn == SUCCESS)
-               return 0;
-       else if (rtn == NEEDS_RETRY) {
+
+       switch (rtn) {
+       case NEEDS_RETRY:
                if (retry_cnt--)
                        goto retry_tur;
+               /*FALLTHRU*/
+       case SUCCESS:
                return 0;
+       default:
+               return 1;
        }
-       return 1;
 }
 
 /**
@@ -837,44 +835,16 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
 static int scsi_eh_try_stu(struct scsi_cmnd *scmd)
 {
        static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0};
-       int rtn;
-       int saved_result;
 
-       if (!scmd->device->allow_restart)
-               return 1;
-
-       memcpy(scmd->cmnd, stu_command, sizeof(stu_command));
-
-       /*
-        * zero the sense buffer.  the scsi spec mandates that any
-        * untransferred sense data should be interpreted as being zero.
-        */
-       memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
-
-       saved_result = scmd->result;
-       scmd->request_buffer = NULL;
-       scmd->request_bufflen = 0;
-       scmd->use_sg = 0;
-       scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
-       scmd->underflow = 0;
-       scmd->sc_data_direction = DMA_NONE;
+       if (scmd->device->allow_restart) {
+               int rtn;
 
-       rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT);
-
-       /*
-        * when we eventually call scsi_finish, we really wish to complete
-        * the original request, so let's restore the original data. (db)
-        */
-       scsi_setup_cmd_retry(scmd);
-       scmd->result = saved_result;
+               memcpy(scmd->cmnd, stu_command, sizeof(stu_command));
+               rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT, 0);
+               if (rtn == SUCCESS)
+                       return 0;
+       }
 
-       /*
-        * hey, we are done.  let's look to see what happened.
-        */
-       SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n",
-               __FUNCTION__, scmd, rtn));
-       if (rtn == SUCCESS)
-               return 0;
        return 1;
 }
 
@@ -1684,8 +1654,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
     
        scmd->scsi_done         = scsi_reset_provider_done_command;
        scmd->done                      = NULL;
-       scmd->buffer                    = NULL;
-       scmd->bufflen                   = 0;
        scmd->request_buffer            = NULL;
        scmd->request_bufflen           = 0;
 
index a89c411..32293f4 100644 (file)
@@ -110,11 +110,8 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
                                       sshdr.asc, sshdr.ascq);
                        break;
                case NOT_READY: /* This happens if there is no disc in drive */
-                       if (sdev->removable && (cmd[0] != TEST_UNIT_READY)) {
-                               printk(KERN_INFO "Device not ready. Make sure"
-                                      " there is a disc in the drive.\n");
+                       if (sdev->removable)
                                break;
-                       }
                case UNIT_ATTENTION:
                        if (sdev->removable) {
                                sdev->changed = 1;
index 08af9aa..077c1c6 100644 (file)
@@ -436,60 +436,16 @@ EXPORT_SYMBOL_GPL(scsi_execute_async);
  *
  * Arguments:   cmd    - command that is ready to be queued.
  *
- * Returns:     Nothing
- *
  * Notes:       This function has the job of initializing a number of
  *              fields related to error handling.   Typically this will
  *              be called once for each command, as required.
  */
-static int scsi_init_cmd_errh(struct scsi_cmnd *cmd)
+static void scsi_init_cmd_errh(struct scsi_cmnd *cmd)
 {
        cmd->serial_number = 0;
-
        memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer);
-
        if (cmd->cmd_len == 0)
                cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]);
-
-       /*
-        * We need saved copies of a number of fields - this is because
-        * error handling may need to overwrite these with different values
-        * to run different commands, and once error handling is complete,
-        * we will need to restore these values prior to running the actual
-        * command.
-        */
-       cmd->old_use_sg = cmd->use_sg;
-       cmd->old_cmd_len = cmd->cmd_len;
-       cmd->sc_old_data_direction = cmd->sc_data_direction;
-       cmd->old_underflow = cmd->underflow;
-       memcpy(cmd->data_cmnd, cmd->cmnd, sizeof(cmd->cmnd));
-       cmd->buffer = cmd->request_buffer;
-       cmd->bufflen = cmd->request_bufflen;
-
-       return 1;
-}
-
-/*
- * Function:   scsi_setup_cmd_retry()
- *
- * Purpose:    Restore the command state for a retry
- *
- * Arguments:  cmd     - command to be restored
- *
- * Returns:    Nothing
- *
- * Notes:      Immediately prior to retrying a command, we need
- *             to restore certain fields that we saved above.
- */
-void scsi_setup_cmd_retry(struct scsi_cmnd *cmd)
-{
-       memcpy(cmd->cmnd, cmd->data_cmnd, sizeof(cmd->data_cmnd));
-       cmd->request_buffer = cmd->buffer;
-       cmd->request_bufflen = cmd->bufflen;
-       cmd->use_sg = cmd->old_use_sg;
-       cmd->cmd_len = cmd->old_cmd_len;
-       cmd->sc_data_direction = cmd->sc_old_data_direction;
-       cmd->underflow = cmd->old_underflow;
 }
 
 void scsi_device_unbusy(struct scsi_device *sdev)
@@ -807,22 +763,13 @@ static void scsi_free_sgtable(struct scatterlist *sgl, int index)
  */
 static void scsi_release_buffers(struct scsi_cmnd *cmd)
 {
-       struct request *req = cmd->request;
-
-       /*
-        * Free up any indirection buffers we allocated for DMA purposes. 
-        */
        if (cmd->use_sg)
                scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
-       else if (cmd->request_buffer != req->buffer)
-               kfree(cmd->request_buffer);
 
        /*
         * Zero these out.  They now point to freed memory, and it is
         * dangerous to hang onto the pointers.
         */
-       cmd->buffer  = NULL;
-       cmd->bufflen = 0;
        cmd->request_buffer = NULL;
        cmd->request_bufflen = 0;
 }
@@ -858,7 +805,7 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd)
 void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 {
        int result = cmd->result;
-       int this_count = cmd->bufflen;
+       int this_count = cmd->request_bufflen;
        request_queue_t *q = cmd->device->request_queue;
        struct request *req = cmd->request;
        int clear_errors = 1;
@@ -866,28 +813,14 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
        int sense_valid = 0;
        int sense_deferred = 0;
 
-       /*
-        * Free up any indirection buffers we allocated for DMA purposes. 
-        * For the case of a READ, we need to copy the data out of the
-        * bounce buffer and into the real buffer.
-        */
-       if (cmd->use_sg)
-               scsi_free_sgtable(cmd->buffer, cmd->sglist_len);
-       else if (cmd->buffer != req->buffer) {
-               if (rq_data_dir(req) == READ) {
-                       unsigned long flags;
-                       char *to = bio_kmap_irq(req->bio, &flags);
-                       memcpy(to, cmd->buffer, cmd->bufflen);
-                       bio_kunmap_irq(to, &flags);
-               }
-               kfree(cmd->buffer);
-       }
+       scsi_release_buffers(cmd);
 
        if (result) {
                sense_valid = scsi_command_normalize_sense(cmd, &sshdr);
                if (sense_valid)
                        sense_deferred = scsi_sense_is_deferred(&sshdr);
        }
+
        if (blk_pc_request(req)) { /* SG_IO ioctl from block level */
                req->errors = result;
                if (result) {
@@ -908,15 +841,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
        }
 
        /*
-        * Zero these out.  They now point to freed memory, and it is
-        * dangerous to hang onto the pointers.
-        */
-       cmd->buffer  = NULL;
-       cmd->bufflen = 0;
-       cmd->request_buffer = NULL;
-       cmd->request_bufflen = 0;
-
-       /*
         * Next deal with any sectors which we were able to correctly
         * handle.
         */
@@ -1012,7 +936,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                        if (!(req->flags & REQ_QUIET)) {
                                scmd_printk(KERN_INFO, cmd,
                                            "Volume overflow, CDB: ");
-                               __scsi_print_command(cmd->data_cmnd);
+                               __scsi_print_command(cmd->cmnd);
                                scsi_print_sense("", cmd);
                        }
                        /* See SSC3rXX or current. */
@@ -1143,7 +1067,7 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd)
         * successfully. Since this is a REQ_BLOCK_PC command the
         * caller should check the request's errors value
         */
-       scsi_io_completion(cmd, cmd->bufflen);
+       scsi_io_completion(cmd, cmd->request_bufflen);
 }
 
 static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
index e2fbe9a..ae24c85 100644 (file)
@@ -57,7 +57,6 @@ extern int scsi_eh_scmd_add(struct scsi_cmnd *, int);
 
 /* scsi_lib.c */
 extern int scsi_maybe_unblock_host(struct scsi_device *sdev);
-extern void scsi_setup_cmd_retry(struct scsi_cmnd *cmd);
 extern void scsi_device_unbusy(struct scsi_device *sdev);
 extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason);
 extern void scsi_next_command(struct scsi_cmnd *cmd);
index dd07562..5a625c3 100644 (file)
@@ -41,6 +41,7 @@ struct sas_host_attrs {
        struct mutex lock;
        u32 next_target_id;
        u32 next_expander_id;
+       int next_port_id;
 };
 #define to_sas_host_attrs(host)        ((struct sas_host_attrs *)(host)->shost_data)
 
@@ -146,6 +147,7 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev,
        mutex_init(&sas_host->lock);
        sas_host->next_target_id = 0;
        sas_host->next_expander_id = 0;
+       sas_host->next_port_id = 0;
        return 0;
 }
 
@@ -327,7 +329,7 @@ sas_phy_protocol_attr(identify.target_port_protocols,
 sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n",
                unsigned long long);
 sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8);
-//sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8);
+//sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", int);
 sas_phy_linkspeed_attr(negotiated_linkrate);
 sas_phy_linkspeed_attr(minimum_linkrate_hw);
 sas_phy_linkspeed_attr(minimum_linkrate);
@@ -590,6 +592,38 @@ struct sas_port *sas_port_alloc(struct device *parent, int port_id)
 }
 EXPORT_SYMBOL(sas_port_alloc);
 
+/** sas_port_alloc_num - allocate and initialize a SAS port structure
+ *
+ * @parent:    parent device
+ *
+ * Allocates a SAS port structure and a number to go with it.  This
+ * interface is really for adapters where the port number has no
+ * meansing, so the sas class should manage them.  It will be added to
+ * the device tree below the device specified by @parent which must be
+ * either a Scsi_Host or a sas_expander_device.
+ *
+ * Returns %NULL on error
+ */
+struct sas_port *sas_port_alloc_num(struct device *parent)
+{
+       int index;
+       struct Scsi_Host *shost = dev_to_shost(parent);
+       struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
+
+       /* FIXME: use idr for this eventually */
+       mutex_lock(&sas_host->lock);
+       if (scsi_is_sas_expander_device(parent)) {
+               struct sas_rphy *rphy = dev_to_rphy(parent);
+               struct sas_expander_device *exp = rphy_to_expander_device(rphy);
+
+               index = exp->next_port_id++;
+       } else
+               index = sas_host->next_port_id++;
+       mutex_unlock(&sas_host->lock);
+       return sas_port_alloc(parent, index);
+}
+EXPORT_SYMBOL(sas_port_alloc_num);
+
 /**
  * sas_port_add - add a SAS port to the device hierarchy
  *
@@ -658,6 +692,13 @@ void sas_port_delete(struct sas_port *port)
        }
        mutex_unlock(&port->phy_list_mutex);
 
+       if (port->is_backlink) {
+               struct device *parent = port->dev.parent;
+
+               sysfs_remove_link(&port->dev.kobj, parent->bus_id);
+               port->is_backlink = 0;
+       }
+
        transport_remove_device(dev);
        device_del(dev);
        transport_destroy_device(dev);
@@ -733,6 +774,19 @@ void sas_port_delete_phy(struct sas_port *port, struct sas_phy *phy)
 }
 EXPORT_SYMBOL(sas_port_delete_phy);
 
+void sas_port_mark_backlink(struct sas_port *port)
+{
+       struct device *parent = port->dev.parent->parent->parent;
+
+       if (port->is_backlink)
+               return;
+       port->is_backlink = 1;
+       sysfs_create_link(&port->dev.kobj, &parent->kobj,
+                         parent->bus_id);
+
+}
+EXPORT_SYMBOL(sas_port_mark_backlink);
+
 /*
  * SAS remote PHY attributes.
  */
@@ -1140,7 +1194,7 @@ int sas_rphy_add(struct sas_rphy *rphy)
 
        if (identify->device_type == SAS_END_DEVICE &&
            rphy->scsi_target_id != -1) {
-               scsi_scan_target(&rphy->dev, parent->port_identifier,
+               scsi_scan_target(&rphy->dev, 0,
                                rphy->scsi_target_id, ~0, 0);
        }
 
@@ -1242,15 +1296,13 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel,
 
        mutex_lock(&sas_host->lock);
        list_for_each_entry(rphy, &sas_host->rphy_list, list) {
-               struct sas_port *parent = dev_to_sas_port(rphy->dev.parent);
-
                if (rphy->identify.device_type != SAS_END_DEVICE ||
                    rphy->scsi_target_id == -1)
                        continue;
 
-               if ((channel == SCAN_WILD_CARD || channel == parent->port_identifier) &&
+               if ((channel == SCAN_WILD_CARD || channel == 0) &&
                    (id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) {
-                       scsi_scan_target(&rphy->dev, parent->port_identifier,
+                       scsi_scan_target(&rphy->dev, 0,
                                         rphy->scsi_target_id, lun, 1);
                }
        }
index 3225d31..98bd3aa 100644 (file)
@@ -502,8 +502,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
                SCpnt->cmnd[4] = (unsigned char) this_count;
                SCpnt->cmnd[5] = 0;
        }
-       SCpnt->request_bufflen = SCpnt->bufflen =
-                       this_count * sdp->sector_size;
+       SCpnt->request_bufflen = this_count * sdp->sector_size;
 
        /*
         * We shouldn't disconnect in the middle of a sector, so with a dumb
index 3f312a8..2679ea8 100644 (file)
@@ -1002,7 +1002,7 @@ connect_loop:
                        }
 #endif
 
-                       buffer = (struct scatterlist *) SCint->buffer;
+                       buffer = (struct scatterlist *) SCint->request_buffer;
                        len = buffer->length;
                        data = page_address(buffer->page) + buffer->offset;
                } else {
index fd94408..fae6e95 100644 (file)
@@ -360,7 +360,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
                                "mismatch count %d, bytes %d\n",
                                size, SCpnt->request_bufflen);
                        if (SCpnt->request_bufflen > size)
-                               SCpnt->request_bufflen = SCpnt->bufflen = size;
+                               SCpnt->request_bufflen = size;
                }
        }
 
@@ -387,8 +387,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
 
        if (this_count > 0xffff) {
                this_count = 0xffff;
-               SCpnt->request_bufflen = SCpnt->bufflen =
-                               this_count * s_size;
+               SCpnt->request_bufflen = this_count * s_size;
        }
 
        SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff;
index 756ceb9..7f669b6 100644 (file)
@@ -368,7 +368,7 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
                       SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
                       SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
                if (cmdstatp->have_sense)
-                        __scsi_print_sense("st", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
+                        __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
        } ) /* end DEB */
        if (!debugging) { /* Abnormal conditions for tape */
                if (!cmdstatp->have_sense)
@@ -384,9 +384,8 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
                         scode != VOLUME_OVERFLOW &&
                         SRpnt->cmd[0] != MODE_SENSE &&
                         SRpnt->cmd[0] != TEST_UNIT_READY) {
-                               printk(KERN_WARNING "%s: Error with sense data: ", name);
-                               __scsi_print_sense("st", SRpnt->sense,
-                                                  SCSI_SENSE_BUFFERSIZE);
+
+                       __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
                }
        }
 
index 2ebe0d6..2f8073b 100644 (file)
@@ -517,7 +517,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd *cmd)
      */
 
     if (cmd->use_sg) {
-       cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
+       cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
        cmd->SCp.buffers_residual = cmd->use_sg - 1;
        cmd->SCp.ptr = (char *) SGADDR(cmd->SCp.buffer);
        cmd->SCp.this_residual = cmd->SCp.buffer->length;
index 1f328ca..6b60536 100644 (file)
@@ -347,7 +347,7 @@ static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp)
 static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp)
 {
     int sz = sp->use_sg - 1;
-    struct scatterlist *sg = (struct scatterlist *)sp->buffer;
+    struct scatterlist *sg = (struct scatterlist *)sp->request_buffer;
                         
     while(sz >= 0) {
         dvma_unmap((char *)sg[sz].dma_address);
index 680f38a..2083454 100644 (file)
@@ -373,7 +373,7 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd,
  */
 
        if (cmd->use_sg) {
-               cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
+               cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
                cmd->SCp.buffers_residual = cmd->use_sg - 1;
                cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
                    cmd->SCp.buffer->offset;
index 979497f..dc673e1 100644 (file)
@@ -1047,12 +1047,13 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
        up = &sunsab_ports[inst * 2];
 
        err = sunsab_init_one(&up[0], op,
-                             sizeof(union sab82532_async_regs),
+                             0,
                              (inst * 2) + 0);
        if (err)
                return err;
 
-       err = sunsab_init_one(&up[1], op, 0,
+       err = sunsab_init_one(&up[1], op,
+                             sizeof(union sab82532_async_regs),
                              (inst * 2) + 1);
        if (err) {
                of_iounmap(up[0].port.membase,
@@ -1117,7 +1118,7 @@ static int __init sunsab_init(void)
        int err;
 
        num_channels = 0;
-       for_each_node_by_name(dp, "su")
+       for_each_node_by_name(dp, "se")
                num_channels += 2;
        for_each_node_by_name(dp, "serial") {
                if (of_device_is_compatible(dp, "sab82532"))
index a1456d9..47bc3d5 100644 (file)
@@ -68,9 +68,6 @@ static int num_sunzilog;
 #define NUM_SUNZILOG   num_sunzilog
 #define NUM_CHANNELS   (NUM_SUNZILOG * 2)
 
-#define KEYBOARD_LINE 0x2
-#define MOUSE_LINE    0x3
-
 #define ZS_CLOCK               4915200 /* Zilog input clock rate. */
 #define ZS_CLOCK_DIVISOR       16      /* Divisor this driver uses. */
 
@@ -1225,12 +1222,10 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
 {
        int baud, brg;
 
-       if (channel == KEYBOARD_LINE) {
-               up->flags |= SUNZILOG_FLAG_CONS_KEYB;
+       if (up->flags & SUNZILOG_FLAG_CONS_KEYB) {
                up->cflag = B1200 | CS8 | CLOCAL | CREAD;
                baud = 1200;
        } else {
-               up->flags |= SUNZILOG_FLAG_CONS_MOUSE;
                up->cflag = B4800 | CS8 | CLOCAL | CREAD;
                baud = 4800;
        }
@@ -1243,14 +1238,14 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
 }
 
 #ifdef CONFIG_SERIO
-static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int channel)
+static void __init sunzilog_register_serio(struct uart_sunzilog_port *up)
 {
        struct serio *serio = &up->serio;
 
        serio->port_data = up;
 
        serio->id.type = SERIO_RS232;
-       if (channel == KEYBOARD_LINE) {
+       if (up->flags & SUNZILOG_FLAG_CONS_KEYB) {
                serio->id.proto = SERIO_SUNKBD;
                strlcpy(serio->name, "zskbd", sizeof(serio->name));
        } else {
@@ -1259,7 +1254,8 @@ static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int ch
                strlcpy(serio->name, "zsms", sizeof(serio->name));
        }
        strlcpy(serio->phys,
-               (channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"),
+               ((up->flags & SUNZILOG_FLAG_CONS_KEYB) ?
+                "zs/serio0" : "zs/serio1"),
                sizeof(serio->phys));
 
        serio->write = sunzilog_serio_write;
@@ -1286,8 +1282,8 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up)
                (void) read_zsreg(channel, R0);
        }
 
-       if (up->port.line == KEYBOARD_LINE ||
-           up->port.line == MOUSE_LINE) {
+       if (up->flags & (SUNZILOG_FLAG_CONS_KEYB |
+                        SUNZILOG_FLAG_CONS_MOUSE)) {
                sunzilog_init_kbdms(up, up->port.line);
                up->curregs[R9] |= (NV | MIE);
                write_zsreg(channel, R9, up->curregs[R9]);
@@ -1313,37 +1309,26 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up)
        spin_unlock_irqrestore(&up->port.lock, flags);
 
 #ifdef CONFIG_SERIO
-       if (up->port.line == KEYBOARD_LINE || up->port.line == MOUSE_LINE)
-               sunzilog_register_serio(up, up->port.line);
+       if (up->flags & (SUNZILOG_FLAG_CONS_KEYB |
+                        SUNZILOG_FLAG_CONS_MOUSE))
+               sunzilog_register_serio(up);
 #endif
 }
 
-static int __devinit zs_get_instance(struct device_node *dp)
-{
-       int ret;
-
-       ret = of_getintprop_default(dp, "slave", -1);
-       if (ret != -1)
-               return ret;
-
-       if (of_find_property(dp, "keyboard", NULL))
-               ret = 1;
-       else
-               ret = 0;
-
-       return ret;
-}
-
 static int zilog_irq = -1;
 
-static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *match)
+static int __devinit zs_probe(struct of_device *op, const struct of_device_id *match)
 {
-       struct of_device *op = to_of_device(&dev->dev);
+       static int inst;
        struct uart_sunzilog_port *up;
        struct zilog_layout __iomem *rp;
-       int inst = zs_get_instance(dev->node);
+       int keyboard_mouse;
        int err;
 
+       keyboard_mouse = 0;
+       if (of_find_property(op->node, "keyboard", NULL))
+               keyboard_mouse = 1;
+
        sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0,
                                              sizeof(struct zilog_layout),
                                              "zs");
@@ -1352,16 +1337,8 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
 
        rp = sunzilog_chip_regs[inst];
 
-       if (zilog_irq == -1) {
+       if (zilog_irq == -1)
                zilog_irq = op->irqs[0];
-               err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED,
-                                 "zs", sunzilog_irq_chain);
-               if (err) {
-                       of_iounmap(rp, sizeof(struct zilog_layout));
-
-                       return err;
-               }
-       }
 
        up = &sunzilog_port_table[inst * 2];
 
@@ -1378,7 +1355,7 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
        up[0].port.line = (inst * 2) + 0;
        up[0].port.dev = &op->dev;
        up[0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A;
-       if (inst == 1)
+       if (keyboard_mouse)
                up[0].flags |= SUNZILOG_FLAG_CONS_KEYB;
        sunzilog_init_hw(&up[0]);
 
@@ -1395,11 +1372,11 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
        up[1].port.line = (inst * 2) + 1;
        up[1].port.dev = &op->dev;
        up[1].flags |= 0;
-       if (inst == 1)
+       if (keyboard_mouse)
                up[1].flags |= SUNZILOG_FLAG_CONS_MOUSE;
        sunzilog_init_hw(&up[1]);
 
-       if (inst != 1) {
+       if (!keyboard_mouse) {
                err = uart_add_one_port(&sunzilog_reg, &up[0].port);
                if (err) {
                        of_iounmap(rp, sizeof(struct zilog_layout));
@@ -1411,9 +1388,18 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
                        of_iounmap(rp, sizeof(struct zilog_layout));
                        return err;
                }
+       } else {
+               printk(KERN_INFO "%s: Keyboard at MMIO %lx (irq = %d) "
+                      "is a zs\n",
+                      op->dev.bus_id, up[0].port.mapbase, op->irqs[0]);
+               printk(KERN_INFO "%s: Mouse at MMIO %lx (irq = %d) "
+                      "is a zs\n",
+                      op->dev.bus_id, up[1].port.mapbase, op->irqs[0]);
        }
 
-       dev_set_drvdata(&dev->dev, &up[0]);
+       dev_set_drvdata(&op->dev, &up[0]);
+
+       inst++;
 
        return 0;
 }
@@ -1462,36 +1448,65 @@ static struct of_platform_driver zs_driver = {
 static int __init sunzilog_init(void)
 {
        struct device_node *dp;
-       int err;
+       int err, uart_count;
+       int num_keybms;
 
        NUM_SUNZILOG = 0;
-       for_each_node_by_name(dp, "zs")
+       num_keybms = 0;
+       for_each_node_by_name(dp, "zs") {
                NUM_SUNZILOG++;
+               if (of_find_property(dp, "keyboard", NULL))
+                       num_keybms++;
+       }
 
+       uart_count = 0;
        if (NUM_SUNZILOG) {
                int uart_count;
 
                err = sunzilog_alloc_tables();
                if (err)
-                       return err;
+                       goto out;
 
-               /* Subtract 1 for keyboard, 1 for mouse.  */
-               uart_count = (NUM_SUNZILOG * 2) - 2;
+               uart_count = (NUM_SUNZILOG * 2) - (2 * num_keybms);
 
                sunzilog_reg.nr = uart_count;
                sunzilog_reg.minor = sunserial_current_minor;
                err = uart_register_driver(&sunzilog_reg);
-               if (err) {
-                       sunzilog_free_tables();
-                       return err;
-               }
+               if (err)
+                       goto out_free_tables;
+
                sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64;
                sunzilog_reg.cons = SUNZILOG_CONSOLE();
 
                sunserial_current_minor += uart_count;
        }
 
-       return of_register_driver(&zs_driver, &of_bus_type);
+       err = of_register_driver(&zs_driver, &of_bus_type);
+       if (err)
+               goto out_unregister_uart;
+
+       if (zilog_irq != -1) {
+               err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED,
+                                 "zs", sunzilog_irq_chain);
+               if (err)
+                       goto out_unregister_driver;
+       }
+
+out:
+       return err;
+
+out_unregister_driver:
+       of_unregister_driver(&zs_driver);
+
+out_unregister_uart:
+       if (NUM_SUNZILOG) {
+               uart_unregister_driver(&sunzilog_reg);
+               sunzilog_reg.cons = NULL;
+       }
+
+out_free_tables:
+       sunzilog_free_tables();
+       goto out;
 }
 
 static void __exit sunzilog_exit(void)
index ceda3a2..7858703 100644 (file)
@@ -246,8 +246,8 @@ extern void xfs_buf_trace(xfs_buf_t *, char *, void *, void *);
 #define BUF_BUSY               XBF_DONT_BLOCK
 
 #define XFS_BUF_BFLAGS(bp)     ((bp)->b_flags)
-#define XFS_BUF_ZEROFLAGS(bp)  \
-       ((bp)->b_flags &= ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI))
+#define XFS_BUF_ZEROFLAGS(bp)  ((bp)->b_flags &= \
+               ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI|XBF_ORDERED))
 
 #define XFS_BUF_STALE(bp)      ((bp)->b_flags |= XFS_B_STALE)
 #define XFS_BUF_UNSTALE(bp)    ((bp)->b_flags &= ~XFS_B_STALE)
index 9bdef9d..4754f34 100644 (file)
@@ -314,6 +314,13 @@ xfs_mountfs_check_barriers(xfs_mount_t *mp)
                return;
        }
 
+       if (xfs_readonly_buftarg(mp->m_ddev_targp)) {
+               xfs_fs_cmn_err(CE_NOTE, mp,
+                 "Disabling barriers, underlying device is readonly");
+               mp->m_flags &= ~XFS_MOUNT_BARRIER;
+               return;
+       }
+
        error = xfs_barrier_test(mp);
        if (error) {
                xfs_fs_cmn_err(CE_NOTE, mp,
index e95e99f..f137856 100644 (file)
@@ -217,17 +217,24 @@ xfs_qm_statvfs(
                return 0;
        dp = &dqp->q_core;
 
-       limit = dp->d_blk_softlimit ? dp->d_blk_softlimit : dp->d_blk_hardlimit;
+       limit = dp->d_blk_softlimit ?
+               be64_to_cpu(dp->d_blk_softlimit) :
+               be64_to_cpu(dp->d_blk_hardlimit);
        if (limit && statp->f_blocks > limit) {
                statp->f_blocks = limit;
-               statp->f_bfree = (statp->f_blocks > dp->d_bcount) ?
-                                       (statp->f_blocks - dp->d_bcount) : 0;
+               statp->f_bfree =
+                       (statp->f_blocks > be64_to_cpu(dp->d_bcount)) ?
+                        (statp->f_blocks - be64_to_cpu(dp->d_bcount)) : 0;
        }
-       limit = dp->d_ino_softlimit ? dp->d_ino_softlimit : dp->d_ino_hardlimit;
+
+       limit = dp->d_ino_softlimit ?
+               be64_to_cpu(dp->d_ino_softlimit) :
+               be64_to_cpu(dp->d_ino_hardlimit);
        if (limit && statp->f_files > limit) {
                statp->f_files = limit;
-               statp->f_ffree = (statp->f_files > dp->d_icount) ?
-                                       (statp->f_ffree - dp->d_icount) : 0;
+               statp->f_ffree =
+                       (statp->f_files > be64_to_cpu(dp->d_icount)) ?
+                        (statp->f_ffree - be64_to_cpu(dp->d_icount)) : 0;
        }
 
        xfs_qm_dqput(dqp);
index 86c1bf0..1f8ecff 100644 (file)
@@ -334,10 +334,9 @@ xfs_itobp(
 #if !defined(__KERNEL__)
        ni = 0;
 #elif defined(DEBUG)
-       ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 :
-               (BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog);
+       ni = BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog;
 #else  /* usual case */
-       ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1;
+       ni = 1;
 #endif
 
        for (i = 0; i < ni; i++) {
@@ -348,11 +347,15 @@ xfs_itobp(
                                        (i << mp->m_sb.sb_inodelog));
                di_ok = INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC &&
                            XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT));
-               if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
-                                XFS_RANDOM_ITOBP_INOTOBP))) {
+               if (unlikely(XFS_TEST_ERROR(!di_ok, mp,
+                                               XFS_ERRTAG_ITOBP_INOTOBP,
+                                               XFS_RANDOM_ITOBP_INOTOBP))) {
+                       if (imap_flags & XFS_IMAP_BULKSTAT) {
+                               xfs_trans_brelse(tp, bp);
+                               return XFS_ERROR(EINVAL);
+                       }
 #ifdef DEBUG
-                       if (!(imap_flags & XFS_IMAP_BULKSTAT))
-                               cmn_err(CE_ALERT,
+                       cmn_err(CE_ALERT,
                                        "Device %s - bad inode magic/vsn "
                                        "daddr %lld #%d (magic=%x)",
                                XFS_BUFTARG_NAME(mp->m_ddev_targp),
index e730328..21ac1a6 100644 (file)
@@ -1413,7 +1413,7 @@ xlog_sync(xlog_t          *log,
        ops = iclog->ic_header.h_num_logops;
        INT_SET(iclog->ic_header.h_num_logops, ARCH_CONVERT, ops);
 
-       bp          = iclog->ic_bp;
+       bp = iclog->ic_bp;
        ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long)1);
        XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
        XFS_BUF_SET_ADDR(bp, BLOCK_LSN(INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT)));
@@ -1430,15 +1430,14 @@ xlog_sync(xlog_t                *log,
        }
        XFS_BUF_SET_PTR(bp, (xfs_caddr_t) &(iclog->ic_header), count);
        XFS_BUF_SET_FSPRIVATE(bp, iclog);       /* save for later */
+       XFS_BUF_ZEROFLAGS(bp);
        XFS_BUF_BUSY(bp);
        XFS_BUF_ASYNC(bp);
        /*
         * Do an ordered write for the log block.
-        *
-        * It may not be needed to flush the first split block in the log wrap
-        * case, but do it anyways to be safe -AK
+        * Its unnecessary to flush the first split block in the log wrap case.
         */
-       if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
+       if (!split && (log->l_mp->m_flags & XFS_MOUNT_BARRIER))
                XFS_BUF_ORDERED(bp);
 
        ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
@@ -1460,7 +1459,7 @@ xlog_sync(xlog_t          *log,
                return error;
        }
        if (split) {
-               bp              = iclog->ic_log->l_xbuf;
+               bp = iclog->ic_log->l_xbuf;
                ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) ==
                                                        (unsigned long)1);
                XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
@@ -1468,6 +1467,7 @@ xlog_sync(xlog_t          *log,
                XFS_BUF_SET_PTR(bp, (xfs_caddr_t)((__psint_t)&(iclog->ic_header)+
                                            (__psint_t)count), split);
                XFS_BUF_SET_FSPRIVATE(bp, iclog);
+               XFS_BUF_ZEROFLAGS(bp);
                XFS_BUF_BUSY(bp);
                XFS_BUF_ASYNC(bp);
                if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
index 6c96391..b427d22 100644 (file)
@@ -515,7 +515,7 @@ xfs_mount(
        if (error)
                goto error2;
 
-       if ((mp->m_flags & XFS_MOUNT_BARRIER) && !(vfsp->vfs_flag & VFS_RDONLY))
+       if (mp->m_flags & XFS_MOUNT_BARRIER)
                xfs_mountfs_check_barriers(mp);
 
        error = XFS_IOINIT(vfsp, args, flags);
index c3594f4..06caa2d 100644 (file)
@@ -244,11 +244,6 @@ extern void prom_getstring(int node, char *prop, char *buf, int bufsize);
 /* Does the passed node have the given "name"? YES=1 NO=0 */
 extern int prom_nodematch(int thisnode, char *name);
 
-/* Puts in buffer a prom name in the form name@x,y or name (x for which_io
- * and y for first regs phys address
- */
-extern int prom_getname(int node, char *buf, int buflen);
-
 /* Search all siblings starting at the passed node for "name" matching
  * the given string.  Returns the node on success, zero on failure.
  */
index 36a3a85..1604004 100644 (file)
@@ -128,8 +128,13 @@ extern void account_system_vtime(struct task_struct *);
 
 #define nop() __asm__ __volatile__ ("nop")
 
-#define xchg(ptr,x) \
-  ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(void *)(ptr),sizeof(*(ptr))))
+#define xchg(ptr,x)                                                      \
+({                                                                       \
+       __typeof__(*(ptr)) __ret;                                         \
+       __ret = (__typeof__(*(ptr)))                                      \
+               __xchg((unsigned long)(x), (void *)(ptr),sizeof(*(ptr))); \
+       __ret;                                                            \
+})
 
 static inline unsigned long __xchg(unsigned long x, void * ptr, int size)
 {
index 4848057..5d0332a 100644 (file)
@@ -19,7 +19,7 @@ static inline cycles_t get_cycles(void)
 {
        cycles_t cycles;
 
-       __asm__("stck 0(%1)" : "=m" (cycles) : "a" (&cycles) : "cc");
+       __asm__ __volatile__ ("stck 0(%1)" : "=m" (cycles) : "a" (&cycles) : "cc");
        return cycles >> 2;
 }
 
@@ -27,7 +27,7 @@ static inline unsigned long long get_clock (void)
 {
        unsigned long long clk;
 
-       __asm__("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc");
+       __asm__ __volatile__ ("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc");
        return clk;
 }
 
index f283f8a..91691e5 100644 (file)
@@ -267,11 +267,6 @@ extern void prom_getstring(int node, char *prop, char *buf, int bufsize);
 /* Does the passed node have the given "name"? YES=1 NO=0 */
 extern int prom_nodematch(int thisnode, char *name);
 
-/* Puts in buffer a prom name in the form name@x,y or name (x for which_io 
- * and y for first regs phys address
- */
-extern int prom_getname(int node, char *buf, int buflen);
-
 /* Search all siblings starting at the passed node for "name" matching
  * the given string.  Returns the node on success, zero on failure.
  */
index 0ae5084..d03a21c 100644 (file)
@@ -168,7 +168,7 @@ struct sigstack {
  * statically allocated data.. which is NOT GOOD.
  *
  */
-#define SA_STATIC_ALLOC                0x80
+#define SA_STATIC_ALLOC                0x8000
 #endif
 
 #include <asm-generic/signal.h>
index b4959d2..e01b805 100644 (file)
@@ -175,7 +175,7 @@ struct linux_nodeops {
 };
 
 /* More fun PROM structures for device probing. */
-#define PROMREG_MAX     16
+#define PROMREG_MAX     24
 #define PROMVADDR_MAX   16
 #define PROMINTR_MAX    15
 
index a68b0bb..6a0da3b 100644 (file)
@@ -287,11 +287,6 @@ extern void prom_getstring(int node, const char *prop, char *buf, int bufsize);
 /* Does the passed node have the given "name"? YES=1 NO=0 */
 extern int prom_nodematch(int thisnode, const char *name);
 
-/* Puts in buffer a prom name in the form name@x,y or name (x for which_io 
- * and y for first regs phys address
- */
-extern int prom_getname(int node, char *buf, int buflen);
-
 /* Search all siblings starting at the passed node for "name" matching
  * the given string.  Returns the node on success, zero on failure.
  */
index 03f5bc9..1ba19eb 100644 (file)
@@ -339,7 +339,7 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot)
        "       .section        .sun4v_2insn_patch, \"ax\"\n"
        "       .word           661b\n"
        "       andn            %0, %4, %0\n"
-       "       or              %0, %3, %0\n"
+       "       or              %0, %5, %0\n"
        "       .previous\n"
        : "=r" (val)
        : "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U),
index 5015bb8..89d4243 100644 (file)
@@ -34,7 +34,7 @@
 #define _FP_MUL_MEAT_D(R,X,Y)                                  \
   _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
 #define _FP_MUL_MEAT_Q(R,X,Y)                                  \
-  _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
 
 #define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
 #define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
index f7bf875..10f3461 100644 (file)
@@ -19,7 +19,7 @@
 #define EXCEPTION_STACK_ORDER 0
 #define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
 
-#define DEBUG_STACK_ORDER EXCEPTION_STACK_ORDER
+#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1)
 #define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER)
 
 #define IRQSTACK_ORDER 2
index 44a11f1..8fb344a 100644 (file)
@@ -48,7 +48,6 @@ static inline void unregister_cpu_notifier(struct notifier_block *nb)
 {
 }
 #endif
-extern int current_in_cpu_hotplug(void);
 
 int cpu_up(unsigned int cpu);
 
@@ -61,10 +60,6 @@ static inline int register_cpu_notifier(struct notifier_block *nb)
 static inline void unregister_cpu_notifier(struct notifier_block *nb)
 {
 }
-static inline int current_in_cpu_hotplug(void)
-{
-       return 0;
-}
 
 #endif /* CONFIG_SMP */
 extern struct sysdev_class cpu_sysdev_class;
@@ -73,7 +68,6 @@ extern struct sysdev_class cpu_sysdev_class;
 /* Stop CPUs going up and down. */
 extern void lock_cpu_hotplug(void);
 extern void unlock_cpu_hotplug(void);
-extern int lock_cpu_hotplug_interruptible(void);
 #define hotcpu_notifier(fn, pri) {                             \
        static struct notifier_block fn##_nb =                  \
                { .notifier_call = fn, .priority = pri };       \
index 35e1376..4ea39fe 100644 (file)
@@ -172,9 +172,6 @@ extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
                                   unsigned int relation);
 
 
-/* pass an event to the cpufreq governor */
-int cpufreq_governor(unsigned int cpu, unsigned int event);
-
 int cpufreq_register_governor(struct cpufreq_governor *governor);
 void cpufreq_unregister_governor(struct cpufreq_governor *governor);
 
index 34c3a21..d097b5b 100644 (file)
@@ -96,7 +96,8 @@ struct robust_list_head {
 long do_futex(u32 __user *uaddr, int op, u32 val, unsigned long timeout,
              u32 __user *uaddr2, u32 val2, u32 val3);
 
-extern int handle_futex_death(u32 __user *uaddr, struct task_struct *curr);
+extern int
+handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi);
 
 #ifdef CONFIG_FUTEX
 extern void exit_robust_list(struct task_struct *curr);
index dc7abef..9962045 100644 (file)
@@ -571,6 +571,7 @@ typedef struct ide_drive_s {
        u8      waiting_for_dma;        /* dma currently in progress */
        u8      unmask;                 /* okay to unmask other irqs */
        u8      bswap;                  /* byte swap data */
+       u8      noflush;                /* don't attempt flushes */
        u8      dsc_overlap;            /* DSC overlap */
        u8      nice1;                  /* give potential excess bandwidth */
 
index 76cc099..75f02d8 100644 (file)
@@ -924,10 +924,10 @@ static inline void netif_tx_lock_bh(struct net_device *dev)
 
 static inline int netif_tx_trylock(struct net_device *dev)
 {
-       int err = spin_trylock(&dev->_xmit_lock);
-       if (!err)
+       int ok = spin_trylock(&dev->_xmit_lock);
+       if (likely(ok))
                dev->xmit_lock_owner = smp_processor_id();
-       return err;
+       return ok;
 }
 
 static inline void netif_tx_unlock(struct net_device *dev)
index 8776402..31f02ba 100644 (file)
@@ -79,6 +79,8 @@ struct bridge_skb_cb {
                __u32 ipv4;
        } daddr;
 };
+
+extern int brnf_deferred_hooks;
 #endif /* CONFIG_BRIDGE_NETFILTER */
 
 #endif /* __KERNEL__ */
index 0bf31b8..4307e76 100644 (file)
@@ -1066,9 +1066,8 @@ static inline void __skb_queue_purge(struct sk_buff_head *list)
                kfree_skb(skb);
 }
 
-#ifndef CONFIG_HAVE_ARCH_DEV_ALLOC_SKB
 /**
- *     __dev_alloc_skb - allocate an skbuff for sending
+ *     __dev_alloc_skb - allocate an skbuff for receiving
  *     @length: length to allocate
  *     @gfp_mask: get_free_pages mask, passed to alloc_skb
  *
@@ -1087,12 +1086,9 @@ static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
                skb_reserve(skb, NET_SKB_PAD);
        return skb;
 }
-#else
-extern struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask);
-#endif
 
 /**
- *     dev_alloc_skb - allocate an skbuff for sending
+ *     dev_alloc_skb - allocate an skbuff for receiving
  *     @length: length to allocate
  *
  *     Allocate a new &sk_buff and assign it a usage count of one. The
index 19760eb..ceae5ee 100644 (file)
@@ -37,7 +37,7 @@ static inline struct dma_chan *get_softnet_dma(void)
 }
 
 int dma_skb_copy_datagram_iovec(struct dma_chan* chan,
-               const struct sk_buff *skb, int offset, struct iovec *to,
+               struct sk_buff *skb, int offset, struct iovec *to,
                size_t len, struct dma_pinned_list *pinned_list);
 
 #endif /* CONFIG_NET_DMA */
index 1925c65..f6afee7 100644 (file)
@@ -169,23 +169,17 @@ psched_tod_diff(int delta_sec, int bound)
 
 #define PSCHED_TADD2(tv, delta, tv_res) \
 ({ \
-          int __delta = (delta); \
-          (tv_res) = (tv); \
-          while(__delta >= USEC_PER_SEC){ \
-                (tv_res).tv_sec++; \
-                __delta -= USEC_PER_SEC; \
-          } \
+          int __delta = (tv).tv_usec + (delta); \
+          (tv_res).tv_sec = (tv).tv_sec; \
+          while (__delta >= USEC_PER_SEC) { (tv_res).tv_sec++; __delta -= USEC_PER_SEC; } \
           (tv_res).tv_usec = __delta; \
 })
 
 #define PSCHED_TADD(tv, delta) \
 ({ \
-          int __delta = (delta); \
-          while(__delta >= USEC_PER_SEC){ \
-                (tv).tv_sec++; \
-                __delta -= USEC_PER_SEC; \
-          } \
-          (tv).tv_usec = __delta; \
+          (tv).tv_usec += (delta); \
+          while ((tv).tv_usec >= USEC_PER_SEC) { (tv).tv_sec++; \
+                (tv).tv_usec -= USEC_PER_SEC; } \
 })
 
 /* Set/check that time is in the "past perfect";
index 5f69158..e5aa7ff 100644 (file)
@@ -445,6 +445,7 @@ typedef struct sctp_sender_hb_info {
        struct sctp_paramhdr param_hdr;
        union sctp_addr daddr;
        unsigned long sent_at;
+       __u64 hb_nonce;
 } __attribute__((packed)) sctp_sender_hb_info_t;
 
 /*
@@ -730,13 +731,10 @@ void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *,
 const union sctp_addr *sctp_source(const struct sctp_chunk *chunk);
 
 /* This is a structure for holding either an IPv6 or an IPv4 address.  */
-/* sin_family -- AF_INET or AF_INET6
- * sin_port -- ordinary port number
- * sin_addr -- cast to either (struct in_addr) or (struct in6_addr)
- */
 struct sctp_sockaddr_entry {
        struct list_head list;
        union sctp_addr a;
+       __u8 use_as_src;
 };
 
 typedef struct sctp_chunk *(sctp_packet_phandler_t)(struct sctp_association *);
@@ -984,6 +982,9 @@ struct sctp_transport {
                 */
                char cacc_saw_newack;
        } cacc;
+
+       /* 64-bit random number sent with heartbeat. */
+       __u64 hb_nonce;
 };
 
 struct sctp_transport *sctp_transport_new(const union sctp_addr *,
@@ -1138,7 +1139,7 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
                        sctp_scope_t scope, gfp_t gfp,
                        int flags);
 int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
-                      gfp_t gfp);
+                      __u8 use_as_src, gfp_t gfp);
 int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
 int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *,
                         struct sctp_sock *);
index 8a6bef6..1b7aae6 100644 (file)
@@ -560,9 +560,18 @@ struct sctp_paddrinfo {
 } __attribute__((packed, aligned(4)));
 
 /* Peer addresses's state. */
+/* UNKNOWN: Peer address passed by the upper layer in sendmsg or connect[x]
+ * calls.
+ * UNCONFIRMED: Peer address received in INIT/INIT-ACK address parameters.
+ *              Not yet confirmed by a heartbeat and not available for data
+ *             transfers.
+ * ACTIVE : Peer address confirmed, active and available for data transfers.
+ * INACTIVE: Peer address inactive and not available for data transfers.
+ */
 enum sctp_spinfo_state {
        SCTP_INACTIVE,
        SCTP_ACTIVE,
+       SCTP_UNCONFIRMED,
        SCTP_UNKNOWN = 0xffff  /* Value used for transport state unknown */
 };
 
index 5ff7755..585d28e 100644 (file)
@@ -75,6 +75,7 @@
 #define IB_MGMT_METHOD_TRAP_REPRESS            0x07
 
 #define IB_MGMT_METHOD_RESP                    0x80
+#define IB_BM_ATTR_MOD_RESP                    cpu_to_be32(1)
 
 #define IB_MGMT_MAX_METHODS                    128
 
@@ -247,6 +248,12 @@ struct ib_mad_send_buf {
 };
 
 /**
+ * ib_response_mad - Returns if the specified MAD has been generated in
+ *   response to a sent request or trap.
+ */
+int ib_response_mad(struct ib_mad *mad);
+
+/**
  * ib_get_rmpp_resptime - Returns the RMPP response time.
  * @rmpp_hdr: An RMPP header.
  */
index 371f70d..58e6444 100644 (file)
@@ -58,9 +58,7 @@ struct scsi_cmnd {
        int timeout_per_command;
 
        unsigned char cmd_len;
-       unsigned char old_cmd_len;
        enum dma_data_direction sc_data_direction;
-       enum dma_data_direction sc_old_data_direction;
 
        /* These elements define the operation we are about to perform */
 #define MAX_COMMAND_SIZE       16
@@ -71,18 +69,11 @@ struct scsi_cmnd {
        void *request_buffer;           /* Actual requested buffer */
 
        /* These elements define the operation we ultimately want to perform */
-       unsigned char data_cmnd[MAX_COMMAND_SIZE];
-       unsigned short old_use_sg;      /* We save  use_sg here when requesting
-                                        * sense info */
        unsigned short use_sg;  /* Number of pieces of scatter-gather */
        unsigned short sglist_len;      /* size of malloc'd scatter-gather list */
-       unsigned bufflen;       /* Size of data buffer */
-       void *buffer;           /* Data buffer */
 
        unsigned underflow;     /* Return error if less than
                                   this amount is transferred */
-       unsigned old_underflow; /* save underflow here when reusing the
-                                * command for error handling */
 
        unsigned transfersize;  /* How much we are guaranteed to
                                   transfer with each SCSI transfer
index e3c503c..6cc2314 100644 (file)
@@ -106,6 +106,7 @@ struct sas_end_device {
 
 struct sas_expander_device {
        int    level;
+       int    next_port_id;
 
        #define SAS_EXPANDER_VENDOR_ID_LEN      8
        char   vendor_id[SAS_EXPANDER_VENDOR_ID_LEN+1];
@@ -127,8 +128,10 @@ struct sas_expander_device {
 struct sas_port {
        struct device           dev;
 
-       u8                      port_identifier;
+       int                     port_identifier;
        int                     num_phys;
+       /* port flags */
+       unsigned int            is_backlink:1;
 
        /* the other end of the link */
        struct sas_rphy         *rphy;
@@ -168,11 +171,13 @@ extern void sas_rphy_delete(struct sas_rphy *);
 extern int scsi_is_sas_rphy(const struct device *);
 
 struct sas_port *sas_port_alloc(struct device *, int);
+struct sas_port *sas_port_alloc_num(struct device *);
 int sas_port_add(struct sas_port *);
 void sas_port_free(struct sas_port *);
 void sas_port_delete(struct sas_port *);
 void sas_port_add_phy(struct sas_port *, struct sas_phy *);
 void sas_port_delete_phy(struct sas_port *, struct sas_phy *);
+void sas_port_mark_backlink(struct sas_port *);
 int scsi_is_sas_port(const struct device *);
 
 extern struct scsi_transport_template *
index 70fbf2e..f230f9a 100644 (file)
 #include <linux/mutex.h>
 
 /* This protects CPUs going up and down... */
-static DEFINE_MUTEX(cpucontrol);
+static DEFINE_MUTEX(cpu_add_remove_lock);
+static DEFINE_MUTEX(cpu_bitmask_lock);
 
 static __cpuinitdata BLOCKING_NOTIFIER_HEAD(cpu_chain);
 
 #ifdef CONFIG_HOTPLUG_CPU
-static struct task_struct *lock_cpu_hotplug_owner;
-static int lock_cpu_hotplug_depth;
 
-static int __lock_cpu_hotplug(int interruptible)
-{
-       int ret = 0;
-
-       if (lock_cpu_hotplug_owner != current) {
-               if (interruptible)
-                       ret = mutex_lock_interruptible(&cpucontrol);
-               else
-                       mutex_lock(&cpucontrol);
-       }
-
-       /*
-        * Set only if we succeed in locking
-        */
-       if (!ret) {
-               lock_cpu_hotplug_depth++;
-               lock_cpu_hotplug_owner = current;
-       }
-
-       return ret;
-}
+/* Crappy recursive lock-takers in cpufreq! Complain loudly about idiots */
+static struct task_struct *recursive;
+static int recursive_depth;
 
 void lock_cpu_hotplug(void)
 {
-       __lock_cpu_hotplug(0);
+       struct task_struct *tsk = current;
+
+       if (tsk == recursive) {
+               static int warnings = 10;
+               if (warnings) {
+                       printk(KERN_ERR "Lukewarm IQ detected in hotplug locking\n");
+                       WARN_ON(1);
+                       warnings--;
+               }
+               recursive_depth++;
+               return;
+       }
+       mutex_lock(&cpu_bitmask_lock);
+       recursive = tsk;
 }
 EXPORT_SYMBOL_GPL(lock_cpu_hotplug);
 
 void unlock_cpu_hotplug(void)
 {
-       if (--lock_cpu_hotplug_depth == 0) {
-               lock_cpu_hotplug_owner = NULL;
-               mutex_unlock(&cpucontrol);
+       WARN_ON(recursive != current);
+       if (recursive_depth) {
+               recursive_depth--;
+               return;
        }
+       mutex_unlock(&cpu_bitmask_lock);
+       recursive = NULL;
 }
 EXPORT_SYMBOL_GPL(unlock_cpu_hotplug);
 
-int lock_cpu_hotplug_interruptible(void)
-{
-       return __lock_cpu_hotplug(1);
-}
-EXPORT_SYMBOL_GPL(lock_cpu_hotplug_interruptible);
 #endif /* CONFIG_HOTPLUG_CPU */
 
 /* Need to know about CPUs going up/down? */
@@ -122,9 +114,7 @@ int cpu_down(unsigned int cpu)
        struct task_struct *p;
        cpumask_t old_allowed, tmp;
 
-       if ((err = lock_cpu_hotplug_interruptible()) != 0)
-               return err;
-
+       mutex_lock(&cpu_add_remove_lock);
        if (num_online_cpus() == 1) {
                err = -EBUSY;
                goto out;
@@ -150,7 +140,10 @@ int cpu_down(unsigned int cpu)
        cpu_clear(cpu, tmp);
        set_cpus_allowed(current, tmp);
 
+       mutex_lock(&cpu_bitmask_lock);
        p = __stop_machine_run(take_cpu_down, NULL, cpu);
+       mutex_unlock(&cpu_bitmask_lock);
+
        if (IS_ERR(p)) {
                /* CPU didn't die: tell everyone.  Can't complain. */
                if (blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED,
@@ -187,7 +180,7 @@ out_thread:
 out_allowed:
        set_cpus_allowed(current, old_allowed);
 out:
-       unlock_cpu_hotplug();
+       mutex_unlock(&cpu_add_remove_lock);
        return err;
 }
 #endif /*CONFIG_HOTPLUG_CPU*/
@@ -197,9 +190,7 @@ int __devinit cpu_up(unsigned int cpu)
        int ret;
        void *hcpu = (void *)(long)cpu;
 
-       if ((ret = lock_cpu_hotplug_interruptible()) != 0)
-               return ret;
-
+       mutex_lock(&cpu_add_remove_lock);
        if (cpu_online(cpu) || !cpu_present(cpu)) {
                ret = -EINVAL;
                goto out;
@@ -214,7 +205,9 @@ int __devinit cpu_up(unsigned int cpu)
        }
 
        /* Arch-specific enabling code. */
+       mutex_lock(&cpu_bitmask_lock);
        ret = __cpu_up(cpu);
+       mutex_unlock(&cpu_bitmask_lock);
        if (ret != 0)
                goto out_notify;
        BUG_ON(!cpu_online(cpu));
@@ -227,6 +220,6 @@ out_notify:
                blocking_notifier_call_chain(&cpu_chain,
                                CPU_UP_CANCELED, hcpu);
 out:
-       unlock_cpu_hotplug();
+       mutex_unlock(&cpu_add_remove_lock);
        return ret;
 }
index c232dc0..1a649f2 100644 (file)
@@ -762,6 +762,8 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
  *
  * Call with manage_mutex held.  May nest a call to the
  * lock_cpu_hotplug()/unlock_cpu_hotplug() pair.
+ * Must not be called holding callback_mutex, because we must
+ * not call lock_cpu_hotplug() while holding callback_mutex.
  */
 
 static void update_cpu_domains(struct cpuset *cur)
@@ -781,7 +783,7 @@ static void update_cpu_domains(struct cpuset *cur)
                if (is_cpu_exclusive(c))
                        cpus_andnot(pspan, pspan, c->cpus_allowed);
        }
-       if (is_removed(cur) || !is_cpu_exclusive(cur)) {
+       if (!is_cpu_exclusive(cur)) {
                cpus_or(pspan, pspan, cur->cpus_allowed);
                if (cpus_equal(pspan, cur->cpus_allowed))
                        return;
@@ -1917,6 +1919,17 @@ static int cpuset_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        return cpuset_create(c_parent, dentry->d_name.name, mode | S_IFDIR);
 }
 
+/*
+ * Locking note on the strange update_flag() call below:
+ *
+ * If the cpuset being removed is marked cpu_exclusive, then simulate
+ * turning cpu_exclusive off, which will call update_cpu_domains().
+ * The lock_cpu_hotplug() call in update_cpu_domains() must not be
+ * made while holding callback_mutex.  Elsewhere the kernel nests
+ * callback_mutex inside lock_cpu_hotplug() calls.  So the reverse
+ * nesting would risk an ABBA deadlock.
+ */
+
 static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
 {
        struct cpuset *cs = dentry->d_fsdata;
@@ -1936,11 +1949,16 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
                mutex_unlock(&manage_mutex);
                return -EBUSY;
        }
+       if (is_cpu_exclusive(cs)) {
+               int retval = update_flag(CS_CPU_EXCLUSIVE, cs, "0");
+               if (retval < 0) {
+                       mutex_unlock(&manage_mutex);
+                       return retval;
+               }
+       }
        parent = cs->parent;
        mutex_lock(&callback_mutex);
        set_bit(CS_REMOVED, &cs->flags);
-       if (is_cpu_exclusive(cs))
-               update_cpu_domains(cs);
        list_del(&cs->sibling); /* delete my sibling from parent->children */
        spin_lock(&cs->dentry->d_lock);
        d = dget(cs->dentry);
index cf0c8e2..dda2049 100644 (file)
@@ -415,15 +415,15 @@ out_unlock:
  */
 void exit_pi_state_list(struct task_struct *curr)
 {
-       struct futex_hash_bucket *hb;
        struct list_head *next, *head = &curr->pi_state_list;
        struct futex_pi_state *pi_state;
+       struct futex_hash_bucket *hb;
        union futex_key key;
 
        /*
         * We are a ZOMBIE and nobody can enqueue itself on
         * pi_state_list anymore, but we have to be careful
-        * versus waiters unqueueing themselfs
+        * versus waiters unqueueing themselves:
         */
        spin_lock_irq(&curr->pi_lock);
        while (!list_empty(head)) {
@@ -431,21 +431,24 @@ void exit_pi_state_list(struct task_struct *curr)
                next = head->next;
                pi_state = list_entry(next, struct futex_pi_state, list);
                key = pi_state->key;
+               hb = hash_futex(&key);
                spin_unlock_irq(&curr->pi_lock);
 
-               hb = hash_futex(&key);
                spin_lock(&hb->lock);
 
                spin_lock_irq(&curr->pi_lock);
+               /*
+                * We dropped the pi-lock, so re-check whether this
+                * task still owns the PI-state:
+                */
                if (head->next != next) {
                        spin_unlock(&hb->lock);
                        continue;
                }
 
-               list_del_init(&pi_state->list);
-
                WARN_ON(pi_state->owner != curr);
-
+               WARN_ON(list_empty(&pi_state->list));
+               list_del_init(&pi_state->list);
                pi_state->owner = NULL;
                spin_unlock_irq(&curr->pi_lock);
 
@@ -470,7 +473,7 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, struct futex_q *me)
        head = &hb->chain;
 
        list_for_each_entry_safe(this, next, head, list) {
-               if (match_futex (&this->key, &me->key)) {
+               if (match_futex(&this->key, &me->key)) {
                        /*
                         * Another waiter already exists - bump up
                         * the refcount and return its pi_state:
@@ -482,6 +485,8 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, struct futex_q *me)
                        if (unlikely(!pi_state))
                                return -EINVAL;
 
+                       WARN_ON(!atomic_read(&pi_state->refcount));
+
                        atomic_inc(&pi_state->refcount);
                        me->pi_state = pi_state;
 
@@ -490,10 +495,13 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, struct futex_q *me)
        }
 
        /*
-        * We are the first waiter - try to look up the real owner and
-        * attach the new pi_state to it:
+        * We are the first waiter - try to look up the real owner and attach
+        * the new pi_state to it, but bail out when the owner died bit is set
+        * and TID = 0:
         */
        pid = uval & FUTEX_TID_MASK;
+       if (!pid && (uval & FUTEX_OWNER_DIED))
+               return -ESRCH;
        p = futex_find_get_task(pid);
        if (!p)
                return -ESRCH;
@@ -510,6 +518,7 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, struct futex_q *me)
        pi_state->key = me->key;
 
        spin_lock_irq(&p->pi_lock);
+       WARN_ON(!list_empty(&pi_state->list));
        list_add(&pi_state->list, &p->pi_state_list);
        pi_state->owner = p;
        spin_unlock_irq(&p->pi_lock);
@@ -573,20 +582,29 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
         * kept enabled while there is PI state around. We must also
         * preserve the owner died bit.)
         */
-       newval = (uval & FUTEX_OWNER_DIED) | FUTEX_WAITERS | new_owner->pid;
+       if (!(uval & FUTEX_OWNER_DIED)) {
+               newval = FUTEX_WAITERS | new_owner->pid;
 
-       inc_preempt_count();
-       curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval);
-       dec_preempt_count();
+               inc_preempt_count();
+               curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval);
+               dec_preempt_count();
+               if (curval == -EFAULT)
+                       return -EFAULT;
+               if (curval != uval)
+                       return -EINVAL;
+       }
 
-       if (curval == -EFAULT)
-               return -EFAULT;
-       if (curval != uval)
-               return -EINVAL;
+       spin_lock_irq(&pi_state->owner->pi_lock);
+       WARN_ON(list_empty(&pi_state->list));
+       list_del_init(&pi_state->list);
+       spin_unlock_irq(&pi_state->owner->pi_lock);
 
-       list_del_init(&pi_state->owner->pi_state_list);
+       spin_lock_irq(&new_owner->pi_lock);
+       WARN_ON(!list_empty(&pi_state->list));
        list_add(&pi_state->list, &new_owner->pi_state_list);
        pi_state->owner = new_owner;
+       spin_unlock_irq(&new_owner->pi_lock);
+
        rt_mutex_unlock(&pi_state->pi_mutex);
 
        return 0;
@@ -1236,6 +1254,7 @@ static int do_futex_lock_pi(u32 __user *uaddr, int detect, int trylock,
                /* Owner died? */
                if (q.pi_state->owner != NULL) {
                        spin_lock_irq(&q.pi_state->owner->pi_lock);
+                       WARN_ON(list_empty(&q.pi_state->list));
                        list_del_init(&q.pi_state->list);
                        spin_unlock_irq(&q.pi_state->owner->pi_lock);
                } else
@@ -1244,6 +1263,7 @@ static int do_futex_lock_pi(u32 __user *uaddr, int detect, int trylock,
                q.pi_state->owner = current;
 
                spin_lock_irq(&current->pi_lock);
+               WARN_ON(!list_empty(&q.pi_state->list));
                list_add(&q.pi_state->list, &current->pi_state_list);
                spin_unlock_irq(&current->pi_lock);
 
@@ -1427,9 +1447,11 @@ retry_locked:
         * again. If it succeeds then we can return without waking
         * anyone else up:
         */
-       inc_preempt_count();
-       uval = futex_atomic_cmpxchg_inatomic(uaddr, current->pid, 0);
-       dec_preempt_count();
+       if (!(uval & FUTEX_OWNER_DIED)) {
+               inc_preempt_count();
+               uval = futex_atomic_cmpxchg_inatomic(uaddr, current->pid, 0);
+               dec_preempt_count();
+       }
 
        if (unlikely(uval == -EFAULT))
                goto pi_faulted;
@@ -1462,9 +1484,11 @@ retry_locked:
        /*
         * No waiters - kernel unlocks the futex:
         */
-       ret = unlock_futex_pi(uaddr, uval);
-       if (ret == -EFAULT)
-               goto pi_faulted;
+       if (!(uval & FUTEX_OWNER_DIED)) {
+               ret = unlock_futex_pi(uaddr, uval);
+               if (ret == -EFAULT)
+                       goto pi_faulted;
+       }
 
 out_unlock:
        spin_unlock(&hb->lock);
@@ -1683,9 +1707,9 @@ err_unlock:
  * Process a futex-list entry, check whether it's owned by the
  * dying task, and do notification if so:
  */
-int handle_futex_death(u32 __user *uaddr, struct task_struct *curr)
+int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi)
 {
-       u32 uval, nval;
+       u32 uval, nval, mval;
 
 retry:
        if (get_user(uval, uaddr))
@@ -1702,21 +1726,45 @@ retry:
                 * thread-death.) The rest of the cleanup is done in
                 * userspace.
                 */
-               nval = futex_atomic_cmpxchg_inatomic(uaddr, uval,
-                                                    uval | FUTEX_OWNER_DIED);
+               mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED;
+               nval = futex_atomic_cmpxchg_inatomic(uaddr, uval, mval);
+
                if (nval == -EFAULT)
                        return -1;
 
                if (nval != uval)
                        goto retry;
 
-               if (uval & FUTEX_WAITERS)
-                       futex_wake(uaddr, 1);
+               /*
+                * Wake robust non-PI futexes here. The wakeup of
+                * PI futexes happens in exit_pi_state():
+                */
+               if (!pi) {
+                       if (uval & FUTEX_WAITERS)
+                               futex_wake(uaddr, 1);
+               }
        }
        return 0;
 }
 
 /*
+ * Fetch a robust-list pointer. Bit 0 signals PI futexes:
+ */
+static inline int fetch_robust_entry(struct robust_list __user **entry,
+                                    struct robust_list __user **head, int *pi)
+{
+       unsigned long uentry;
+
+       if (get_user(uentry, (unsigned long *)head))
+               return -EFAULT;
+
+       *entry = (void *)(uentry & ~1UL);
+       *pi = uentry & 1;
+
+       return 0;
+}
+
+/*
  * Walk curr->robust_list (very carefully, it's a userspace list!)
  * and mark any locks found there dead, and notify any waiters.
  *
@@ -1726,14 +1774,14 @@ void exit_robust_list(struct task_struct *curr)
 {
        struct robust_list_head __user *head = curr->robust_list;
        struct robust_list __user *entry, *pending;
-       unsigned int limit = ROBUST_LIST_LIMIT;
+       unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
        unsigned long futex_offset;
 
        /*
         * Fetch the list head (which was registered earlier, via
         * sys_set_robust_list()):
         */
-       if (get_user(entry, &head->list.next))
+       if (fetch_robust_entry(&entry, &head->list.next, &pi))
                return;
        /*
         * Fetch the relative futex offset:
@@ -1744,10 +1792,11 @@ void exit_robust_list(struct task_struct *curr)
         * Fetch any possibly pending lock-add first, and handle it
         * if it exists:
         */
-       if (get_user(pending, &head->list_op_pending))
+       if (fetch_robust_entry(&pending, &head->list_op_pending, &pip))
                return;
+
        if (pending)
-               handle_futex_death((void *)pending + futex_offset, curr);
+               handle_futex_death((void *)pending + futex_offset, curr, pip);
 
        while (entry != &head->list) {
                /*
@@ -1756,12 +1805,12 @@ void exit_robust_list(struct task_struct *curr)
                 */
                if (entry != pending)
                        if (handle_futex_death((void *)entry + futex_offset,
-                                               curr))
+                                               curr, pi))
                                return;
                /*
                 * Fetch the next entry in the list:
                 */
-               if (get_user(entry, &entry->next))
+               if (fetch_robust_entry(&entry, &entry->next, &pi))
                        return;
                /*
                 * Avoid excessively long or circular lists:
index d1d92b4..d1aab1a 100644 (file)
 
 #include <asm/uaccess.h>
 
+
+/*
+ * Fetch a robust-list pointer. Bit 0 signals PI futexes:
+ */
+static inline int
+fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry,
+                  compat_uptr_t *head, int *pi)
+{
+       if (get_user(*uentry, head))
+               return -EFAULT;
+
+       *entry = compat_ptr((*uentry) & ~1);
+       *pi = (unsigned int)(*uentry) & 1;
+
+       return 0;
+}
+
 /*
  * Walk curr->robust_list (very carefully, it's a userspace list!)
  * and mark any locks found there dead, and notify any waiters.
@@ -22,17 +39,16 @@ void compat_exit_robust_list(struct task_struct *curr)
 {
        struct compat_robust_list_head __user *head = curr->compat_robust_list;
        struct robust_list __user *entry, *pending;
+       unsigned int limit = ROBUST_LIST_LIMIT, pi;
        compat_uptr_t uentry, upending;
-       unsigned int limit = ROBUST_LIST_LIMIT;
        compat_long_t futex_offset;
 
        /*
         * Fetch the list head (which was registered earlier, via
         * sys_set_robust_list()):
         */
-       if (get_user(uentry, &head->list.next))
+       if (fetch_robust_entry(&uentry, &entry, &head->list.next, &pi))
                return;
-       entry = compat_ptr(uentry);
        /*
         * Fetch the relative futex offset:
         */
@@ -42,11 +58,11 @@ void compat_exit_robust_list(struct task_struct *curr)
         * Fetch any possibly pending lock-add first, and handle it
         * if it exists:
         */
-       if (get_user(upending, &head->list_op_pending))
+       if (fetch_robust_entry(&upending, &pending,
+                              &head->list_op_pending, &pi))
                return;
-       pending = compat_ptr(upending);
        if (upending)
-               handle_futex_death((void *)pending + futex_offset, curr);
+               handle_futex_death((void *)pending + futex_offset, curr, pi);
 
        while (compat_ptr(uentry) != &head->list) {
                /*
@@ -55,15 +71,15 @@ void compat_exit_robust_list(struct task_struct *curr)
                 */
                if (entry != pending)
                        if (handle_futex_death((void *)entry + futex_offset,
-                                               curr))
+                                               curr, pi))
                                return;
 
                /*
                 * Fetch the next entry in the list:
                 */
-               if (get_user(uentry, (compat_uptr_t *)&entry->next))
+               if (fetch_robust_entry(&uentry, &entry,
+                                      (compat_uptr_t *)&entry->next, &pi))
                        return;
-               entry = compat_ptr(uentry);
                /*
                 * Avoid excessively long or circular lists:
                 */
index 458031b..18fcb9f 100644 (file)
@@ -67,10 +67,6 @@ static struct packet_type vlan_packet_type = {
        .func = vlan_skb_recv, /* VLAN receive method */
 };
 
-/* Bits of netdev state that are propagated from real device to virtual */
-#define VLAN_LINK_STATE_MASK \
-       ((1<<__LINK_STATE_PRESENT)|(1<<__LINK_STATE_NOCARRIER)|(1<<__LINK_STATE_DORMANT))
-
 /* End of global variables definitions. */
 
 /*
@@ -479,7 +475,9 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
        new_dev->flags = real_dev->flags;
        new_dev->flags &= ~IFF_UP;
 
-       new_dev->state = real_dev->state & ~(1<<__LINK_STATE_START);
+       new_dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) |
+                                            (1<<__LINK_STATE_DORMANT))) |
+                        (1<<__LINK_STATE_PRESENT); 
 
        /* need 4 bytes for extra VLAN header info,
         * hope the underlying device can handle it.
@@ -542,12 +540,11 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
         * so it cannot "appear" on us.
         */
        if (!grp) { /* need to add a new group */
-               grp = kmalloc(sizeof(struct vlan_group), GFP_KERNEL);
+               grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL);
                if (!grp)
                        goto out_free_unregister;
                                        
                /* printk(KERN_ALERT "VLAN REGISTER:  Allocated new group.\n"); */
-               memset(grp, 0, sizeof(struct vlan_group));
                grp->real_dev_ifindex = real_dev->ifindex;
 
                hlist_add_head_rcu(&grp->hlist, 
index 5ee96d4..96dc6bb 100644 (file)
@@ -227,12 +227,11 @@ static void atif_drop_device(struct net_device *dev)
 static struct atalk_iface *atif_add_device(struct net_device *dev,
                                           struct atalk_addr *sa)
 {
-       struct atalk_iface *iface = kmalloc(sizeof(*iface), GFP_KERNEL);
+       struct atalk_iface *iface = kzalloc(sizeof(*iface), GFP_KERNEL);
 
        if (!iface)
                goto out;
 
-       memset(iface, 0, sizeof(*iface));
        dev_hold(dev);
        iface->dev = dev;
        dev->atalk_ptr = iface;
@@ -559,12 +558,11 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint)
        }
 
        if (!rt) {
-               rt = kmalloc(sizeof(*rt), GFP_ATOMIC);
+               rt = kzalloc(sizeof(*rt), GFP_ATOMIC);
 
                retval = -ENOBUFS;
                if (!rt)
                        goto out_unlock;
-               memset(rt, 0, sizeof(*rt));
 
                rt->next = atalk_routes;
                atalk_routes = rt;
index a487233..d00cca9 100644 (file)
@@ -508,10 +508,9 @@ Note: we do not have explicit unassign, but look at _push()
 
        if (copy_from_user(&be, arg, sizeof be))
                return -EFAULT;
-       brvcc = kmalloc(sizeof(struct br2684_vcc), GFP_KERNEL);
+       brvcc = kzalloc(sizeof(struct br2684_vcc), GFP_KERNEL);
        if (!brvcc)
                return -ENOMEM;
-       memset(brvcc, 0, sizeof(struct br2684_vcc));
        write_lock_irq(&devs_lock);
        net_dev = br2684_find_dev(&be.ifspec);
        if (net_dev == NULL) {
index 2e62105..7ce7bfe 100644 (file)
@@ -929,12 +929,11 @@ static int arp_seq_open(struct inode *inode, struct file *file)
        struct seq_file *seq;
        int rc = -EAGAIN;
 
-       state = kmalloc(sizeof(*state), GFP_KERNEL);
+       state = kzalloc(sizeof(*state), GFP_KERNEL);
        if (!state) {
                rc = -ENOMEM;
                goto out_kfree;
        }
-       memset(state, 0, sizeof(*state));
        state->ns.neigh_sub_iter = clip_seq_sub_iter;
 
        rc = seq_open(file, &arp_seq_ops);
index 4b68a18..b4aa489 100644 (file)
@@ -1811,12 +1811,11 @@ make_entry(struct lec_priv *priv, unsigned char *mac_addr)
 {
         struct lec_arp_table *to_return;
 
-        to_return = kmalloc(sizeof(struct lec_arp_table), GFP_ATOMIC);
+        to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC);
         if (!to_return) {
                 printk("LEC: Arp entry kmalloc failed\n");
                 return NULL;
         }
-        memset(to_return, 0, sizeof(struct lec_arp_table));
         memcpy(to_return->mac_addr, mac_addr, ETH_ALEN);
         init_timer(&to_return->timer);
         to_return->timer.function = lec_arp_expire_arp;
index 9aafe1e..0070466 100644 (file)
@@ -258,10 +258,9 @@ static struct mpoa_client *alloc_mpc(void)
 {
        struct mpoa_client *mpc;
 
-       mpc = kmalloc(sizeof (struct mpoa_client), GFP_KERNEL);
+       mpc = kzalloc(sizeof (struct mpoa_client), GFP_KERNEL);
        if (mpc == NULL)
                return NULL;
-       memset(mpc, 0, sizeof(struct mpoa_client));
        rwlock_init(&mpc->ingress_lock);
        rwlock_init(&mpc->egress_lock);
        mpc->next = mpcs;
index 76a7d8f..19d5dfc 100644 (file)
@@ -287,10 +287,9 @@ static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, void __user *arg)
        if (be.encaps != PPPOATM_ENCAPS_AUTODETECT &&
            be.encaps != PPPOATM_ENCAPS_VC && be.encaps != PPPOATM_ENCAPS_LLC)
                return -EINVAL;
-       pvcc = kmalloc(sizeof(*pvcc), GFP_KERNEL);
+       pvcc = kzalloc(sizeof(*pvcc), GFP_KERNEL);
        if (pvcc == NULL)
                return -ENOMEM;
-       memset(pvcc, 0, sizeof(*pvcc));
        pvcc->atmvcc = atmvcc;
        pvcc->old_push = atmvcc->push;
        pvcc->old_pop = atmvcc->pop;
index de25c64..529f7e6 100644 (file)
@@ -33,10 +33,9 @@ static struct atm_dev *__alloc_atm_dev(const char *type)
 {
        struct atm_dev *dev;
 
-       dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (!dev)
                return NULL;
-       memset(dev, 0, sizeof(*dev));
        dev->type = type;
        dev->signal = ATM_PHY_SIG_UNKNOWN;
        dev->link_rate = ATM_OC3_PCR;
index 369a75b..867d425 100644 (file)
@@ -203,13 +203,11 @@ void ax25_register_sysctl(void)
        for (ax25_table_size = sizeof(ctl_table), ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next)
                ax25_table_size += sizeof(ctl_table);
 
-       if ((ax25_table = kmalloc(ax25_table_size, GFP_ATOMIC)) == NULL) {
+       if ((ax25_table = kzalloc(ax25_table_size, GFP_ATOMIC)) == NULL) {
                spin_unlock_bh(&ax25_dev_lock);
                return;
        }
 
-       memset(ax25_table, 0x00, ax25_table_size);
-
        for (n = 0, ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) {
                ctl_table *child = kmalloc(sizeof(ax25_param_table), GFP_ATOMIC);
                if (!child) {
index 77eab8f..332dd8f 100644 (file)
@@ -55,6 +55,7 @@
 #define VERSION "1.8"
 
 static int disable_cfc = 0;
+static int channel_mtu = -1;
 static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU;
 
 static struct task_struct *rfcomm_thread;
@@ -812,7 +813,10 @@ static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d
                pn->credits   = 0;
        }
 
-       pn->mtu = htobs(d->mtu);
+       if (cr && channel_mtu >= 0)
+               pn->mtu = htobs(channel_mtu);
+       else
+               pn->mtu = htobs(d->mtu);
 
        *ptr = __fcs(buf); ptr++;
 
@@ -1243,7 +1247,10 @@ static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
 
        d->priority = pn->priority;
 
-       d->mtu = s->mtu = btohs(pn->mtu);
+       d->mtu = btohs(pn->mtu);
+
+       if (cr && d->mtu > s->mtu)
+               d->mtu = s->mtu;
 
        return 0;
 }
@@ -1770,6 +1777,11 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s)
        s = rfcomm_session_add(nsock, BT_OPEN);
        if (s) {
                rfcomm_session_hold(s);
+
+               /* We should adjust MTU on incoming sessions.
+                * L2CAP MTU minus UIH header and FCS. */
+               s->mtu = min(l2cap_pi(nsock->sk)->omtu, l2cap_pi(nsock->sk)->imtu) - 5;
+
                rfcomm_schedule(RFCOMM_SCHED_RX);
        } else
                sock_release(nsock);
@@ -2087,6 +2099,9 @@ module_exit(rfcomm_exit);
 module_param(disable_cfc, bool, 0644);
 MODULE_PARM_DESC(disable_cfc, "Disable credit based flow control");
 
+module_param(channel_mtu, int, 0644);
+MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel");
+
 module_param(l2cap_mtu, uint, 0644);
 MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection");
 
index 159fb84..4e4119a 100644 (file)
@@ -162,12 +162,10 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                if (num > BR_MAX_PORTS)
                        num = BR_MAX_PORTS;
 
-               indices = kmalloc(num*sizeof(int), GFP_KERNEL);
+               indices = kcalloc(num, sizeof(int), GFP_KERNEL);
                if (indices == NULL)
                        return -ENOMEM;
 
-               memset(indices, 0, num*sizeof(int));
-
                get_port_ifindices(br, indices, num);
                if (copy_to_user((void __user *)args[1], indices, num*sizeof(int)))
                        num =  -EFAULT;
@@ -327,11 +325,10 @@ static int old_deviceless(void __user *uarg)
 
                if (args[2] >= 2048)
                        return -ENOMEM;
-               indices = kmalloc(args[2]*sizeof(int), GFP_KERNEL);
+               indices = kcalloc(args[2], sizeof(int), GFP_KERNEL);
                if (indices == NULL)
                        return -ENOMEM;
 
-               memset(indices, 0, args[2]*sizeof(int));
                args[2] = get_bridge_ifindices(indices, args[2]);
 
                ret = copy_to_user((void __user *)args[1], indices, args[2]*sizeof(int))
index cbc8a38..05b3de8 100644 (file)
@@ -61,6 +61,9 @@ static int brnf_filter_vlan_tagged = 1;
 #define brnf_filter_vlan_tagged 1
 #endif
 
+int brnf_deferred_hooks;
+EXPORT_SYMBOL_GPL(brnf_deferred_hooks);
+
 static __be16 inline vlan_proto(const struct sk_buff *skb)
 {
        return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
@@ -890,6 +893,8 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb,
                                return NF_ACCEPT;
                        else if (ip->version == 6 && !brnf_call_ip6tables)
                                return NF_ACCEPT;
+                       else if (!brnf_deferred_hooks)
+                               return NF_ACCEPT;
 #endif
                        if (hook == NF_IP_POST_ROUTING)
                                return NF_ACCEPT;
index 27ce168..2797e28 100644 (file)
@@ -437,7 +437,7 @@ static int ethtool_set_pauseparam(struct net_device *dev, void __user *useraddr)
 {
        struct ethtool_pauseparam pauseparam;
 
-       if (!dev->ethtool_ops->get_pauseparam)
+       if (!dev->ethtool_ops->set_pauseparam)
                return -EOPNOTSUPP;
 
        if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam)))
index b7c98db..248a6b6 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/socket.h>
 #include <linux/rtnetlink.h> /* for BUG_TRAP */
 #include <net/tcp.h>
+#include <net/netdma.h>
 
 #define NET_DMA_DEFAULT_COPYBREAK 4096
 
index 6048373..b44c455 100644 (file)
@@ -26,4 +26,6 @@ extern void dccp_feat_clean(struct dccp_minisock *dmsk);
 extern int  dccp_feat_clone(struct sock *oldsk, struct sock *newsk);
 extern int  dccp_feat_init(struct dccp_minisock *dmsk);
 
+extern int  dccp_feat_default_sequence_window;
+
 #endif /* _DCCP_FEAT_H */
index c3073e7..7f56f7e 100644 (file)
@@ -504,8 +504,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
        ireq = inet_rsk(req);
        ireq->loc_addr = daddr;
        ireq->rmt_addr = saddr;
-       req->rcv_wnd    = 100; /* Fake, option parsing will get the
-                                 right value */
+       req->rcv_wnd    = dccp_feat_default_sequence_window;
        ireq->opt       = NULL;
 
        /* 
index ff42bc4..9f3d4d7 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "dccp.h"
 #include "ipv6.h"
+#include "feat.h"
 
 /* Socket used for sending RSTs and ACKs */
 static struct socket *dccp_v6_ctl_socket;
@@ -707,8 +708,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        ireq = inet_rsk(req);
        ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr);
        ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr);
-       req->rcv_wnd    = 100; /* Fake, option parsing will get the
-                                 right value */
+       req->rcv_wnd    = dccp_feat_default_sequence_window;
        ireq6->pktopts  = NULL;
 
        if (ipv6_opt_accepted(sk, skb) ||
index c3cda1e..daf72bb 100644 (file)
@@ -29,6 +29,8 @@ int dccp_feat_default_ack_ratio             = DCCPF_INITIAL_ACK_RATIO;
 int dccp_feat_default_send_ack_vector = DCCPF_INITIAL_SEND_ACK_VECTOR;
 int dccp_feat_default_send_ndp_count  = DCCPF_INITIAL_SEND_NDP_COUNT;
 
+EXPORT_SYMBOL_GPL(dccp_feat_default_sequence_window);
+
 void dccp_minisock_init(struct dccp_minisock *dmsk)
 {
        dmsk->dccpms_sequence_window = dccp_feat_default_sequence_window;
index 98a2520..476455f 100644 (file)
@@ -413,11 +413,7 @@ static struct dn_ifaddr *dn_dev_alloc_ifa(void)
 {
        struct dn_ifaddr *ifa;
 
-       ifa = kmalloc(sizeof(*ifa), GFP_KERNEL);
-
-       if (ifa) {
-               memset(ifa, 0, sizeof(*ifa));
-       }
+       ifa = kzalloc(sizeof(*ifa), GFP_KERNEL);
 
        return ifa;
 }
@@ -1105,10 +1101,9 @@ struct dn_dev *dn_dev_create(struct net_device *dev, int *err)
                return NULL;
 
        *err = -ENOBUFS;
-       if ((dn_db = kmalloc(sizeof(struct dn_dev), GFP_ATOMIC)) == NULL)
+       if ((dn_db = kzalloc(sizeof(struct dn_dev), GFP_ATOMIC)) == NULL)
                return NULL;
 
-       memset(dn_db, 0, sizeof(struct dn_dev));
        memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms));
        smp_wmb();
        dev->dn_ptr = dn_db;
index 0375077..fa20e2e 100644 (file)
@@ -283,11 +283,10 @@ struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, struct dn_kern_rta
                        goto err_inval;
        }
 
-       fi = kmalloc(sizeof(*fi)+nhs*sizeof(struct dn_fib_nh), GFP_KERNEL);
+       fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct dn_fib_nh), GFP_KERNEL);
        err = -ENOBUFS;
        if (fi == NULL)
                goto failure;
-       memset(fi, 0, sizeof(*fi)+nhs*sizeof(struct dn_fib_nh));
 
        fi->fib_protocol = r->rtm_protocol;
        fi->fib_nhs = nhs;
index 5ce9c9e..ff0ebe9 100644 (file)
@@ -580,12 +580,11 @@ static int dn_neigh_seq_open(struct inode *inode, struct file *file)
 {
        struct seq_file *seq;
        int rc = -ENOMEM;
-       struct neigh_seq_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+       struct neigh_seq_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
 
        if (!s)
                goto out;
 
-       memset(s, 0, sizeof(*s));
        rc = seq_open(file, &dn_neigh_seq_ops);
        if (rc)
                goto out_kfree;
index 22f321d..6986be7 100644 (file)
@@ -151,10 +151,9 @@ int dn_fib_rtm_newrule(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
                }
        }
 
-       new_r = kmalloc(sizeof(*new_r), GFP_KERNEL);
+       new_r = kzalloc(sizeof(*new_r), GFP_KERNEL);
        if (!new_r)
                return -ENOMEM;
-       memset(new_r, 0, sizeof(*new_r));
 
        if (rta[RTA_SRC-1])
                memcpy(&new_r->r_src, RTA_DATA(rta[RTA_SRC-1]), 2);
index 37d9d0a..e926c95 100644 (file)
@@ -158,12 +158,10 @@ static void dn_rehash_zone(struct dn_zone *dz)
                        break;
        }
 
-       ht = kmalloc(new_divisor*sizeof(struct dn_fib_node*), GFP_KERNEL);
-
+       ht = kcalloc(new_divisor, sizeof(struct dn_fib_node*), GFP_KERNEL);
        if (ht == NULL)
                return;
 
-       memset(ht, 0, new_divisor*sizeof(struct dn_fib_node *));
        write_lock_bh(&dn_fib_tables_lock);
        old_ht = dz->dz_hash;
        dz->dz_hash = ht;
@@ -184,11 +182,10 @@ static void dn_free_node(struct dn_fib_node *f)
 static struct dn_zone *dn_new_zone(struct dn_hash *table, int z)
 {
        int i;
-       struct dn_zone *dz = kmalloc(sizeof(struct dn_zone), GFP_KERNEL);
+       struct dn_zone *dz = kzalloc(sizeof(struct dn_zone), GFP_KERNEL);
        if (!dz)
                return NULL;
 
-       memset(dz, 0, sizeof(struct dn_zone));
        if (z) {
                dz->dz_divisor = 16;
                dz->dz_hashmask = 0x0F;
@@ -197,14 +194,12 @@ static struct dn_zone *dn_new_zone(struct dn_hash *table, int z)
                dz->dz_hashmask = 0;
        }
 
-       dz->dz_hash = kmalloc(dz->dz_divisor*sizeof(struct dn_fib_node *), GFP_KERNEL);
-
+       dz->dz_hash = kcalloc(dz->dz_divisor, sizeof(struct dn_fib_node *), GFP_KERNEL);
        if (!dz->dz_hash) {
                kfree(dz);
                return NULL;
        }
 
-       memset(dz->dz_hash, 0, dz->dz_divisor*sizeof(struct dn_fib_node*));
        dz->dz_order = z;
        dz->dz_mask = dnet_make_mask(z);
 
index 309ae4c..4d66aac 100644 (file)
@@ -673,12 +673,11 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
                edev = dev->ec_ptr;
                if (edev == NULL) {
                        /* Magic up a new one. */
-                       edev = kmalloc(sizeof(struct ec_device), GFP_KERNEL);
+                       edev = kzalloc(sizeof(struct ec_device), GFP_KERNEL);
                        if (edev == NULL) {
                                err = -ENOMEM;
                                break;
                        }
-                       memset(edev, 0, sizeof(struct ec_device));
                        dev->ec_ptr = edev;
                } else
                        net2dev_map[edev->net] = NULL;
index dbb0852..f7e84e9 100644 (file)
@@ -58,6 +58,7 @@ config IEEE80211_CRYPT_TKIP
        depends on IEEE80211 && NET_RADIO
        select CRYPTO
        select CRYPTO_MICHAEL_MIC
+       select CRC32
        ---help---
        Include software based cipher suites in support of IEEE 802.11i
        (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with TKIP enabled
index cb71d79..5ed0a98 100644 (file)
@@ -110,11 +110,10 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
        unsigned long flags;
        struct ieee80211_crypto_alg *alg;
 
-       alg = kmalloc(sizeof(*alg), GFP_KERNEL);
+       alg = kzalloc(sizeof(*alg), GFP_KERNEL);
        if (alg == NULL)
                return -ENOMEM;
 
-       memset(alg, 0, sizeof(*alg));
        alg->ops = ops;
 
        spin_lock_irqsave(&ieee80211_crypto_lock, flags);
index 4926473..ed90a8a 100644 (file)
@@ -76,10 +76,9 @@ static void *ieee80211_ccmp_init(int key_idx)
 {
        struct ieee80211_ccmp_data *priv;
 
-       priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
+       priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
        if (priv == NULL)
                goto fail;
-       memset(priv, 0, sizeof(*priv));
        priv->key_idx = key_idx;
 
        priv->tfm = crypto_alloc_tfm("aes", 0);
index c5a8772..0ebf235 100644 (file)
@@ -39,10 +39,9 @@ static void *prism2_wep_init(int keyidx)
 {
        struct prism2_wep_data *priv;
 
-       priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
+       priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
        if (priv == NULL)
                goto fail;
-       memset(priv, 0, sizeof(*priv));
        priv->key_idx = keyidx;
 
        priv->tfm = crypto_alloc_tfm("arc4", 0);
index a78c4f8..5cb9cfd 100644 (file)
@@ -369,11 +369,10 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
                struct ieee80211_crypt_data *new_crypt;
 
                /* take WEP into use */
-               new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data),
+               new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
                                    GFP_KERNEL);
                if (new_crypt == NULL)
                        return -ENOMEM;
-               memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
                new_crypt->ops = ieee80211_get_crypto_ops("WEP");
                if (!new_crypt->ops) {
                        request_module("ieee80211_crypt_wep");
@@ -616,13 +615,11 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
 
                ieee80211_crypt_delayed_deinit(ieee, crypt);
 
-               new_crypt = (struct ieee80211_crypt_data *)
-                   kmalloc(sizeof(*new_crypt), GFP_KERNEL);
+               new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
                if (new_crypt == NULL) {
                        ret = -ENOMEM;
                        goto done;
                }
-               memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
                new_crypt->ops = ops;
                if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
                        new_crypt->priv = new_crypt->ops->init(idx);
index ebc33ca..4cef39e 100644 (file)
@@ -116,6 +116,16 @@ ieee80211softmac_auth_queue(void *data)
        kfree(auth);
 }
 
+/* Sends a response to an auth challenge (for shared key auth). */
+static void
+ieee80211softmac_auth_challenge_response(void *_aq)
+{
+       struct ieee80211softmac_auth_queue_item *aq = _aq;
+
+       /* Send our response */
+       ieee80211softmac_send_mgt_frame(aq->mac, aq->net, IEEE80211_STYPE_AUTH, aq->state);
+}
+
 /* Handle the auth response from the AP
  * This should be registered with ieee80211 as handle_auth 
  */
@@ -197,24 +207,30 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
                case IEEE80211SOFTMAC_AUTH_SHARED_CHALLENGE:
                        /* Check to make sure we have a challenge IE */
                        data = (u8 *)auth->info_element;
-                       if(*data++ != MFIE_TYPE_CHALLENGE){
+                       if (*data++ != MFIE_TYPE_CHALLENGE) {
                                printkl(KERN_NOTICE PFX "Shared Key Authentication failed due to a missing challenge.\n");
                                break;  
                        }
                        /* Save the challenge */
                        spin_lock_irqsave(&mac->lock, flags);
                        net->challenge_len = *data++;   
-                       if(net->challenge_len > WLAN_AUTH_CHALLENGE_LEN)
+                       if (net->challenge_len > WLAN_AUTH_CHALLENGE_LEN)
                                net->challenge_len = WLAN_AUTH_CHALLENGE_LEN;
-                       if(net->challenge != NULL)
+                       if (net->challenge != NULL)
                                kfree(net->challenge);
                        net->challenge = kmalloc(net->challenge_len, GFP_ATOMIC);
                        memcpy(net->challenge, data, net->challenge_len);
                        aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE; 
-                       spin_unlock_irqrestore(&mac->lock, flags);
 
-                       /* Send our response */
-                       ieee80211softmac_send_mgt_frame(mac, aq->net, IEEE80211_STYPE_AUTH, aq->state);
+                       /* We reuse the work struct from the auth request here.
+                        * It is safe to do so as each one is per-request, and
+                        * at this point (dealing with authentication response)
+                        * we have obviously already sent the initial auth
+                        * request. */
+                       cancel_delayed_work(&aq->work);
+                       INIT_WORK(&aq->work, &ieee80211softmac_auth_challenge_response, (void *)aq);
+                       schedule_work(&aq->work);
+                       spin_unlock_irqrestore(&mac->lock, flags);
                        return 0;
                case IEEE80211SOFTMAC_AUTH_SHARED_PASS:
                        kfree(net->challenge);
index 8cc8b20..6ae5a1d 100644 (file)
@@ -96,8 +96,7 @@ ieee80211softmac_alloc_mgt(u32 size)
        if(size > IEEE80211_DATA_LEN)
                return NULL;
        /* Allocate the frame */
-       data = kmalloc(size, GFP_ATOMIC);
-       memset(data, 0, size);
+       data = kzalloc(size, GFP_ATOMIC);
        return data;
 }
 
index 8e748be..1366bc6 100644 (file)
@@ -215,12 +215,10 @@ static int ah_init_state(struct xfrm_state *x)
        if (x->encap)
                goto error;
 
-       ahp = kmalloc(sizeof(*ahp), GFP_KERNEL);
+       ahp = kzalloc(sizeof(*ahp), GFP_KERNEL);
        if (ahp == NULL)
                return -ENOMEM;
 
-       memset(ahp, 0, sizeof(*ahp));
-
        ahp->key = x->aalg->alg_key;
        ahp->key_len = (x->aalg->alg_key_len+7)/8;
        ahp->tfm = crypto_alloc_tfm(x->aalg->alg_name, 0);
index 7b51b3b..c8a3723 100644 (file)
@@ -1372,12 +1372,11 @@ static int arp_seq_open(struct inode *inode, struct file *file)
 {
        struct seq_file *seq;
        int rc = -ENOMEM;
-       struct neigh_seq_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+       struct neigh_seq_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
        
        if (!s)
                goto out;
 
-       memset(s, 0, sizeof(*s));
        rc = seq_open(file, &arp_seq_ops);
        if (rc)
                goto out_kfree;
index a7c65e9..a6cc31d 100644 (file)
@@ -93,10 +93,9 @@ static void devinet_sysctl_unregister(struct ipv4_devconf *p);
 
 static struct in_ifaddr *inet_alloc_ifa(void)
 {
-       struct in_ifaddr *ifa = kmalloc(sizeof(*ifa), GFP_KERNEL);
+       struct in_ifaddr *ifa = kzalloc(sizeof(*ifa), GFP_KERNEL);
 
        if (ifa) {
-               memset(ifa, 0, sizeof(*ifa));
                INIT_RCU_HEAD(&ifa->rcu_head);
        }
 
@@ -140,10 +139,9 @@ struct in_device *inetdev_init(struct net_device *dev)
 
        ASSERT_RTNL();
 
-       in_dev = kmalloc(sizeof(*in_dev), GFP_KERNEL);
+       in_dev = kzalloc(sizeof(*in_dev), GFP_KERNEL);
        if (!in_dev)
                goto out;
-       memset(in_dev, 0, sizeof(*in_dev));
        INIT_RCU_HEAD(&in_dev->rcu_head);
        memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf));
        in_dev->cnf.sysctl = NULL;
index 4e11273..fc2f8ce 100644 (file)
@@ -316,12 +316,10 @@ static int esp_init_state(struct xfrm_state *x)
        if (x->ealg == NULL)
                goto error;
 
-       esp = kmalloc(sizeof(*esp), GFP_KERNEL);
+       esp = kzalloc(sizeof(*esp), GFP_KERNEL);
        if (esp == NULL)
                return -ENOMEM;
 
-       memset(esp, 0, sizeof(*esp));
-
        if (x->aalg) {
                struct xfrm_algo_desc *aalg_desc;
 
index 3c1d32a..72c633b 100644 (file)
@@ -204,11 +204,10 @@ static struct fn_zone *
 fn_new_zone(struct fn_hash *table, int z)
 {
        int i;
-       struct fn_zone *fz = kmalloc(sizeof(struct fn_zone), GFP_KERNEL);
+       struct fn_zone *fz = kzalloc(sizeof(struct fn_zone), GFP_KERNEL);
        if (!fz)
                return NULL;
 
-       memset(fz, 0, sizeof(struct fn_zone));
        if (z) {
                fz->fz_divisor = 16;
        } else {
@@ -1046,7 +1045,7 @@ static int fib_seq_open(struct inode *inode, struct file *file)
 {
        struct seq_file *seq;
        int rc = -ENOMEM;
-       struct fib_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+       struct fib_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
        
        if (!s)
                goto out;
@@ -1057,7 +1056,6 @@ static int fib_seq_open(struct inode *inode, struct file *file)
 
        seq          = file->private_data;
        seq->private = s;
-       memset(s, 0, sizeof(*s));
 out:
        return rc;
 out_kfree:
index 773b12b..79b0471 100644 (file)
@@ -196,10 +196,9 @@ int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
                }
        }
 
-       new_r = kmalloc(sizeof(*new_r), GFP_KERNEL);
+       new_r = kzalloc(sizeof(*new_r), GFP_KERNEL);
        if (!new_r)
                return -ENOMEM;
-       memset(new_r, 0, sizeof(*new_r));
 
        if (rta[RTA_SRC-1])
                memcpy(&new_r->r_src, RTA_DATA(rta[RTA_SRC-1]), 4);
index 5f87533..9be53a8 100644 (file)
@@ -709,11 +709,10 @@ fib_create_info(const struct rtmsg *r, struct kern_rta *rta,
                        goto failure;
        }
 
-       fi = kmalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
+       fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
        if (fi == NULL)
                goto failure;
        fib_info_cnt++;
-       memset(fi, 0, sizeof(*fi)+nhs*sizeof(struct fib_nh));
 
        fi->fib_protocol = r->rtm_protocol;
 
@@ -962,10 +961,6 @@ fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
        rtm->rtm_protocol = fi->fib_protocol;
        if (fi->fib_priority)
                RTA_PUT(skb, RTA_PRIORITY, 4, &fi->fib_priority);
-#ifdef CONFIG_NET_CLS_ROUTE
-       if (fi->fib_nh[0].nh_tclassid)
-               RTA_PUT(skb, RTA_FLOW, 4, &fi->fib_nh[0].nh_tclassid);
-#endif
        if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0)
                goto rtattr_failure;
        if (fi->fib_prefsrc)
@@ -975,6 +970,10 @@ fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
                        RTA_PUT(skb, RTA_GATEWAY, 4, &fi->fib_nh->nh_gw);
                if (fi->fib_nh->nh_oif)
                        RTA_PUT(skb, RTA_OIF, sizeof(int), &fi->fib_nh->nh_oif);
+#ifdef CONFIG_NET_CLS_ROUTE
+               if (fi->fib_nh[0].nh_tclassid)
+                       RTA_PUT(skb, RTA_FLOW, 4, &fi->fib_nh[0].nh_tclassid);
+#endif
        }
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
        if (fi->fib_nhs > 1) {
@@ -993,6 +992,10 @@ fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
                        nhp->rtnh_ifindex = nh->nh_oif;
                        if (nh->nh_gw)
                                RTA_PUT(skb, RTA_GATEWAY, 4, &nh->nh_gw);
+#ifdef CONFIG_NET_CLS_ROUTE
+                       if (nh->nh_tclassid)
+                               RTA_PUT(skb, RTA_FLOW, 4, &nh->nh_tclassid);
+#endif
                        nhp->rtnh_len = skb->tail - (unsigned char*)nhp;
                } endfor_nexthops(fi);
                mp_head->rta_type = RTA_MULTIPATH;
index d299c8e..9f4b752 100644 (file)
@@ -1028,10 +1028,9 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im)
         * for deleted items allows change reports to use common code with
         * non-deleted or query-response MCA's.
         */
-       pmc = kmalloc(sizeof(*pmc), GFP_KERNEL);
+       pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
        if (!pmc)
                return;
-       memset(pmc, 0, sizeof(*pmc));
        spin_lock_bh(&im->lock);
        pmc->interface = im->interface;
        in_dev_hold(in_dev);
@@ -1529,10 +1528,9 @@ static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode,
                psf_prev = psf;
        }
        if (!psf) {
-               psf = kmalloc(sizeof(*psf), GFP_ATOMIC);
+               psf = kzalloc(sizeof(*psf), GFP_ATOMIC);
                if (!psf)
                        return -ENOBUFS;
-               memset(psf, 0, sizeof(*psf));
                psf->sf_inaddr = *psfsrc;
                if (psf_prev) {
                        psf_prev->sf_next = psf;
@@ -2380,7 +2378,7 @@ static int igmp_mc_seq_open(struct inode *inode, struct file *file)
 {
        struct seq_file *seq;
        int rc = -ENOMEM;
-       struct igmp_mc_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+       struct igmp_mc_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
 
        if (!s)
                goto out;
@@ -2390,7 +2388,6 @@ static int igmp_mc_seq_open(struct inode *inode, struct file *file)
 
        seq = file->private_data;
        seq->private = s;
-       memset(s, 0, sizeof(*s));
 out:
        return rc;
 out_kfree:
@@ -2555,7 +2552,7 @@ static int igmp_mcf_seq_open(struct inode *inode, struct file *file)
 {
        struct seq_file *seq;
        int rc = -ENOMEM;
-       struct igmp_mcf_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+       struct igmp_mcf_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
 
        if (!s)
                goto out;
@@ -2565,7 +2562,6 @@ static int igmp_mcf_seq_open(struct inode *inode, struct file *file)
 
        seq = file->private_data;
        seq->private = s;
-       memset(s, 0, sizeof(*s));
 out:
        return rc;
 out_kfree:
index 8e7e41b..492858e 100644 (file)
@@ -909,11 +909,10 @@ static int __init inet_diag_init(void)
                                          sizeof(struct inet_diag_handler *));
        int err = -ENOMEM;
 
-       inet_diag_table = kmalloc(inet_diag_table_size, GFP_KERNEL);
+       inet_diag_table = kzalloc(inet_diag_table_size, GFP_KERNEL);
        if (!inet_diag_table)
                goto out;
 
-       memset(inet_diag_table, 0, inet_diag_table_size);
        idiagnl = netlink_kernel_create(NETLINK_INET_DIAG, 0, inet_diag_rcv,
                                        THIS_MODULE);
        if (idiagnl == NULL)
index 6ff9b10..0f9b3a3 100644 (file)
@@ -617,7 +617,6 @@ static int ipgre_rcv(struct sk_buff *skb)
                skb->mac.raw = skb->nh.raw;
                skb->nh.raw = __pskb_pull(skb, offset);
                skb_postpull_rcsum(skb, skb->h.raw, offset);
-               memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
                skb->pkt_type = PACKET_HOST;
 #ifdef CONFIG_NET_IPGRE_BROADCAST
                if (MULTICAST(iph->daddr)) {
index 184c78c..212734c 100644 (file)
@@ -429,7 +429,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
        }
 
        /* Remove any debris in the socket control block */
-       memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+       memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
 
        return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
                       ip_rcv_finish);
index cbcae65..406056e 100644 (file)
@@ -256,7 +256,6 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
 
        if (!opt) {
                opt = &(IPCB(skb)->opt);
-               memset(opt, 0, sizeof(struct ip_options));
                iph = skb->nh.raw;
                opt->optlen = ((struct iphdr *)iph)->ihl*4 - sizeof(struct iphdr);
                optptr = iph + sizeof(struct iphdr);
index 8a8b5cf..a0c28b2 100644 (file)
@@ -410,11 +410,10 @@ static int ipcomp_init_state(struct xfrm_state *x)
                goto out;
 
        err = -ENOMEM;
-       ipcd = kmalloc(sizeof(*ipcd), GFP_KERNEL);
+       ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL);
        if (!ipcd)
                goto out;
 
-       memset(ipcd, 0, sizeof(*ipcd));
        x->props.header_len = 0;
        if (x->props.mode)
                x->props.header_len += sizeof(struct iphdr);
index 3291d51..76ab50b 100644 (file)
@@ -487,7 +487,6 @@ static int ipip_rcv(struct sk_buff *skb)
 
                skb->mac.raw = skb->nh.raw;
                skb->nh.raw = skb->data;
-               memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
                skb->protocol = htons(ETH_P_IP);
                skb->pkt_type = PACKET_HOST;
 
index ba33f86..85893ee 100644 (file)
@@ -1461,7 +1461,6 @@ int pim_rcv_v1(struct sk_buff * skb)
        skb_pull(skb, (u8*)encap - skb->data);
        skb->nh.iph = (struct iphdr *)skb->data;
        skb->dev = reg_dev;
-       memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
        skb->protocol = htons(ETH_P_IP);
        skb->ip_summed = 0;
        skb->pkt_type = PACKET_HOST;
@@ -1517,7 +1516,6 @@ static int pim_rcv(struct sk_buff * skb)
        skb_pull(skb, (u8*)encap - skb->data);
        skb->nh.iph = (struct iphdr *)skb->data;
        skb->dev = reg_dev;
-       memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
        skb->protocol = htons(ETH_P_IP);
        skb->ip_summed = 0;
        skb->pkt_type = PACKET_HOST;
@@ -1580,6 +1578,7 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait)
        cache = ipmr_cache_find(rt->rt_src, rt->rt_dst);
 
        if (cache==NULL) {
+               struct sk_buff *skb2;
                struct net_device *dev;
                int vif;
 
@@ -1593,12 +1592,18 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait)
                        read_unlock(&mrt_lock);
                        return -ENODEV;
                }
-               skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
-               skb->nh.iph->ihl = sizeof(struct iphdr)>>2;
-               skb->nh.iph->saddr = rt->rt_src;
-               skb->nh.iph->daddr = rt->rt_dst;
-               skb->nh.iph->version = 0;
-               err = ipmr_cache_unresolved(vif, skb);
+               skb2 = skb_clone(skb, GFP_ATOMIC);
+               if (!skb2) {
+                       read_unlock(&mrt_lock);
+                       return -ENOMEM;
+               }
+
+               skb2->nh.raw = skb_push(skb2, sizeof(struct iphdr));
+               skb2->nh.iph->ihl = sizeof(struct iphdr)>>2;
+               skb2->nh.iph->saddr = rt->rt_src;
+               skb2->nh.iph->daddr = rt->rt_dst;
+               skb2->nh.iph->version = 0;
+               err = ipmr_cache_unresolved(vif, skb2);
                read_unlock(&mrt_lock);
                return err;
        }
index f28ec68..6a28faf 100644 (file)
@@ -735,12 +735,11 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest,
        if (atype != RTN_LOCAL && atype != RTN_UNICAST)
                return -EINVAL;
 
-       dest = kmalloc(sizeof(struct ip_vs_dest), GFP_ATOMIC);
+       dest = kzalloc(sizeof(struct ip_vs_dest), GFP_ATOMIC);
        if (dest == NULL) {
                IP_VS_ERR("ip_vs_new_dest: kmalloc failed.\n");
                return -ENOMEM;
        }
-       memset(dest, 0, sizeof(struct ip_vs_dest));
 
        dest->protocol = svc->protocol;
        dest->vaddr = svc->addr;
@@ -1050,14 +1049,12 @@ ip_vs_add_service(struct ip_vs_service_user *u, struct ip_vs_service **svc_p)
                goto out_mod_dec;
        }
 
-       svc = (struct ip_vs_service *)
-               kmalloc(sizeof(struct ip_vs_service), GFP_ATOMIC);
+       svc = kzalloc(sizeof(struct ip_vs_service), GFP_ATOMIC);
        if (svc == NULL) {
                IP_VS_DBG(1, "ip_vs_add_service: kmalloc failed.\n");
                ret = -ENOMEM;
                goto out_err;
        }
-       memset(svc, 0, sizeof(struct ip_vs_service));
 
        /* I'm the first user of the service */
        atomic_set(&svc->usecnt, 1);
@@ -1797,7 +1794,7 @@ static int ip_vs_info_open(struct inode *inode, struct file *file)
 {
        struct seq_file *seq;
        int rc = -ENOMEM;
-       struct ip_vs_iter *s = kmalloc(sizeof(*s), GFP_KERNEL);
+       struct ip_vs_iter *s = kzalloc(sizeof(*s), GFP_KERNEL);
 
        if (!s)
                goto out;
@@ -1808,7 +1805,6 @@ static int ip_vs_info_open(struct inode *inode, struct file *file)
 
        seq          = file->private_data;
        seq->private = s;
-       memset(s, 0, sizeof(*s));
 out:
        return rc;
 out_kfree:
index 4c19403..7d68b80 100644 (file)
@@ -123,11 +123,10 @@ int ip_vs_new_estimator(struct ip_vs_stats *stats)
 {
        struct ip_vs_estimator *est;
 
-       est = kmalloc(sizeof(*est), GFP_KERNEL);
+       est = kzalloc(sizeof(*est), GFP_KERNEL);
        if (est == NULL)
                return -ENOMEM;
 
-       memset(est, 0, sizeof(*est));
        est->stats = stats;
        est->last_conns = stats->conns;
        est->cps = stats->cps<<10;
index af35235..9a39e29 100644 (file)
@@ -1200,7 +1200,7 @@ static struct ip_conntrack_expect *find_expect(struct ip_conntrack *ct,
        tuple.dst.protonum = IPPROTO_TCP;
 
        exp = __ip_conntrack_expect_find(&tuple);
-       if (exp->master == ct)
+       if (exp && exp->master == ct)
                return exp;
        return NULL;
 }
index 7bd3c22..7a9fa04 100644 (file)
@@ -534,6 +534,8 @@ static struct nf_hook_ops ip_conntrack_ops[] = {
 
 /* Sysctl support */
 
+int ip_conntrack_checksum = 1;
+
 #ifdef CONFIG_SYSCTL
 
 /* From ip_conntrack_core.c */
@@ -568,8 +570,6 @@ extern unsigned int ip_ct_generic_timeout;
 static int log_invalid_proto_min = 0;
 static int log_invalid_proto_max = 255;
 
-int ip_conntrack_checksum = 1;
-
 static struct ctl_table_header *ip_ct_sysctl_header;
 
 static ctl_table ip_ct_sysctl_table[] = {
index 0b1b416..18b7fbd 100644 (file)
@@ -1255,9 +1255,9 @@ static int help(struct sk_buff **pskb,
        struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl);
 
        /* SNMP replies and originating SNMP traps get mangled */
-       if (udph->source == ntohs(SNMP_PORT) && dir != IP_CT_DIR_REPLY)
+       if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY)
                return NF_ACCEPT;
-       if (udph->dest == ntohs(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL)
+       if (udph->dest == htons(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL)
                return NF_ACCEPT;
 
        /* No NAT? */
index cbffeae..d994c5f 100644 (file)
@@ -172,11 +172,10 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, u_int32_t ip,
        struct clusterip_config *c;
        char buffer[16];
 
-       c = kmalloc(sizeof(*c), GFP_ATOMIC);
+       c = kzalloc(sizeof(*c), GFP_ATOMIC);
        if (!c)
                return NULL;
 
-       memset(c, 0, sizeof(*c));
        c->dev = dev;
        c->clusterip = ip;
        memcpy(&c->clustermac, &i->clustermac, ETH_ALEN);
index bd221ec..62b2762 100644 (file)
@@ -609,6 +609,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        if (sin) {
                sin->sin_family = AF_INET;
                sin->sin_addr.s_addr = skb->nh.iph->saddr;
+               sin->sin_port = 0;
                memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
        }
        if (inet->cmsg_flags)
index a891133..f6f39e8 100644 (file)
@@ -1640,10 +1640,9 @@ static int tcp_seq_open(struct inode *inode, struct file *file)
        if (unlikely(afinfo == NULL))
                return -EINVAL;
 
-       s = kmalloc(sizeof(*s), GFP_KERNEL);
+       s = kzalloc(sizeof(*s), GFP_KERNEL);
        if (!s)
                return -ENOMEM;
-       memset(s, 0, sizeof(*s));
        s->family               = afinfo->family;
        s->seq_ops.start        = tcp_seq_start;
        s->seq_ops.next         = tcp_seq_next;
index 9bfcdda..f136cec 100644 (file)
@@ -1468,11 +1468,10 @@ static int udp_seq_open(struct inode *inode, struct file *file)
        struct udp_seq_afinfo *afinfo = PDE(inode)->data;
        struct seq_file *seq;
        int rc = -ENOMEM;
-       struct udp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+       struct udp_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
 
        if (!s)
                goto out;
-       memset(s, 0, sizeof(*s));
        s->family               = afinfo->family;
        s->seq_ops.start        = udp_seq_start;
        s->seq_ops.next         = udp_seq_next;
index f8d880b..13cafbe 100644 (file)
@@ -92,7 +92,6 @@ static int xfrm4_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
        skb->mac.raw = memmove(skb->data - skb->mac_len,
                               skb->mac.raw, skb->mac_len);
        skb->nh.raw = skb->data;
-       memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
        err = 0;
 
 out:
index df8f051..25c2a9e 100644 (file)
@@ -71,6 +71,8 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
                goto out;
        }
 
+       memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm));
+
        /*
         * Store incoming device index. When the packet will
         * be queued, we cannot refer to skb->dev anymore.
index bc77c0e..84d7ebd 100644 (file)
@@ -567,10 +567,9 @@ static inline struct ipv6_txoptions *create_tel(__u8 encap_limit)
 
        int opt_len = sizeof(*opt) + 8;
 
-       if (!(opt = kmalloc(opt_len, GFP_ATOMIC))) {
+       if (!(opt = kzalloc(opt_len, GFP_ATOMIC))) {
                return NULL;
        }
-       memset(opt, 0, opt_len);
        opt->tot_len = opt_len;
        opt->dst0opt = (struct ipv6_opt_hdr *) (opt + 1);
        opt->opt_nflen = 8;
index fa1ce0a..d57e61c 100644 (file)
@@ -411,6 +411,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
        /* Copy the address. */
        if (sin6) {
                sin6->sin6_family = AF_INET6;
+               sin6->sin6_port = 0;
                ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
                sin6->sin6_flowinfo = 0;
                sin6->sin6_scope_id = 0;
index c56aeec..836eecd 100644 (file)
@@ -380,7 +380,6 @@ static int ipip6_rcv(struct sk_buff *skb)
                secpath_reset(skb);
                skb->mac.raw = skb->nh.raw;
                skb->nh.raw = skb->data;
-               memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
                IPCB(skb)->flags = 0;
                skb->protocol = htons(ETH_P_IPV6);
                skb->pkt_type = PACKET_HOST;
index 6b44fe8..c8f9369 100644 (file)
 #include <linux/icmpv6.h>
 #include <linux/mutex.h>
 
-#ifdef CONFIG_IPV6_XFRM6_TUNNEL_DEBUG
-# define X6TDEBUG      3
-#else
-# define X6TDEBUG      1
-#endif
-
-#define X6TPRINTK(fmt, args...)                printk(fmt, ## args)
-#define X6TNOPRINTK(fmt, args...)      do { ; } while(0)
-
-#if X6TDEBUG >= 1
-# define X6TPRINTK1    X6TPRINTK
-#else
-# define X6TPRINTK1    X6TNOPRINTK
-#endif
-
-#if X6TDEBUG >= 3
-# define X6TPRINTK3    X6TPRINTK
-#else
-# define X6TPRINTK3    X6TNOPRINTK
-#endif
-
 /*
  * xfrm_tunnel_spi things are for allocating unique id ("spi") 
  * per xfrm_address_t.
@@ -62,15 +41,8 @@ struct xfrm6_tunnel_spi {
        xfrm_address_t addr;
        u32 spi;
        atomic_t refcnt;
-#ifdef XFRM6_TUNNEL_SPI_MAGIC
-       u32 magic;
-#endif
 };
 
-#ifdef CONFIG_IPV6_XFRM6_TUNNEL_DEBUG
-# define XFRM6_TUNNEL_SPI_MAGIC 0xdeadbeef
-#endif
-
 static DEFINE_RWLOCK(xfrm6_tunnel_spi_lock);
 
 static u32 xfrm6_tunnel_spi;
@@ -86,43 +58,15 @@ static kmem_cache_t *xfrm6_tunnel_spi_kmem __read_mostly;
 static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
 static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
 
-#ifdef XFRM6_TUNNEL_SPI_MAGIC
-static int x6spi_check_magic(const struct xfrm6_tunnel_spi *x6spi,
-                            const char *name)
-{
-       if (unlikely(x6spi->magic != XFRM6_TUNNEL_SPI_MAGIC)) {
-               X6TPRINTK3(KERN_DEBUG "%s(): x6spi object "
-                                     "at %p has corrupted magic %08x "
-                                     "(should be %08x)\n",
-                          name, x6spi, x6spi->magic, XFRM6_TUNNEL_SPI_MAGIC);
-               return -1;
-       }
-       return 0;
-}
-#else
-static int inline x6spi_check_magic(const struct xfrm6_tunnel_spi *x6spi,
-                                   const char *name)
-{
-       return 0;
-}
-#endif
-
-#define X6SPI_CHECK_MAGIC(x6spi) x6spi_check_magic((x6spi), __FUNCTION__)
-
-
 static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
 {
        unsigned h;
 
-       X6TPRINTK3(KERN_DEBUG "%s(addr=%p)\n", __FUNCTION__, addr);
-
        h = addr->a6[0] ^ addr->a6[1] ^ addr->a6[2] ^ addr->a6[3];
        h ^= h >> 16;
        h ^= h >> 8;
        h &= XFRM6_TUNNEL_SPI_BYADDR_HSIZE - 1;
 
-       X6TPRINTK3(KERN_DEBUG "%s() = %u\n", __FUNCTION__, h);
-
        return h;
 }
 
@@ -136,19 +80,13 @@ static int xfrm6_tunnel_spi_init(void)
 {
        int i;
 
-       X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);
-
        xfrm6_tunnel_spi = 0;
        xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi",
                                                  sizeof(struct xfrm6_tunnel_spi),
                                                  0, SLAB_HWCACHE_ALIGN,
                                                  NULL, NULL);
-       if (!xfrm6_tunnel_spi_kmem) {
-               X6TPRINTK1(KERN_ERR
-                          "%s(): failed to allocate xfrm6_tunnel_spi_kmem\n",
-                          __FUNCTION__);
+       if (!xfrm6_tunnel_spi_kmem)
                return -ENOMEM;
-       }
 
        for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
                INIT_HLIST_HEAD(&xfrm6_tunnel_spi_byaddr[i]);
@@ -161,22 +99,16 @@ static void xfrm6_tunnel_spi_fini(void)
 {
        int i;
 
-       X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);
-
        for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) {
                if (!hlist_empty(&xfrm6_tunnel_spi_byaddr[i]))
-                       goto err;
+                       return;
        }
        for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++) {
                if (!hlist_empty(&xfrm6_tunnel_spi_byspi[i]))
-                       goto err;
+                       return;
        }
        kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
        xfrm6_tunnel_spi_kmem = NULL;
-       return;
-err:
-       X6TPRINTK1(KERN_ERR "%s(): table is not empty\n", __FUNCTION__);
-       return;
 }
 
 static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
@@ -184,19 +116,13 @@ static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
        struct xfrm6_tunnel_spi *x6spi;
        struct hlist_node *pos;
 
-       X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);
-
        hlist_for_each_entry(x6spi, pos,
                             &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
                             list_byaddr) {
-               if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) {
-                       X6SPI_CHECK_MAGIC(x6spi);
-                       X6TPRINTK3(KERN_DEBUG "%s() = %p(%u)\n", __FUNCTION__, x6spi, x6spi->spi);
+               if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0)
                        return x6spi;
-               }
        }
 
-       X6TPRINTK3(KERN_DEBUG "%s() = NULL(0)\n", __FUNCTION__);
        return NULL;
 }
 
@@ -205,8 +131,6 @@ u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
        struct xfrm6_tunnel_spi *x6spi;
        u32 spi;
 
-       X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);
-
        read_lock_bh(&xfrm6_tunnel_spi_lock);
        x6spi = __xfrm6_tunnel_spi_lookup(saddr);
        spi = x6spi ? x6spi->spi : 0;
@@ -223,8 +147,6 @@ static u32 __xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
        struct hlist_node *pos;
        unsigned index;
 
-       X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);
-
        if (xfrm6_tunnel_spi < XFRM6_TUNNEL_SPI_MIN ||
            xfrm6_tunnel_spi >= XFRM6_TUNNEL_SPI_MAX)
                xfrm6_tunnel_spi = XFRM6_TUNNEL_SPI_MIN;
@@ -258,18 +180,10 @@ try_next_2:;
        spi = 0;
        goto out;
 alloc_spi:
-       X6TPRINTK3(KERN_DEBUG "%s(): allocate new spi for " NIP6_FMT "\n",
-                             __FUNCTION__, 
-                             NIP6(*(struct in6_addr *)saddr));
        x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, SLAB_ATOMIC);
-       if (!x6spi) {
-               X6TPRINTK1(KERN_ERR "%s(): kmem_cache_alloc() failed\n", 
-                          __FUNCTION__);
+       if (!x6spi)
                goto out;
-       }
-#ifdef XFRM6_TUNNEL_SPI_MAGIC
-       x6spi->magic = XFRM6_TUNNEL_SPI_MAGIC;
-#endif
+
        memcpy(&x6spi->addr, saddr, sizeof(x6spi->addr));
        x6spi->spi = spi;
        atomic_set(&x6spi->refcnt, 1);
@@ -278,9 +192,7 @@ alloc_spi:
 
        index = xfrm6_tunnel_spi_hash_byaddr(saddr);
        hlist_add_head(&x6spi->list_byaddr, &xfrm6_tunnel_spi_byaddr[index]);
-       X6SPI_CHECK_MAGIC(x6spi);
 out:
-       X6TPRINTK3(KERN_DEBUG "%s() = %u\n", __FUNCTION__, spi);
        return spi;
 }
 
@@ -289,8 +201,6 @@ u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
        struct xfrm6_tunnel_spi *x6spi;
        u32 spi;
 
-       X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);
-
        write_lock_bh(&xfrm6_tunnel_spi_lock);
        x6spi = __xfrm6_tunnel_spi_lookup(saddr);
        if (x6spi) {
@@ -300,8 +210,6 @@ u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
                spi = __xfrm6_tunnel_alloc_spi(saddr);
        write_unlock_bh(&xfrm6_tunnel_spi_lock);
 
-       X6TPRINTK3(KERN_DEBUG "%s() = %u\n", __FUNCTION__, spi);
-
        return spi;
 }
 
@@ -312,8 +220,6 @@ void xfrm6_tunnel_free_spi(xfrm_address_t *saddr)
        struct xfrm6_tunnel_spi *x6spi;
        struct hlist_node *pos, *n;
 
-       X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);
-
        write_lock_bh(&xfrm6_tunnel_spi_lock);
 
        hlist_for_each_entry_safe(x6spi, pos, n, 
@@ -321,12 +227,6 @@ void xfrm6_tunnel_free_spi(xfrm_address_t *saddr)
                                  list_byaddr)
        {
                if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) {
-                       X6TPRINTK3(KERN_DEBUG "%s(): x6spi object for " NIP6_FMT 
-                                             " found at %p\n",
-                                  __FUNCTION__, 
-                                  NIP6(*(struct in6_addr *)saddr),
-                                  x6spi);
-                       X6SPI_CHECK_MAGIC(x6spi);
                        if (atomic_dec_and_test(&x6spi->refcnt)) {
                                hlist_del(&x6spi->list_byaddr);
                                hlist_del(&x6spi->list_byspi);
@@ -377,20 +277,14 @@ static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                case ICMPV6_ADDR_UNREACH:
                case ICMPV6_PORT_UNREACH:
                default:
-                       X6TPRINTK3(KERN_DEBUG
-                                  "xfrm6_tunnel: Destination Unreach.\n");
                        break;
                }
                break;
        case ICMPV6_PKT_TOOBIG:
-                       X6TPRINTK3(KERN_DEBUG 
-                                  "xfrm6_tunnel: Packet Too Big.\n");
                break;
        case ICMPV6_TIME_EXCEED:
                switch (code) {
                case ICMPV6_EXC_HOPLIMIT:
-                       X6TPRINTK3(KERN_DEBUG
-                                  "xfrm6_tunnel: Too small Hoplimit.\n");
                        break;
                case ICMPV6_EXC_FRAGTIME:
                default: 
@@ -447,22 +341,14 @@ static struct xfrm6_tunnel xfrm6_tunnel_handler = {
 
 static int __init xfrm6_tunnel_init(void)
 {
-       X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);
-
-       if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) {
-               X6TPRINTK1(KERN_ERR
-                          "xfrm6_tunnel init: can't add xfrm type\n");
+       if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0)
                return -EAGAIN;
-       }
+
        if (xfrm6_tunnel_register(&xfrm6_tunnel_handler)) {
-               X6TPRINTK1(KERN_ERR
-                          "xfrm6_tunnel init(): can't add handler\n");
                xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
                return -EAGAIN;
        }
        if (xfrm6_tunnel_spi_init() < 0) {
-               X6TPRINTK1(KERN_ERR
-                          "xfrm6_tunnel init: failed to initialize spi\n");
                xfrm6_tunnel_deregister(&xfrm6_tunnel_handler);
                xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
                return -EAGAIN;
@@ -472,15 +358,9 @@ static int __init xfrm6_tunnel_init(void)
 
 static void __exit xfrm6_tunnel_fini(void)
 {
-       X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);
-
        xfrm6_tunnel_spi_fini();
-       if (xfrm6_tunnel_deregister(&xfrm6_tunnel_handler))
-               X6TPRINTK1(KERN_ERR 
-                          "xfrm6_tunnel close: can't remove handler\n");
-       if (xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6) < 0)
-               X6TPRINTK1(KERN_ERR
-                          "xfrm6_tunnel close: can't remove xfrm type\n");
+       xfrm6_tunnel_deregister(&xfrm6_tunnel_handler);
+       xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
 }
 
 module_init(xfrm6_tunnel_init);
index 7fae48a..17699ee 100644 (file)
@@ -308,7 +308,7 @@ static void irda_connect_response(struct irda_sock *self)
 
        IRDA_ASSERT(self != NULL, return;);
 
-       skb = dev_alloc_skb(64);
+       skb = alloc_skb(64, GFP_ATOMIC);
        if (skb == NULL) {
                IRDA_DEBUG(0, "%s() Unable to allocate sk_buff!\n",
                           __FUNCTION__);
index 9c4a902..ad6b6af 100644 (file)
@@ -115,12 +115,10 @@ struct ircomm_cb *ircomm_open(notify_t *notify, __u8 service_type, int line)
 
        IRDA_ASSERT(ircomm != NULL, return NULL;);
 
-       self = kmalloc(sizeof(struct ircomm_cb), GFP_ATOMIC);
+       self = kzalloc(sizeof(struct ircomm_cb), GFP_ATOMIC);
        if (self == NULL)
                return NULL;
 
-       memset(self, 0, sizeof(struct ircomm_cb));
-
        self->notify = *notify;
        self->magic = IRCOMM_MAGIC;
 
index d909720..959874b 100644 (file)
@@ -81,7 +81,7 @@ static int ircomm_lmp_connect_response(struct ircomm_cb *self,
        
        /* Any userdata supplied? */
        if (userdata == NULL) {
-               tx_skb = dev_alloc_skb(64);
+               tx_skb = alloc_skb(64, GFP_ATOMIC);
                if (!tx_skb)
                        return -ENOMEM;
 
@@ -115,7 +115,7 @@ static int ircomm_lmp_disconnect_request(struct ircomm_cb *self,
        IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
         if (!userdata) {
-               tx_skb = dev_alloc_skb(64);
+               tx_skb = alloc_skb(64, GFP_ATOMIC);
                if (!tx_skb)
                        return -ENOMEM;
                
index 6009bab..a39f573 100644 (file)
@@ -121,7 +121,7 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush)
 
        skb = self->ctrl_skb;   
        if (!skb) {
-               skb = dev_alloc_skb(256);
+               skb = alloc_skb(256, GFP_ATOMIC);
                if (!skb) {
                        spin_unlock_irqrestore(&self->spinlock, flags);
                        return -ENOMEM;
index b400f27..3bcdb46 100644 (file)
@@ -379,12 +379,11 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
        self = hashbin_lock_find(ircomm_tty, line, NULL);
        if (!self) {
                /* No, so make new instance */
-               self = kmalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL);
+               self = kzalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL);
                if (self == NULL) {
                        IRDA_ERROR("%s(), kmalloc failed!\n", __FUNCTION__);
                        return -ENOMEM;
                }
-               memset(self, 0, sizeof(struct ircomm_tty_cb));
                
                self->magic = IRCOMM_TTY_MAGIC;
                self->flow = FLOW_STOP;
@@ -759,8 +758,9 @@ static int ircomm_tty_write(struct tty_struct *tty,
                        }
                } else {
                        /* Prepare a full sized frame */
-                       skb = dev_alloc_skb(self->max_data_size+
-                                           self->max_header_size);
+                       skb = alloc_skb(self->max_data_size+
+                                       self->max_header_size,
+                                       GFP_ATOMIC);
                        if (!skb) {
                                spin_unlock_irqrestore(&self->spinlock, flags);
                                return -ENOBUFS;
index ba40e54..7e7a317 100644 (file)
@@ -401,12 +401,10 @@ dongle_t *irda_device_dongle_init(struct net_device *dev, int type)
        }
 
        /* Allocate dongle info for this instance */
-       dongle = kmalloc(sizeof(dongle_t), GFP_KERNEL);
+       dongle = kzalloc(sizeof(dongle_t), GFP_KERNEL);
        if (!dongle)
                goto out;
 
-       memset(dongle, 0, sizeof(dongle_t));
-
        /* Bind the registration info to this particular instance */
        dongle->issue = reg;
        dongle->dev = dev;
index a047265..61128aa 100644 (file)
@@ -345,7 +345,7 @@ static void iriap_disconnect_request(struct iriap_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
 
-       tx_skb = dev_alloc_skb(64);
+       tx_skb = alloc_skb(64, GFP_ATOMIC);
        if (tx_skb == NULL) {
                IRDA_DEBUG(0, "%s(), Could not allocate an sk_buff of length %d\n", 
                        __FUNCTION__, 64);
@@ -396,7 +396,7 @@ int iriap_getvaluebyclass_request(struct iriap_cb *self,
        attr_len = strlen(attr);        /* Up to IAS_MAX_ATTRIBNAME = 60 */
 
        skb_len = self->max_header_size+2+name_len+1+attr_len+4;
-       tx_skb = dev_alloc_skb(skb_len);
+       tx_skb = alloc_skb(skb_len, GFP_ATOMIC);
        if (!tx_skb)
                return -ENOMEM;
 
@@ -562,7 +562,8 @@ static void iriap_getvaluebyclass_response(struct iriap_cb *self,
         *  value. We add 32 bytes because of the 6 bytes for the frame and
         *  max 5 bytes for the value coding.
         */
-       tx_skb = dev_alloc_skb(value->len + self->max_header_size + 32);
+       tx_skb = alloc_skb(value->len + self->max_header_size + 32,
+                          GFP_ATOMIC);
        if (!tx_skb)
                return;
 
@@ -700,7 +701,7 @@ void iriap_send_ack(struct iriap_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
 
-       tx_skb = dev_alloc_skb(64);
+       tx_skb = alloc_skb(64, GFP_ATOMIC);
        if (!tx_skb)
                return;
 
index a736074..da17395 100644 (file)
@@ -365,7 +365,7 @@ static void state_r_disconnect(struct iriap_cb *self, IRIAP_EVENT event,
 
        switch (event) {
        case IAP_LM_CONNECT_INDICATION:
-               tx_skb = dev_alloc_skb(64);
+               tx_skb = alloc_skb(64, GFP_ATOMIC);
                if (tx_skb == NULL) {
                        IRDA_WARNING("%s: unable to malloc!\n", __FUNCTION__);
                        return;
index 82e665c..a154b1d 100644 (file)
@@ -82,13 +82,12 @@ struct ias_object *irias_new_object( char *name, int id)
 
        IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
 
-       obj = kmalloc(sizeof(struct ias_object), GFP_ATOMIC);
+       obj = kzalloc(sizeof(struct ias_object), GFP_ATOMIC);
        if (obj == NULL) {
                IRDA_WARNING("%s(), Unable to allocate object!\n",
                             __FUNCTION__);
                return NULL;
        }
-       memset(obj, 0, sizeof( struct ias_object));
 
        obj->magic = IAS_OBJECT_MAGIC;
        obj->name = strndup(name, IAS_MAX_CLASSNAME);
@@ -346,13 +345,12 @@ void irias_add_integer_attrib(struct ias_object *obj, char *name, int value,
        IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
        IRDA_ASSERT(name != NULL, return;);
 
-       attrib = kmalloc(sizeof(struct ias_attrib), GFP_ATOMIC);
+       attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC);
        if (attrib == NULL) {
                IRDA_WARNING("%s: Unable to allocate attribute!\n",
                             __FUNCTION__);
                return;
        }
-       memset(attrib, 0, sizeof( struct ias_attrib));
 
        attrib->magic = IAS_ATTRIB_MAGIC;
        attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
@@ -382,13 +380,12 @@ void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets,
        IRDA_ASSERT(name != NULL, return;);
        IRDA_ASSERT(octets != NULL, return;);
 
-       attrib = kmalloc(sizeof(struct ias_attrib), GFP_ATOMIC);
+       attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC);
        if (attrib == NULL) {
                IRDA_WARNING("%s: Unable to allocate attribute!\n",
                             __FUNCTION__);
                return;
        }
-       memset(attrib, 0, sizeof( struct ias_attrib));
 
        attrib->magic = IAS_ATTRIB_MAGIC;
        attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
@@ -416,13 +413,12 @@ void irias_add_string_attrib(struct ias_object *obj, char *name, char *value,
        IRDA_ASSERT(name != NULL, return;);
        IRDA_ASSERT(value != NULL, return;);
 
-       attrib = kmalloc(sizeof( struct ias_attrib), GFP_ATOMIC);
+       attrib = kzalloc(sizeof( struct ias_attrib), GFP_ATOMIC);
        if (attrib == NULL) {
                IRDA_WARNING("%s: Unable to allocate attribute!\n",
                             __FUNCTION__);
                return;
        }
-       memset(attrib, 0, sizeof( struct ias_attrib));
 
        attrib->magic = IAS_ATTRIB_MAGIC;
        attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
@@ -443,12 +439,11 @@ struct ias_value *irias_new_integer_value(int integer)
 {
        struct ias_value *value;
 
-       value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
+       value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
        if (value == NULL) {
                IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
                return NULL;
        }
-       memset(value, 0, sizeof(struct ias_value));
 
        value->type = IAS_INTEGER;
        value->len = 4;
@@ -469,12 +464,11 @@ struct ias_value *irias_new_string_value(char *string)
 {
        struct ias_value *value;
 
-       value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
+       value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
        if (value == NULL) {
                IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
                return NULL;
        }
-       memset( value, 0, sizeof( struct ias_value));
 
        value->type = IAS_STRING;
        value->charset = CS_ASCII;
@@ -495,12 +489,11 @@ struct ias_value *irias_new_octseq_value(__u8 *octseq , int len)
 {
        struct ias_value *value;
 
-       value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
+       value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
        if (value == NULL) {
                IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
                return NULL;
        }
-       memset(value, 0, sizeof(struct ias_value));
 
        value->type = IAS_OCT_SEQ;
        /* Check length */
@@ -522,12 +515,11 @@ struct ias_value *irias_new_missing_value(void)
 {
        struct ias_value *value;
 
-       value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
+       value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC);
        if (value == NULL) {
                IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
                return NULL;
        }
-       memset(value, 0, sizeof(struct ias_value));
 
        value->type = IAS_MISSING;
        value->len = 0;
index bd659dd..7dd0a2f 100644 (file)
@@ -636,7 +636,7 @@ void irlan_get_provider_info(struct irlan_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
 
-       skb = dev_alloc_skb(64);
+       skb = alloc_skb(64, GFP_ATOMIC);
        if (!skb)
                return;
 
@@ -668,7 +668,7 @@ void irlan_open_data_channel(struct irlan_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
        
-       skb = dev_alloc_skb(64);
+       skb = alloc_skb(64, GFP_ATOMIC);
        if (!skb)
                return;
 
@@ -704,7 +704,7 @@ void irlan_close_data_channel(struct irlan_cb *self)
        if (self->client.tsap_ctrl == NULL)
                return;
 
-       skb = dev_alloc_skb(64);
+       skb = alloc_skb(64, GFP_ATOMIC);
        if (!skb)
                return;
 
@@ -739,7 +739,7 @@ static void irlan_open_unicast_addr(struct irlan_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);       
        
-       skb = dev_alloc_skb(128);
+       skb = alloc_skb(128, GFP_ATOMIC);
        if (!skb)
                return;
 
@@ -777,7 +777,7 @@ void irlan_set_broadcast_filter(struct irlan_cb *self, int status)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
        
-       skb = dev_alloc_skb(128);
+       skb = alloc_skb(128, GFP_ATOMIC);
        if (!skb)
                return;
 
@@ -816,7 +816,7 @@ void irlan_set_multicast_filter(struct irlan_cb *self, int status)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
 
-       skb = dev_alloc_skb(128);
+       skb = alloc_skb(128, GFP_ATOMIC);
        if (!skb)
                return;
        
@@ -856,7 +856,7 @@ static void irlan_get_unicast_addr(struct irlan_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
        
-       skb = dev_alloc_skb(128);
+       skb = alloc_skb(128, GFP_ATOMIC);
        if (!skb)
                return;
 
@@ -891,7 +891,7 @@ void irlan_get_media_char(struct irlan_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
        
-       skb = dev_alloc_skb(64);
+       skb = alloc_skb(64, GFP_ATOMIC);
        if (!skb)
                return;
 
index 39c202d..9c0df86 100644 (file)
@@ -296,7 +296,7 @@ void irlan_provider_send_reply(struct irlan_cb *self, int command,
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
 
-       skb = dev_alloc_skb(128);
+       skb = alloc_skb(128, GFP_ATOMIC);
        if (!skb)
                return;
 
index cade355..e7852a0 100644 (file)
@@ -116,11 +116,10 @@ struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos,
        IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
        /* Initialize the irlap structure. */
-       self = kmalloc(sizeof(struct irlap_cb), GFP_KERNEL);
+       self = kzalloc(sizeof(struct irlap_cb), GFP_KERNEL);
        if (self == NULL)
                return NULL;
 
-       memset(self, 0, sizeof(struct irlap_cb));
        self->magic = LAP_MAGIC;
 
        /* Make a binding between the layers */
@@ -882,7 +881,7 @@ static void irlap_change_speed(struct irlap_cb *self, __u32 speed, int now)
        /* Change speed now, or just piggyback speed on frames */
        if (now) {
                /* Send down empty frame to trigger speed change */
-               skb = dev_alloc_skb(0);
+               skb = alloc_skb(0, GFP_ATOMIC);
                if (skb)
                        irlap_queue_xmit(self, skb);
        }
@@ -1222,7 +1221,7 @@ static int irlap_seq_open(struct inode *inode, struct file *file)
 {
        struct seq_file *seq;
        int rc = -ENOMEM;
-       struct irlap_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+       struct irlap_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
        
        if (!s)
                goto out;
@@ -1238,7 +1237,6 @@ static int irlap_seq_open(struct inode *inode, struct file *file)
 
        seq          = file->private_data;
        seq->private = s;
-       memset(s, 0, sizeof(*s));
 out:
        return rc;
 out_kfree:
index 3e9a06a..ccb983b 100644 (file)
@@ -117,7 +117,7 @@ void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos)
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
 
        /* Allocate frame */
-       tx_skb = dev_alloc_skb(64);
+       tx_skb = alloc_skb(64, GFP_ATOMIC);
        if (!tx_skb)
                return;
 
@@ -210,7 +210,7 @@ void irlap_send_ua_response_frame(struct irlap_cb *self, struct qos_info *qos)
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
 
        /* Allocate frame */
-       tx_skb = dev_alloc_skb(64);
+       tx_skb = alloc_skb(64, GFP_ATOMIC);
        if (!tx_skb)
                return;
 
@@ -250,7 +250,7 @@ void irlap_send_dm_frame( struct irlap_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
 
-       tx_skb = dev_alloc_skb(32);
+       tx_skb = alloc_skb(32, GFP_ATOMIC);
        if (!tx_skb)
                return;
 
@@ -282,7 +282,7 @@ void irlap_send_disc_frame(struct irlap_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
 
-       tx_skb = dev_alloc_skb(16);
+       tx_skb = alloc_skb(16, GFP_ATOMIC);
        if (!tx_skb)
                return;
 
@@ -315,7 +315,7 @@ void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s,
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
        IRDA_ASSERT(discovery != NULL, return;);
 
-       tx_skb = dev_alloc_skb(64);
+       tx_skb = alloc_skb(64, GFP_ATOMIC);
        if (!tx_skb)
                return;
 
@@ -422,11 +422,10 @@ static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self,
                return;
        }
 
-       if ((discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) {
+       if ((discovery = kzalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) {
                IRDA_WARNING("%s: kmalloc failed!\n", __FUNCTION__);
                return;
        }
-       memset(discovery, 0, sizeof(discovery_t));
 
        discovery->data.daddr = info->daddr;
        discovery->data.saddr = self->saddr;
@@ -576,7 +575,7 @@ void irlap_send_rr_frame(struct irlap_cb *self, int command)
        struct sk_buff *tx_skb;
        __u8 *frame;
 
-       tx_skb = dev_alloc_skb(16);
+       tx_skb = alloc_skb(16, GFP_ATOMIC);
        if (!tx_skb)
                return;
 
@@ -601,7 +600,7 @@ void irlap_send_rd_frame(struct irlap_cb *self)
        struct sk_buff *tx_skb;
        __u8 *frame;
 
-       tx_skb = dev_alloc_skb(16);
+       tx_skb = alloc_skb(16, GFP_ATOMIC);
        if (!tx_skb)
                return;
 
@@ -1215,7 +1214,7 @@ void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr,
        struct test_frame *frame;
        __u8 *info;
 
-       tx_skb = dev_alloc_skb(cmd->len+sizeof(struct test_frame));
+       tx_skb = alloc_skb(cmd->len+sizeof(struct test_frame), GFP_ATOMIC);
        if (!tx_skb)
                return;
 
index 129ad64..c440913 100644 (file)
@@ -78,10 +78,9 @@ int __init irlmp_init(void)
 {
        IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
        /* Initialize the irlmp structure. */
-       irlmp = kmalloc( sizeof(struct irlmp_cb), GFP_KERNEL);
+       irlmp = kzalloc( sizeof(struct irlmp_cb), GFP_KERNEL);
        if (irlmp == NULL)
                return -ENOMEM;
-       memset(irlmp, 0, sizeof(struct irlmp_cb));
 
        irlmp->magic = LMP_MAGIC;
 
@@ -160,12 +159,11 @@ struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, notify_t *notify, __u8 pid)
                return NULL;
 
        /* Allocate new instance of a LSAP connection */
-       self = kmalloc(sizeof(struct lsap_cb), GFP_ATOMIC);
+       self = kzalloc(sizeof(struct lsap_cb), GFP_ATOMIC);
        if (self == NULL) {
                IRDA_ERROR("%s: can't allocate memory\n", __FUNCTION__);
                return NULL;
        }
-       memset(self, 0, sizeof(struct lsap_cb));
 
        self->magic = LMP_LSAP_MAGIC;
        self->slsap_sel = slsap_sel;
@@ -288,12 +286,11 @@ void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify)
        /*
         *  Allocate new instance of a LSAP connection
         */
-       lap = kmalloc(sizeof(struct lap_cb), GFP_KERNEL);
+       lap = kzalloc(sizeof(struct lap_cb), GFP_KERNEL);
        if (lap == NULL) {
                IRDA_ERROR("%s: unable to kmalloc\n", __FUNCTION__);
                return;
        }
-       memset(lap, 0, sizeof(struct lap_cb));
 
        lap->irlap = irlap;
        lap->magic = LMP_LAP_MAGIC;
@@ -395,7 +392,7 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
 
        /* Any userdata? */
        if (tx_skb == NULL) {
-               tx_skb = dev_alloc_skb(64);
+               tx_skb = alloc_skb(64, GFP_ATOMIC);
                if (!tx_skb)
                        return -ENOMEM;
 
index e53bf9e..a1e502f 100644 (file)
@@ -476,11 +476,10 @@ dev_irnet_open(struct inode *     inode,
 #endif /* SECURE_DEVIRNET */
 
   /* Allocate a private structure for this IrNET instance */
-  ap = kmalloc(sizeof(*ap), GFP_KERNEL);
+  ap = kzalloc(sizeof(*ap), GFP_KERNEL);
   DABORT(ap == NULL, -ENOMEM, FS_ERROR, "Can't allocate struct irnet...\n");
 
   /* initialize the irnet structure */
-  memset(ap, 0, sizeof(*ap));
   ap->file = file;
 
   /* PPP channel setup */
index 49c51c5..42acf1c 100644 (file)
@@ -85,10 +85,9 @@ static pi_param_info_t param_info = { pi_major_call_table, 1, 0x0f, 4 };
  */
 int __init irttp_init(void)
 {
-       irttp = kmalloc(sizeof(struct irttp_cb), GFP_KERNEL);
+       irttp = kzalloc(sizeof(struct irttp_cb), GFP_KERNEL);
        if (irttp == NULL)
                return -ENOMEM;
-       memset(irttp, 0, sizeof(struct irttp_cb));
 
        irttp->magic = TTP_MAGIC;
 
@@ -306,7 +305,8 @@ static inline void irttp_fragment_skb(struct tsap_cb *self,
                IRDA_DEBUG(2, "%s(), fragmenting ...\n", __FUNCTION__);
 
                /* Make new segment */
-               frag = dev_alloc_skb(self->max_seg_size+self->max_header_size);
+               frag = alloc_skb(self->max_seg_size+self->max_header_size,
+                                GFP_ATOMIC);
                if (!frag)
                        return;
 
@@ -389,12 +389,11 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
                return NULL;
        }
 
-       self = kmalloc(sizeof(struct tsap_cb), GFP_ATOMIC);
+       self = kzalloc(sizeof(struct tsap_cb), GFP_ATOMIC);
        if (self == NULL) {
                IRDA_DEBUG(0, "%s(), unable to kmalloc!\n", __FUNCTION__);
                return NULL;
        }
-       memset(self, 0, sizeof(struct tsap_cb));
        spin_lock_init(&self->lock);
 
        /* Initialise todo timer */
@@ -805,7 +804,7 @@ static inline void irttp_give_credit(struct tsap_cb *self)
                   self->send_credit, self->avail_credit, self->remote_credit);
 
        /* Give credit to peer */
-       tx_skb = dev_alloc_skb(64);
+       tx_skb = alloc_skb(64, GFP_ATOMIC);
        if (!tx_skb)
                return;
 
@@ -1094,7 +1093,7 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
 
        /* Any userdata supplied? */
        if (userdata == NULL) {
-               tx_skb = dev_alloc_skb(64);
+               tx_skb = alloc_skb(64, GFP_ATOMIC);
                if (!tx_skb)
                        return -ENOMEM;
 
@@ -1342,7 +1341,7 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
 
        /* Any userdata supplied? */
        if (userdata == NULL) {
-               tx_skb = dev_alloc_skb(64);
+               tx_skb = alloc_skb(64, GFP_ATOMIC);
                if (!tx_skb)
                        return -ENOMEM;
 
@@ -1541,7 +1540,7 @@ int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata,
 
        if (!userdata) {
                struct sk_buff *tx_skb;
-               tx_skb = dev_alloc_skb(64);
+               tx_skb = alloc_skb(64, GFP_ATOMIC);
                if (!tx_skb)
                        return -ENOMEM;
 
@@ -1876,7 +1875,7 @@ static int irttp_seq_open(struct inode *inode, struct file *file)
        int rc = -ENOMEM;
        struct irttp_iter_state *s;
 
-       s = kmalloc(sizeof(*s), GFP_KERNEL);
+       s = kzalloc(sizeof(*s), GFP_KERNEL);
        if (!s)
                goto out;
 
@@ -1886,7 +1885,6 @@ static int irttp_seq_open(struct inode *inode, struct file *file)
 
        seq          = file->private_data;
        seq->private = s;
-       memset(s, 0, sizeof(*s));
 out:
        return rc;
 out_kfree:
index aea6616..d504eed 100644 (file)
@@ -115,14 +115,12 @@ static struct lapb_cb *lapb_devtostruct(struct net_device *dev)
  */
 static struct lapb_cb *lapb_create_cb(void)
 {
-       struct lapb_cb *lapb = kmalloc(sizeof(*lapb), GFP_ATOMIC);
+       struct lapb_cb *lapb = kzalloc(sizeof(*lapb), GFP_ATOMIC);
 
 
        if (!lapb)
                goto out;
 
-       memset(lapb, 0x00, sizeof(*lapb));
-
        skb_queue_head_init(&lapb->write_queue);
        skb_queue_head_init(&lapb->ack_queue);
 
index bd242a4..d12413c 100644 (file)
@@ -33,10 +33,9 @@ unsigned char llc_station_mac_sa[ETH_ALEN];
  */
 static struct llc_sap *llc_sap_alloc(void)
 {
-       struct llc_sap *sap = kmalloc(sizeof(*sap), GFP_ATOMIC);
+       struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC);
 
        if (sap) {
-               memset(sap, 0, sizeof(*sap));
                sap->state = LLC_SAP_STATE_ACTIVE;
                memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN);
                rwlock_init(&sap->sk_list.lock);
index 42a178a..a9894dd 100644 (file)
@@ -386,8 +386,8 @@ config NETFILTER_XT_MATCH_REALM
          <file:Documentation/modules.txt>.  If unsure, say `N'.
 
 config NETFILTER_XT_MATCH_SCTP
-       tristate  '"sctp" protocol match support'
-       depends on NETFILTER_XTABLES
+       tristate  '"sctp" protocol match support (EXPERIMENTAL)'
+       depends on NETFILTER_XTABLES && EXPERIMENTAL
        help
          With this option enabled, you will be able to use the 
          `sctp' match in order to match on SCTP source/destination ports
index 5fcab2e..4ef8366 100644 (file)
@@ -428,6 +428,8 @@ static struct file_operations ct_cpu_seq_fops = {
 
 /* Sysctl support */
 
+int nf_conntrack_checksum = 1;
+
 #ifdef CONFIG_SYSCTL
 
 /* From nf_conntrack_core.c */
@@ -459,8 +461,6 @@ extern unsigned int nf_ct_generic_timeout;
 static int log_invalid_proto_min = 0;
 static int log_invalid_proto_max = 255;
 
-int nf_conntrack_checksum = 1;
-
 static struct ctl_table_header *nf_ct_sysctl_header;
 
 static ctl_table nf_ct_sysctl_table[] = {
index bb6fcee..662a869 100644 (file)
@@ -219,21 +219,20 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info,
 
        switch (verdict & NF_VERDICT_MASK) {
        case NF_ACCEPT:
+       case NF_STOP:
                info->okfn(skb);
+       case NF_STOLEN:
                break;
-
        case NF_QUEUE:
                if (!nf_queue(&skb, elem, info->pf, info->hook, 
                              info->indev, info->outdev, info->okfn,
                              verdict >> NF_VERDICT_BITS))
                        goto next_hook;
                break;
+       default:
+               kfree_skb(skb);
        }
        rcu_read_unlock();
-
-       if (verdict == NF_DROP)
-               kfree_skb(skb);
-
        kfree(info);
        return;
 }
index 5fe4c9d..a9f4f6f 100644 (file)
@@ -113,6 +113,21 @@ checkentry(const char *tablename,
        if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
            info->bitmask & ~XT_PHYSDEV_OP_MASK)
                return 0;
+       if (brnf_deferred_hooks == 0 &&
+           info->bitmask & XT_PHYSDEV_OP_OUT &&
+           (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
+            info->invert & XT_PHYSDEV_OP_BRIDGED) &&
+           hook_mask & ((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
+                        (1 << NF_IP_POST_ROUTING))) {
+               printk(KERN_WARNING "physdev match: using --physdev-out in the "
+                      "OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
+                      "traffic is deprecated and breaks other things, it will "
+                      "be removed in January 2007. See Documentation/"
+                      "feature-removal-schedule.txt for details. This doesn't "
+                      "affect you in case you're using it for purely bridged "
+                      "traffic.\n");
+               brnf_deferred_hooks = 1;
+       }
        return 1;
 }
 
index 3ac703b..d2f5320 100644 (file)
@@ -9,6 +9,8 @@
 #include <linux/skbuff.h>
 #include <linux/if_ether.h>
 #include <linux/if_packet.h>
+#include <linux/in.h>
+#include <linux/ip.h>
 
 #include <linux/netfilter/xt_pkttype.h>
 #include <linux/netfilter/x_tables.h>
@@ -28,9 +30,17 @@ static int match(const struct sk_buff *skb,
       unsigned int protoff,
       int *hotdrop)
 {
+       u_int8_t type;
        const struct xt_pkttype_info *info = matchinfo;
 
-       return (skb->pkt_type == info->pkttype) ^ info->invert;
+       if (skb->pkt_type == PACKET_LOOPBACK)
+               type = (MULTICAST(skb->nh.iph->daddr)
+                       ? PACKET_MULTICAST
+                       : PACKET_BROADCAST);
+       else
+               type = skb->pkt_type;
+
+       return (type == info->pkttype) ^ info->invert;
 }
 
 static struct xt_match pkttype_match = {
index 55c0adc..b85c1f9 100644 (file)
@@ -562,10 +562,9 @@ static int netlink_alloc_groups(struct sock *sk)
        if (err)
                return err;
 
-       nlk->groups = kmalloc(NLGRPSZ(groups), GFP_KERNEL);
+       nlk->groups = kzalloc(NLGRPSZ(groups), GFP_KERNEL);
        if (nlk->groups == NULL)
                return -ENOMEM;
-       memset(nlk->groups, 0, NLGRPSZ(groups));
        nlk->ngroups = groups;
        return 0;
 }
@@ -1393,11 +1392,10 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
        struct sock *sk;
        struct netlink_sock *nlk;
 
-       cb = kmalloc(sizeof(*cb), GFP_KERNEL);
+       cb = kzalloc(sizeof(*cb), GFP_KERNEL);
        if (cb == NULL)
                return -ENOBUFS;
 
-       memset(cb, 0, sizeof(*cb));
        cb->dump = dump;
        cb->done = done;
        cb->nlh = nlh;
@@ -1668,7 +1666,7 @@ static int netlink_seq_open(struct inode *inode, struct file *file)
        struct nl_seq_iter *iter;
        int err;
 
-       iter = kmalloc(sizeof(*iter), GFP_KERNEL);
+       iter = kzalloc(sizeof(*iter), GFP_KERNEL);
        if (!iter)
                return -ENOMEM;
 
@@ -1678,7 +1676,6 @@ static int netlink_seq_open(struct inode *inode, struct file *file)
                return err;
        }
 
-       memset(iter, 0, sizeof(*iter));
        seq = file->private_data;
        seq->private = iter;
        return 0;
@@ -1747,15 +1744,13 @@ static int __init netlink_proto_init(void)
        if (sizeof(struct netlink_skb_parms) > sizeof(dummy_skb->cb))
                netlink_skb_parms_too_large();
 
-       nl_table = kmalloc(sizeof(*nl_table) * MAX_LINKS, GFP_KERNEL);
+       nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL);
        if (!nl_table) {
 enomem:
                printk(KERN_CRIT "netlink_init: Cannot allocate nl_table\n");
                return -ENOMEM;
        }
 
-       memset(nl_table, 0, sizeof(*nl_table) * MAX_LINKS);
-
        if (num_physpages >= (128 * 1024))
                max = num_physpages >> (21 - PAGE_SHIFT);
        else
index 573b572..93d2c55 100644 (file)
@@ -58,13 +58,12 @@ static inline int __rxrpc_create_connection(struct rxrpc_peer *peer,
        _enter("%p",peer);
 
        /* allocate and initialise a connection record */
-       conn = kmalloc(sizeof(struct rxrpc_connection), GFP_KERNEL);
+       conn = kzalloc(sizeof(struct rxrpc_connection), GFP_KERNEL);
        if (!conn) {
                _leave(" = -ENOMEM");
                return -ENOMEM;
        }
 
-       memset(conn, 0, sizeof(struct rxrpc_connection));
        atomic_set(&conn->usage, 1);
 
        INIT_LIST_HEAD(&conn->link);
@@ -535,13 +534,12 @@ int rxrpc_conn_newmsg(struct rxrpc_connection *conn,
                return -EINVAL;
        }
 
-       msg = kmalloc(sizeof(struct rxrpc_message), alloc_flags);
+       msg = kzalloc(sizeof(struct rxrpc_message), alloc_flags);
        if (!msg) {
                _leave(" = -ENOMEM");
                return -ENOMEM;
        }
 
-       memset(msg, 0, sizeof(*msg));
        atomic_set(&msg->usage, 1);
 
        INIT_LIST_HEAD(&msg->link);
index ed38f5b..8a27515 100644 (file)
@@ -58,13 +58,12 @@ static int __rxrpc_create_peer(struct rxrpc_transport *trans, __be32 addr,
        _enter("%p,%08x", trans, ntohl(addr));
 
        /* allocate and initialise a peer record */
-       peer = kmalloc(sizeof(struct rxrpc_peer), GFP_KERNEL);
+       peer = kzalloc(sizeof(struct rxrpc_peer), GFP_KERNEL);
        if (!peer) {
                _leave(" = -ENOMEM");
                return -ENOMEM;
        }
 
-       memset(peer, 0, sizeof(struct rxrpc_peer));
        atomic_set(&peer->usage, 1);
 
        INIT_LIST_HEAD(&peer->link);
index dbe6105..465efc8 100644 (file)
@@ -68,11 +68,10 @@ int rxrpc_create_transport(unsigned short port,
 
        _enter("%hu", port);
 
-       trans = kmalloc(sizeof(struct rxrpc_transport), GFP_KERNEL);
+       trans = kzalloc(sizeof(struct rxrpc_transport), GFP_KERNEL);
        if (!trans)
                return -ENOMEM;
 
-       memset(trans, 0, sizeof(struct rxrpc_transport));
        atomic_set(&trans->usage, 1);
        INIT_LIST_HEAD(&trans->services);
        INIT_LIST_HEAD(&trans->link);
@@ -312,13 +311,12 @@ static int rxrpc_incoming_msg(struct rxrpc_transport *trans,
 
        _enter("");
 
-       msg = kmalloc(sizeof(struct rxrpc_message), GFP_KERNEL);
+       msg = kzalloc(sizeof(struct rxrpc_message), GFP_KERNEL);
        if (!msg) {
                _leave(" = -ENOMEM");
                return -ENOMEM;
        }
 
-       memset(msg, 0, sizeof(*msg));
        atomic_set(&msg->usage, 1);
        list_add_tail(&msg->link,msgq);
 
index 9affeee..a2587b5 100644 (file)
@@ -312,10 +312,9 @@ struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est,
        }
 
        *err = -ENOMEM;
-       a = kmalloc(sizeof(*a), GFP_KERNEL);
+       a = kzalloc(sizeof(*a), GFP_KERNEL);
        if (a == NULL)
                goto err_mod;
-       memset(a, 0, sizeof(*a));
 
        /* backward compatibility for policer */
        if (name == NULL)
@@ -492,10 +491,9 @@ tcf_action_get_1(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int *err)
        index = *(int *)RTA_DATA(tb[TCA_ACT_INDEX - 1]);
 
        *err = -ENOMEM;
-       a = kmalloc(sizeof(struct tc_action), GFP_KERNEL);
+       a = kzalloc(sizeof(struct tc_action), GFP_KERNEL);
        if (a == NULL)
                return NULL;
-       memset(a, 0, sizeof(struct tc_action));
 
        *err = -EINVAL;
        a->ops = tc_lookup_action(tb[TCA_ACT_KIND - 1]);
@@ -531,12 +529,11 @@ static struct tc_action *create_a(int i)
 {
        struct tc_action *act;
 
-       act = kmalloc(sizeof(*act), GFP_KERNEL);
+       act = kzalloc(sizeof(*act), GFP_KERNEL);
        if (act == NULL) {
                printk("create_a: failed to alloc!\n");
                return NULL;
        }
-       memset(act, 0, sizeof(*act));
        act->order = i;
        return act;
 }
index 58b3a86..f257475 100644 (file)
@@ -209,10 +209,9 @@ tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,int bind, int ref)
        s = sizeof(*opt) + p->nkeys * sizeof(struct tc_pedit_key);
 
        /* netlink spinlocks held above us - must use ATOMIC */
-       opt = kmalloc(s, GFP_ATOMIC);
+       opt = kzalloc(s, GFP_ATOMIC);
        if (opt == NULL)
                return -ENOBUFS;
-       memset(opt, 0, s);
 
        memcpy(opt->keys, p->keys, p->nkeys * sizeof(struct tc_pedit_key));
        opt->index = p->index;
index 47e00bd..da905d7 100644 (file)
@@ -196,10 +196,9 @@ static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,
                return ret;
        }
 
-       p = kmalloc(sizeof(*p), GFP_KERNEL);
+       p = kzalloc(sizeof(*p), GFP_KERNEL);
        if (p == NULL)
                return -ENOMEM;
-       memset(p, 0, sizeof(*p));
 
        ret = ACT_P_CREATED;
        p->refcnt = 1;
@@ -429,11 +428,10 @@ struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est)
                return p;
        }
 
-       p = kmalloc(sizeof(*p), GFP_KERNEL);
+       p = kzalloc(sizeof(*p), GFP_KERNEL);
        if (p == NULL)
                return NULL;
 
-       memset(p, 0, sizeof(*p));
        p->refcnt = 1;
        spin_lock_init(&p->lock);
        p->stats_lock = &p->lock;
index 61507f0..86cac49 100644 (file)
@@ -178,19 +178,17 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle,
 
        err = -ENOBUFS;
        if (head == NULL) {
-               head = kmalloc(sizeof(*head), GFP_KERNEL);
+               head = kzalloc(sizeof(*head), GFP_KERNEL);
                if (head == NULL)
                        goto errout;
 
-               memset(head, 0, sizeof(*head));
                INIT_LIST_HEAD(&head->flist);
                tp->root = head;
        }
 
-       f = kmalloc(sizeof(*f), GFP_KERNEL);
+       f = kzalloc(sizeof(*f), GFP_KERNEL);
        if (f == NULL)
                goto errout;
-       memset(f, 0, sizeof(*f));
 
        err = -EINVAL;
        if (handle)
index d41de91..e6973d9 100644 (file)
@@ -267,20 +267,18 @@ static int fw_change(struct tcf_proto *tp, unsigned long base,
                return -EINVAL;
 
        if (head == NULL) {
-               head = kmalloc(sizeof(struct fw_head), GFP_KERNEL);
+               head = kzalloc(sizeof(struct fw_head), GFP_KERNEL);
                if (head == NULL)
                        return -ENOBUFS;
-               memset(head, 0, sizeof(*head));
 
                tcf_tree_lock(tp);
                tp->root = head;
                tcf_tree_unlock(tp);
        }
 
-       f = kmalloc(sizeof(struct fw_filter), GFP_KERNEL);
+       f = kzalloc(sizeof(struct fw_filter), GFP_KERNEL);
        if (f == NULL)
                return -ENOBUFS;
-       memset(f, 0, sizeof(*f));
 
        f->id = handle;
 
index c2e7190..d3aea73 100644 (file)
@@ -396,10 +396,9 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base,
        h1 = to_hash(nhandle);
        if ((b = head->table[h1]) == NULL) {
                err = -ENOBUFS;
-               b = kmalloc(sizeof(struct route4_bucket), GFP_KERNEL);
+               b = kzalloc(sizeof(struct route4_bucket), GFP_KERNEL);
                if (b == NULL)
                        goto errout;
-               memset(b, 0, sizeof(*b));
 
                tcf_tree_lock(tp);
                head->table[h1] = b;
@@ -475,20 +474,18 @@ static int route4_change(struct tcf_proto *tp, unsigned long base,
 
        err = -ENOBUFS;
        if (head == NULL) {
-               head = kmalloc(sizeof(struct route4_head), GFP_KERNEL);
+               head = kzalloc(sizeof(struct route4_head), GFP_KERNEL);
                if (head == NULL)
                        goto errout;
-               memset(head, 0, sizeof(struct route4_head));
 
                tcf_tree_lock(tp);
                tp->root = head;
                tcf_tree_unlock(tp);
        }
 
-       f = kmalloc(sizeof(struct route4_filter), GFP_KERNEL);
+       f = kzalloc(sizeof(struct route4_filter), GFP_KERNEL);
        if (f == NULL)
                goto errout;
-       memset(f, 0, sizeof(*f));
 
        err = route4_set_parms(tp, base, f, handle, head, tb,
                tca[TCA_RATE-1], 1);
index ba87419..6e230ec 100644 (file)
@@ -240,9 +240,8 @@ static int rsvp_init(struct tcf_proto *tp)
 {
        struct rsvp_head *data;
 
-       data = kmalloc(sizeof(struct rsvp_head), GFP_KERNEL);
+       data = kzalloc(sizeof(struct rsvp_head), GFP_KERNEL);
        if (data) {
-               memset(data, 0, sizeof(struct rsvp_head));
                tp->root = data;
                return 0;
        }
@@ -446,11 +445,10 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base,
                goto errout2;
 
        err = -ENOBUFS;
-       f = kmalloc(sizeof(struct rsvp_filter), GFP_KERNEL);
+       f = kzalloc(sizeof(struct rsvp_filter), GFP_KERNEL);
        if (f == NULL)
                goto errout2;
 
-       memset(f, 0, sizeof(*f));
        h2 = 16;
        if (tb[TCA_RSVP_SRC-1]) {
                err = -EINVAL;
@@ -532,10 +530,9 @@ insert:
        /* No session found. Create new one. */
 
        err = -ENOBUFS;
-       s = kmalloc(sizeof(struct rsvp_session), GFP_KERNEL);
+       s = kzalloc(sizeof(struct rsvp_session), GFP_KERNEL);
        if (s == NULL)
                goto errout;
-       memset(s, 0, sizeof(*s));
        memcpy(s->dst, dst, sizeof(s->dst));
 
        if (pinfo) {
index 7870e7b..5af8a59 100644 (file)
@@ -148,11 +148,10 @@ static int tcindex_init(struct tcf_proto *tp)
        struct tcindex_data *p;
 
        DPRINTK("tcindex_init(tp %p)\n",tp);
-       p = kmalloc(sizeof(struct tcindex_data),GFP_KERNEL);
+       p = kzalloc(sizeof(struct tcindex_data),GFP_KERNEL);
        if (!p)
                return -ENOMEM;
 
-       memset(p, 0, sizeof(*p));
        p->mask = 0xffff;
        p->hash = DEFAULT_HASH_SIZE;
        p->fall_through = 1;
@@ -296,16 +295,14 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle,
        err = -ENOMEM;
        if (!cp.perfect && !cp.h) {
                if (valid_perfect_hash(&cp)) {
-                       cp.perfect = kmalloc(cp.hash * sizeof(*r), GFP_KERNEL);
+                       cp.perfect = kcalloc(cp.hash, sizeof(*r), GFP_KERNEL);
                        if (!cp.perfect)
                                goto errout;
-                       memset(cp.perfect, 0, cp.hash * sizeof(*r));
                        balloc = 1;
                } else {
-                       cp.h = kmalloc(cp.hash * sizeof(f), GFP_KERNEL);
+                       cp.h = kcalloc(cp.hash, sizeof(f), GFP_KERNEL);
                        if (!cp.h)
                                goto errout;
-                       memset(cp.h, 0, cp.hash * sizeof(f));
                        balloc = 2;
                }
        }
@@ -316,10 +313,9 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle,
                r = tcindex_lookup(&cp, handle) ? : &new_filter_result;
 
        if (r == &new_filter_result) {
-               f = kmalloc(sizeof(*f), GFP_KERNEL);
+               f = kzalloc(sizeof(*f), GFP_KERNEL);
                if (!f)
                        goto errout_alloc;
-               memset(f, 0, sizeof(*f));
        }
 
        if (tb[TCA_TCINDEX_CLASSID-1]) {
index d712edc..eea3669 100644 (file)
@@ -307,23 +307,21 @@ static int u32_init(struct tcf_proto *tp)
                if (tp_c->q == tp->q)
                        break;
 
-       root_ht = kmalloc(sizeof(*root_ht), GFP_KERNEL);
+       root_ht = kzalloc(sizeof(*root_ht), GFP_KERNEL);
        if (root_ht == NULL)
                return -ENOBUFS;
 
-       memset(root_ht, 0, sizeof(*root_ht));
        root_ht->divisor = 0;
        root_ht->refcnt++;
        root_ht->handle = tp_c ? gen_new_htid(tp_c) : 0x80000000;
        root_ht->prio = tp->prio;
 
        if (tp_c == NULL) {
-               tp_c = kmalloc(sizeof(*tp_c), GFP_KERNEL);
+               tp_c = kzalloc(sizeof(*tp_c), GFP_KERNEL);
                if (tp_c == NULL) {
                        kfree(root_ht);
                        return -ENOBUFS;
                }
-               memset(tp_c, 0, sizeof(*tp_c));
                tp_c->q = tp->q;
                tp_c->next = u32_list;
                u32_list = tp_c;
@@ -571,10 +569,9 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
                        if (handle == 0)
                                return -ENOMEM;
                }
-               ht = kmalloc(sizeof(*ht) + divisor*sizeof(void*), GFP_KERNEL);
+               ht = kzalloc(sizeof(*ht) + divisor*sizeof(void*), GFP_KERNEL);
                if (ht == NULL)
                        return -ENOBUFS;
-               memset(ht, 0, sizeof(*ht) + divisor*sizeof(void*));
                ht->tp_c = tp_c;
                ht->refcnt = 0;
                ht->divisor = divisor;
@@ -617,18 +614,16 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
 
        s = RTA_DATA(tb[TCA_U32_SEL-1]);
 
-       n = kmalloc(sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key), GFP_KERNEL);
+       n = kzalloc(sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key), GFP_KERNEL);
        if (n == NULL)
                return -ENOBUFS;
 
-       memset(n, 0, sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key));
 #ifdef CONFIG_CLS_U32_PERF
-       n->pf = kmalloc(sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(u64), GFP_KERNEL);
+       n->pf = kzalloc(sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(u64), GFP_KERNEL);
        if (n->pf == NULL) {
                kfree(n);
                return -ENOBUFS;
        }
-       memset(n->pf, 0, sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(u64));
 #endif
 
        memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key));
index 6983729..61e3b74 100644 (file)
@@ -773,10 +773,9 @@ static int em_meta_change(struct tcf_proto *tp, void *data, int len,
            TCF_META_ID(hdr->right.kind) > TCF_META_ID_MAX)
                goto errout;
 
-       meta = kmalloc(sizeof(*meta), GFP_KERNEL);
+       meta = kzalloc(sizeof(*meta), GFP_KERNEL);
        if (meta == NULL)
                goto errout;
-       memset(meta, 0, sizeof(*meta));
 
        memcpy(&meta->lvalue.hdr, &hdr->left, sizeof(hdr->left));
        memcpy(&meta->rvalue.hdr, &hdr->right, sizeof(hdr->right));
index 2405a86..0fd0768 100644 (file)
@@ -321,10 +321,9 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta,
        list_len = RTA_PAYLOAD(rt_list);
        matches_len = tree_hdr->nmatches * sizeof(*em);
 
-       tree->matches = kmalloc(matches_len, GFP_KERNEL);
+       tree->matches = kzalloc(matches_len, GFP_KERNEL);
        if (tree->matches == NULL)
                goto errout;
-       memset(tree->matches, 0, matches_len);
 
        /* We do not use rtattr_parse_nested here because the maximum
         * number of attributes is unknown. This saves us the allocation
index 5d3ae03..0ebc98e 100644 (file)
@@ -139,11 +139,10 @@ int qdisc_new_estimator(struct tc_stats *stats, spinlock_t *stats_lock, struct r
        if (parm->interval < -2 || parm->interval > 3)
                return -EINVAL;
 
-       est = kmalloc(sizeof(*est), GFP_KERNEL);
+       est = kzalloc(sizeof(*est), GFP_KERNEL);
        if (est == NULL)
                return -ENOBUFS;
 
-       memset(est, 0, sizeof(*est));
        est->interval = parm->interval + 2;
        est->stats = stats;
        est->stats_lock = stats_lock;
index 80b7f6a..bac881b 100644 (file)
@@ -1926,10 +1926,9 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
        }
 
        err = -ENOBUFS;
-       cl = kmalloc(sizeof(*cl), GFP_KERNEL);
+       cl = kzalloc(sizeof(*cl), GFP_KERNEL);
        if (cl == NULL)
                goto failure;
-       memset(cl, 0, sizeof(*cl));
        cl->R_tab = rtab;
        rtab = NULL;
        cl->refcnt = 1;
index d735f51..0834c2e 100644 (file)
@@ -432,10 +432,9 @@ struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops)
        size = QDISC_ALIGN(sizeof(*sch));
        size += ops->priv_size + (QDISC_ALIGNTO - 1);
 
-       p = kmalloc(size, GFP_KERNEL);
+       p = kzalloc(size, GFP_KERNEL);
        if (!p)
                goto errout;
-       memset(p, 0, size);
        sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p);
        sch->padded = (char *) sch - (char *) p;
 
index 0cafdd5..18e81a8 100644 (file)
@@ -406,10 +406,9 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp,
        struct gred_sched_data *q;
 
        if (table->tab[dp] == NULL) {
-               table->tab[dp] = kmalloc(sizeof(*q), GFP_KERNEL);
+               table->tab[dp] = kzalloc(sizeof(*q), GFP_KERNEL);
                if (table->tab[dp] == NULL)
                        return -ENOMEM;
-               memset(table->tab[dp], 0, sizeof(*q));
        }
 
        q = table->tab[dp];
index 6b1b4a9..6a6735a 100644 (file)
@@ -1123,10 +1123,9 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
        if (rsc == NULL && fsc == NULL)
                return -EINVAL;
 
-       cl = kmalloc(sizeof(struct hfsc_class), GFP_KERNEL);
+       cl = kzalloc(sizeof(struct hfsc_class), GFP_KERNEL);
        if (cl == NULL)
                return -ENOBUFS;
-       memset(cl, 0, sizeof(struct hfsc_class));
 
        if (rsc != NULL)
                hfsc_change_rsc(cl, rsc, 0);
index cc5f339..880a339 100644 (file)
@@ -1559,10 +1559,9 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
                        goto failure;
                }
                err = -ENOBUFS;
-               if ((cl = kmalloc(sizeof(*cl), GFP_KERNEL)) == NULL)
+               if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL)
                        goto failure;
                
-               memset(cl, 0, sizeof(*cl));
                cl->refcnt = 1;
                INIT_LIST_HEAD(&cl->sibling);
                INIT_LIST_HEAD(&cl->hlist);
index c5bd806..a08ec4c 100644 (file)
@@ -148,7 +148,8 @@ static long tabledist(unsigned long mu, long sigma,
 static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
-       struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb;
+       /* We don't fill cb now as skb_unshare() may invalidate it */
+       struct netem_skb_cb *cb;
        struct sk_buff *skb2;
        int ret;
        int count = 1;
@@ -200,6 +201,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8);
        }
 
+       cb = (struct netem_skb_cb *)skb->cb;
        if (q->gap == 0                 /* not doing reordering */
            || q->counter < q->gap      /* inside last reordering gap */
            || q->reorder < get_crandom(&q->reorder_cor)) {
index 9d05e13..27329ce 100644 (file)
@@ -441,7 +441,8 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
        /* If the primary path is changing, assume that the
         * user wants to use this new path.
         */
-       if (transport->state != SCTP_INACTIVE)
+       if ((transport->state == SCTP_ACTIVE) ||
+           (transport->state == SCTP_UNKNOWN))
                asoc->peer.active_path = transport;
 
        /*
@@ -532,11 +533,11 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
        port = addr->v4.sin_port;
 
        SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_add_peer:association %p addr: ",
-                                " port: %d state:%s\n",
+                                " port: %d state:%d\n",
                                 asoc,
                                 addr,
                                 addr->v4.sin_port,
-                                peer_state == SCTP_UNKNOWN?"UNKNOWN":"ACTIVE");
+                                peer_state);
 
        /* Set the port if it has not been set yet.  */
        if (0 == asoc->peer.port)
@@ -545,9 +546,12 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
        /* Check to see if this is a duplicate. */
        peer = sctp_assoc_lookup_paddr(asoc, addr);
        if (peer) {
-               if (peer_state == SCTP_ACTIVE &&
-                   peer->state == SCTP_UNKNOWN)
-                    peer->state = SCTP_ACTIVE;
+               if (peer->state == SCTP_UNKNOWN) {
+                       if (peer_state == SCTP_ACTIVE)
+                               peer->state = SCTP_ACTIVE;
+                       if (peer_state == SCTP_UNCONFIRMED)
+                               peer->state = SCTP_UNCONFIRMED;
+               }
                return peer;
        }
 
@@ -739,7 +743,8 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
        list_for_each(pos, &asoc->peer.transport_addr_list) {
                t = list_entry(pos, struct sctp_transport, transports);
 
-               if (t->state == SCTP_INACTIVE)
+               if ((t->state == SCTP_INACTIVE) ||
+                   (t->state == SCTP_UNCONFIRMED))
                        continue;
                if (!first || t->last_time_heard > first->last_time_heard) {
                        second = first;
@@ -759,7 +764,8 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
         * [If the primary is active but not most recent, bump the most
         * recently used transport.]
         */
-       if (asoc->peer.primary_path->state != SCTP_INACTIVE &&
+       if (((asoc->peer.primary_path->state == SCTP_ACTIVE) ||
+            (asoc->peer.primary_path->state == SCTP_UNKNOWN)) &&
            first != asoc->peer.primary_path) {
                second = first;
                first = asoc->peer.primary_path;
@@ -1054,7 +1060,7 @@ void sctp_assoc_update(struct sctp_association *asoc,
                                           transports);
                        if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr))
                                sctp_assoc_add_peer(asoc, &trans->ipaddr,
-                                                   GFP_ATOMIC, SCTP_ACTIVE);
+                                                   GFP_ATOMIC, trans->state);
                }
 
                asoc->ctsn_ack_point = asoc->next_tsn - 1;
@@ -1094,7 +1100,8 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
 
                /* Try to find an active transport. */
 
-               if (t->state != SCTP_INACTIVE) {
+               if ((t->state == SCTP_ACTIVE) ||
+                   (t->state == SCTP_UNKNOWN)) {
                        break;
                } else {
                        /* Keep track of the next transport in case
index 2b96262..2b9c12a 100644 (file)
@@ -146,7 +146,7 @@ void sctp_bind_addr_free(struct sctp_bind_addr *bp)
 
 /* Add an address to the bind address list in the SCTP_bind_addr structure. */
 int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
-                      gfp_t gfp)
+                      __u8 use_as_src, gfp_t gfp)
 {
        struct sctp_sockaddr_entry *addr;
 
@@ -163,6 +163,8 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
        if (!addr->a.v4.sin_port)
                addr->a.v4.sin_port = bp->port;
 
+       addr->use_as_src = use_as_src;
+
        INIT_LIST_HEAD(&addr->list);
        list_add_tail(&addr->list, &bp->address_list);
        SCTP_DBG_OBJCNT_INC(addr);
@@ -274,7 +276,7 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
                }
 
                af->from_addr_param(&addr, rawaddr, port, 0);
-               retval = sctp_add_bind_addr(bp, &addr, gfp);
+               retval = sctp_add_bind_addr(bp, &addr, 1, gfp);
                if (retval) {
                        /* Can't finish building the list, clean up. */
                        sctp_bind_addr_clean(bp);
@@ -367,7 +369,7 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
                    (((AF_INET6 == addr->sa.sa_family) &&
                      (flags & SCTP_ADDR6_ALLOWED) &&
                      (flags & SCTP_ADDR6_PEERSUPP))))
-                       error = sctp_add_bind_addr(dest, addr, gfp);
+                       error = sctp_add_bind_addr(dest, addr, 1, gfp);
        }
 
        return error;
index 67bd530..ffda1d6 100644 (file)
@@ -158,6 +158,12 @@ void sctp_endpoint_add_asoc(struct sctp_endpoint *ep,
 void sctp_endpoint_free(struct sctp_endpoint *ep)
 {
        ep->base.dead = 1;
+
+       ep->base.sk->sk_state = SCTP_SS_CLOSED;
+
+       /* Unlink this endpoint, so we can't find it again! */
+       sctp_unhash_endpoint(ep);
+
        sctp_endpoint_put(ep);
 }
 
@@ -166,11 +172,6 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
 {
        SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return);
 
-       ep->base.sk->sk_state = SCTP_SS_CLOSED;
-
-       /* Unlink this endpoint, so we can't find it again! */
-       sctp_unhash_endpoint(ep);
-
        /* Free up the HMAC transform. */
        sctp_crypto_free_tfm(sctp_sk(ep->base.sk)->hmac);
 
index 8ef0807..99c0cef 100644 (file)
@@ -290,7 +290,8 @@ static void sctp_v6_get_saddr(struct sctp_association *asoc,
        sctp_read_lock(addr_lock);
        list_for_each(pos, &bp->address_list) {
                laddr = list_entry(pos, struct sctp_sockaddr_entry, list);
-               if ((laddr->a.sa.sa_family == AF_INET6) &&
+               if ((laddr->use_as_src) &&
+                   (laddr->a.sa.sa_family == AF_INET6) &&
                    (scope <= sctp_scope(&laddr->a))) {
                        bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
                        if (!baddr || (matchlen < bmatchlen)) {
index e5faa35..30b710c 100644 (file)
@@ -691,7 +691,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
 
                if (!new_transport) {
                        new_transport = asoc->peer.active_path;
-               } else if (new_transport->state == SCTP_INACTIVE) {
+               } else if ((new_transport->state == SCTP_INACTIVE) ||
+                          (new_transport->state == SCTP_UNCONFIRMED)) {
                        /* If the chunk is Heartbeat or Heartbeat Ack,
                         * send it to chunk->transport, even if it's
                         * inactive.
@@ -848,7 +849,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
                         */
                        new_transport = chunk->transport;
                        if (!new_transport ||
-                           new_transport->state == SCTP_INACTIVE)
+                           ((new_transport->state == SCTP_INACTIVE) ||
+                            (new_transport->state == SCTP_UNCONFIRMED)))
                                new_transport = asoc->peer.active_path;
 
                        /* Change packets if necessary.  */
@@ -1464,7 +1466,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
                        /* Mark the destination transport address as
                         * active if it is not so marked.
                         */
-                       if (transport->state == SCTP_INACTIVE) {
+                       if ((transport->state == SCTP_INACTIVE) ||
+                           (transport->state == SCTP_UNCONFIRMED)) {
                                sctp_assoc_control_transport(
                                        transport->asoc,
                                        transport,
index 816c033..1ab03a2 100644 (file)
@@ -240,7 +240,7 @@ int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope,
                            (((AF_INET6 == addr->a.sa.sa_family) &&
                              (copy_flags & SCTP_ADDR6_ALLOWED) &&
                              (copy_flags & SCTP_ADDR6_PEERSUPP)))) {
-                               error = sctp_add_bind_addr(bp, &addr->a, 
+                               error = sctp_add_bind_addr(bp, &addr->a, 1,
                                                           GFP_ATOMIC);
                                if (error)
                                        goto end_copy;
@@ -486,6 +486,8 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
                list_for_each(pos, &bp->address_list) {
                        laddr = list_entry(pos, struct sctp_sockaddr_entry,
                                           list);
+                       if (!laddr->use_as_src)
+                               continue;
                        sctp_v4_dst_saddr(&dst_saddr, dst, bp->port);
                        if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a))
                                goto out_unlock;
@@ -506,7 +508,8 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
        list_for_each(pos, &bp->address_list) {
                laddr = list_entry(pos, struct sctp_sockaddr_entry, list);
 
-               if (AF_INET == laddr->a.sa.sa_family) {
+               if ((laddr->use_as_src) &&
+                   (AF_INET == laddr->a.sa.sa_family)) {
                        fl.fl4_src = laddr->a.v4.sin_addr.s_addr;
                        if (!ip_route_output_key(&rt, &fl)) {
                                dst = &rt->u.dst;
index 2a87736..4f11f58 100644 (file)
@@ -1493,7 +1493,7 @@ no_hmac:
 
        /* Also, add the destination address. */
        if (list_empty(&retval->base.bind_addr.address_list)) {
-               sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest,
+               sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, 1,
                                   GFP_ATOMIC);
        }
 
@@ -2017,7 +2017,7 @@ static int sctp_process_param(struct sctp_association *asoc,
                af->from_addr_param(&addr, param.addr, asoc->peer.port, 0);
                scope = sctp_scope(peer_addr);
                if (sctp_in_scope(&addr, scope))
-                       if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_ACTIVE))
+                       if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_UNCONFIRMED))
                                return 0;
                break;
 
@@ -2418,7 +2418,7 @@ static __u16 sctp_process_asconf_param(struct sctp_association *asoc,
                 * Due to Resource Shortage'.
                 */
 
-               peer = sctp_assoc_add_peer(asoc, &addr, GFP_ATOMIC, SCTP_ACTIVE);
+               peer = sctp_assoc_add_peer(asoc, &addr, GFP_ATOMIC, SCTP_UNCONFIRMED);
                if (!peer)
                        return SCTP_ERROR_RSRC_LOW;
 
@@ -2565,6 +2565,7 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
        union sctp_addr_param *addr_param;
        struct list_head *pos;
        struct sctp_transport *transport;
+       struct sctp_sockaddr_entry *saddr;
        int retval = 0;
 
        addr_param = (union sctp_addr_param *)
@@ -2578,7 +2579,11 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
        case SCTP_PARAM_ADD_IP:
                sctp_local_bh_disable();
                sctp_write_lock(&asoc->base.addr_lock);
-               retval = sctp_add_bind_addr(bp, &addr, GFP_ATOMIC);
+               list_for_each(pos, &bp->address_list) {
+                       saddr = list_entry(pos, struct sctp_sockaddr_entry, list);
+                       if (sctp_cmp_addr_exact(&saddr->a, &addr))
+                               saddr->use_as_src = 1;
+               }
                sctp_write_unlock(&asoc->base.addr_lock);
                sctp_local_bh_enable();
                break;
@@ -2591,6 +2596,7 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
                list_for_each(pos, &asoc->peer.transport_addr_list) {
                        transport = list_entry(pos, struct sctp_transport,
                                                 transports);
+                       dst_release(transport->dst);
                        sctp_transport_route(transport, NULL,
                                             sctp_sk(asoc->base.sk));
                }
index c5beb2a..9c10bde 100644 (file)
@@ -430,7 +430,11 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
        /* The check for association's overall error counter exceeding the
         * threshold is done in the state function.
         */
-       asoc->overall_error_count++;
+       /* When probing UNCONFIRMED addresses, the association overall
+        * error count is NOT incremented
+        */
+       if (transport->state != SCTP_UNCONFIRMED)
+               asoc->overall_error_count++;
 
        if (transport->state != SCTP_INACTIVE &&
            (transport->error_count++ >= transport->pathmaxrxt)) {
@@ -610,7 +614,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
        /* Mark the destination transport address as active if it is not so
         * marked.
         */
-       if (t->state == SCTP_INACTIVE)
+       if ((t->state == SCTP_INACTIVE) || (t->state == SCTP_UNCONFIRMED))
                sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP,
                                             SCTP_HEARTBEAT_SUCCESS);
 
@@ -620,6 +624,10 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
         */
        hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
        sctp_transport_update_rto(t, (jiffies - hbinfo->sent_at));
+
+       /* Update the heartbeat timer.  */
+       if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t)))
+               sctp_transport_hold(t);
 }
 
 /* Helper function to do a transport reset at the expiry of the hearbeat
index 9e58144..ead3f1b 100644 (file)
@@ -846,6 +846,7 @@ static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
        hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t));
        hbinfo.daddr = transport->ipaddr;
        hbinfo.sent_at = jiffies;
+       hbinfo.hb_nonce = transport->hb_nonce;
 
        /* Send a heartbeat to our peer.  */
        paylen = sizeof(sctp_sender_hb_info_t);
@@ -1048,6 +1049,10 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
                return SCTP_DISPOSITION_DISCARD;
        }
 
+       /* Validate the 64-bit random nonce. */
+       if (hbinfo->hb_nonce != link->hb_nonce)
+               return SCTP_DISPOSITION_DISCARD;
+
        max_interval = link->hbinterval + link->rto;
 
        /* Check if the timestamp looks valid.  */
@@ -5278,7 +5283,6 @@ static int sctp_eat_data(const struct sctp_association *asoc,
        datalen -= sizeof(sctp_data_chunk_t);
 
        deliver = SCTP_CMD_CHUNK_ULP;
-       chunk->data_accepted = 1;
 
        /* Think about partial delivery. */
        if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) {
@@ -5357,6 +5361,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
        if (SCTP_CMD_CHUNK_ULP == deliver)
                sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
 
+       chunk->data_accepted = 1;
+
        /* Note: Some chunks may get overcounted (if we drop) or overcounted
         * if we renege and the chunk arrives again.
         */
index 0a2c71d..54722e6 100644 (file)
@@ -369,7 +369,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
 
        /* Use GFP_ATOMIC since BHs are disabled.  */
        addr->v4.sin_port = ntohs(addr->v4.sin_port);
-       ret = sctp_add_bind_addr(bp, addr, GFP_ATOMIC);
+       ret = sctp_add_bind_addr(bp, addr, 1, GFP_ATOMIC);
        addr->v4.sin_port = htons(addr->v4.sin_port);
        sctp_write_unlock(&ep->base.addr_lock);
        sctp_local_bh_enable();
@@ -491,6 +491,7 @@ static int sctp_send_asconf_add_ip(struct sock              *sk,
        struct sctp_chunk               *chunk;
        struct sctp_sockaddr_entry      *laddr;
        union sctp_addr                 *addr;
+       union sctp_addr                 saveaddr;
        void                            *addr_buf;
        struct sctp_af                  *af;
        struct list_head                *pos;
@@ -558,14 +559,26 @@ static int sctp_send_asconf_add_ip(struct sock            *sk,
                }
 
                retval = sctp_send_asconf(asoc, chunk);
+               if (retval)
+                       goto out;
 
-               /* FIXME: After sending the add address ASCONF chunk, we
-                * cannot append the address to the association's binding
-                * address list, because the new address may be used as the
-                * source of a message sent to the peer before the ASCONF
-                * chunk is received by the peer.  So we should wait until
-                * ASCONF_ACK is received.
+               /* Add the new addresses to the bind address list with
+                * use_as_src set to 0.
                 */
+               sctp_local_bh_disable();
+               sctp_write_lock(&asoc->base.addr_lock);
+               addr_buf = addrs;
+               for (i = 0; i < addrcnt; i++) {
+                       addr = (union sctp_addr *)addr_buf;
+                       af = sctp_get_af_specific(addr->v4.sin_family);
+                       memcpy(&saveaddr, addr, af->sockaddr_len);
+                       saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port);
+                       retval = sctp_add_bind_addr(bp, &saveaddr, 0,
+                                                   GFP_ATOMIC);
+                       addr_buf += af->sockaddr_len;
+               }
+               sctp_write_unlock(&asoc->base.addr_lock);
+               sctp_local_bh_enable();
        }
 
 out:
@@ -676,12 +689,15 @@ static int sctp_send_asconf_del_ip(struct sock            *sk,
        struct sctp_sock        *sp;
        struct sctp_endpoint    *ep;
        struct sctp_association *asoc;
+       struct sctp_transport   *transport;
        struct sctp_bind_addr   *bp;
        struct sctp_chunk       *chunk;
        union sctp_addr         *laddr;
+       union sctp_addr         saveaddr;
        void                    *addr_buf;
        struct sctp_af          *af;
-       struct list_head        *pos;
+       struct list_head        *pos, *pos1;
+       struct sctp_sockaddr_entry *saddr;
        int                     i;
        int                     retval = 0;
 
@@ -748,14 +764,42 @@ static int sctp_send_asconf_del_ip(struct sock            *sk,
                        goto out;
                }
 
-               retval = sctp_send_asconf(asoc, chunk);
+               /* Reset use_as_src flag for the addresses in the bind address
+                * list that are to be deleted.
+                */
+               sctp_local_bh_disable();
+               sctp_write_lock(&asoc->base.addr_lock);
+               addr_buf = addrs;
+               for (i = 0; i < addrcnt; i++) {
+                       laddr = (union sctp_addr *)addr_buf;
+                       af = sctp_get_af_specific(laddr->v4.sin_family);
+                       memcpy(&saveaddr, laddr, af->sockaddr_len);
+                       saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port);
+                       list_for_each(pos1, &bp->address_list) {
+                               saddr = list_entry(pos1,
+                                                  struct sctp_sockaddr_entry,
+                                                  list);
+                               if (sctp_cmp_addr_exact(&saddr->a, &saveaddr))
+                                       saddr->use_as_src = 0;
+                       }
+                       addr_buf += af->sockaddr_len;
+               }
+               sctp_write_unlock(&asoc->base.addr_lock);
+               sctp_local_bh_enable();
 
-               /* FIXME: After sending the delete address ASCONF chunk, we
-                * cannot remove the addresses from the association's bind
-                * address list, because there maybe some packet send to
-                * the delete addresses, so we should wait until ASCONF_ACK
-                * packet is received.
+               /* Update the route and saddr entries for all the transports
+                * as some of the addresses in the bind address list are
+                * about to be deleted and cannot be used as source addresses.
                 */
+               list_for_each(pos1, &asoc->peer.transport_addr_list) {
+                       transport = list_entry(pos1, struct sctp_transport,
+                                              transports);
+                       dst_release(transport->dst);
+                       sctp_transport_route(transport, NULL,
+                                            sctp_sk(asoc->base.sk));
+               }
+
+               retval = sctp_send_asconf(asoc, chunk);
        }
 out:
        return retval;
@@ -4977,7 +5021,7 @@ static struct sctp_bind_bucket *sctp_bucket_create(
 /* Caller must hold hashbucket lock for this tb with local BH disabled */
 static void sctp_bucket_destroy(struct sctp_bind_bucket *pp)
 {
-       if (hlist_empty(&pp->owner)) {
+       if (pp && hlist_empty(&pp->owner)) {
                if (pp->next)
                        pp->next->pprev = pp->pprev;
                *(pp->pprev) = pp->next;
index 160f62a..2763aa9 100644 (file)
@@ -49,6 +49,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/random.h>
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
@@ -85,7 +86,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
 
        peer->init_sent_count = 0;
 
-       peer->state = SCTP_ACTIVE;
        peer->param_flags = SPP_HB_DISABLE |
                            SPP_PMTUD_ENABLE |
                            SPP_SACKDELAY_ENABLE;
@@ -109,6 +109,9 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
        peer->hb_timer.function = sctp_generate_heartbeat_event;
        peer->hb_timer.data = (unsigned long)peer;
 
+       /* Initialize the 64-bit random nonce sent with heartbeat. */
+       get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce));
+
        atomic_set(&peer->refcnt, 1);
        peer->dead = 0;
 
@@ -517,7 +520,9 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
 unsigned long sctp_transport_timeout(struct sctp_transport *t)
 {
        unsigned long timeout;
-       timeout = t->hbinterval + t->rto + sctp_jitter(t->rto);
+       timeout = t->rto + sctp_jitter(t->rto);
+       if (t->state != SCTP_UNCONFIRMED)
+               timeout += t->hbinterval;
        timeout += jiffies;
        return timeout;
 }
index 519ebc1..4a9aa93 100644 (file)
@@ -225,9 +225,8 @@ gss_alloc_context(void)
 {
        struct gss_cl_ctx *ctx;
 
-       ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
        if (ctx != NULL) {
-               memset(ctx, 0, sizeof(*ctx));
                ctx->gc_proc = RPC_GSS_PROC_DATA;
                ctx->gc_seq = 1;        /* NetApp 6.4R1 doesn't accept seq. no. 0 */
                spin_lock_init(&ctx->gc_seq_lock);
@@ -391,9 +390,8 @@ gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid)
 {
        struct gss_upcall_msg *gss_msg;
 
-       gss_msg = kmalloc(sizeof(*gss_msg), GFP_KERNEL);
+       gss_msg = kzalloc(sizeof(*gss_msg), GFP_KERNEL);
        if (gss_msg != NULL) {
-               memset(gss_msg, 0, sizeof(*gss_msg));
                INIT_LIST_HEAD(&gss_msg->list);
                rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq");
                init_waitqueue_head(&gss_msg->waitqueue);
@@ -776,10 +774,9 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
        dprintk("RPC:      gss_create_cred for uid %d, flavor %d\n",
                acred->uid, auth->au_flavor);
 
-       if (!(cred = kmalloc(sizeof(*cred), GFP_KERNEL)))
+       if (!(cred = kzalloc(sizeof(*cred), GFP_KERNEL)))
                goto out_err;
 
-       memset(cred, 0, sizeof(*cred));
        atomic_set(&cred->gc_count, 1);
        cred->gc_uid = acred->uid;
        /*
index b8714a8..70e1e53 100644 (file)
@@ -129,9 +129,8 @@ gss_import_sec_context_kerberos(const void *p,
        const void *end = (const void *)((const char *)p + len);
        struct  krb5_ctx *ctx;
 
-       if (!(ctx = kmalloc(sizeof(*ctx), GFP_KERNEL)))
+       if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL)))
                goto out_err;
-       memset(ctx, 0, sizeof(*ctx));
 
        p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate));
        if (IS_ERR(p))
index d88468d..3db7453 100644 (file)
@@ -237,9 +237,8 @@ gss_import_sec_context(const void *input_token, size_t bufsize,
                       struct gss_api_mech      *mech,
                       struct gss_ctx           **ctx_id)
 {
-       if (!(*ctx_id = kmalloc(sizeof(**ctx_id), GFP_KERNEL)))
+       if (!(*ctx_id = kzalloc(sizeof(**ctx_id), GFP_KERNEL)))
                return GSS_S_FAILURE;
-       memset(*ctx_id, 0, sizeof(**ctx_id));
        (*ctx_id)->mech_type = gss_mech_get(mech);
 
        return mech->gm_ops
index 3d0432a..88dcb52 100644 (file)
@@ -152,9 +152,8 @@ gss_import_sec_context_spkm3(const void *p, size_t len,
        const void *end = (const void *)((const char *)p + len);
        struct  spkm3_ctx *ctx;
 
-       if (!(ctx = kmalloc(sizeof(*ctx), GFP_KERNEL)))
+       if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL)))
                goto out_err;
-       memset(ctx, 0, sizeof(*ctx));
 
        p = simple_get_netobj(p, end, &ctx->ctx_id);
        if (IS_ERR(p))
index af0d7ce..854a983 100644 (file)
@@ -90,10 +90,9 @@ asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits)
 int
 decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, int explen)
 {
-       if (!(out->data = kmalloc(explen,GFP_KERNEL)))
+       if (!(out->data = kzalloc(explen,GFP_KERNEL)))
                return 0;
        out->len = explen;
-       memset(out->data, 0, explen);
        memcpy(out->data, in, enclen);
        return 1;
 }
index aa8965e..4ba271f 100644 (file)
@@ -125,10 +125,9 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname,
                goto out_err;
 
        err = -ENOMEM;
-       clnt = kmalloc(sizeof(*clnt), GFP_KERNEL);
+       clnt = kzalloc(sizeof(*clnt), GFP_KERNEL);
        if (!clnt)
                goto out_err;
-       memset(clnt, 0, sizeof(*clnt));
        atomic_set(&clnt->cl_users, 0);
        atomic_set(&clnt->cl_count, 1);
        clnt->cl_parent = clnt;
index 15c2db2..bd98124 100644 (file)
@@ -114,13 +114,8 @@ void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) {
  */
 struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt)
 {
-       unsigned int ops = clnt->cl_maxproc;
-       size_t size = ops * sizeof(struct rpc_iostats);
        struct rpc_iostats *new;
-
-       new = kmalloc(size, GFP_KERNEL);
-       if (new)
-               memset(new, 0 , size);
+       new = kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL);
        return new;
 }
 EXPORT_SYMBOL(rpc_alloc_iostats);
index 01ba60a..b76a227 100644 (file)
@@ -32,9 +32,8 @@ svc_create(struct svc_program *prog, unsigned int bufsize)
        int vers;
        unsigned int xdrsize;
 
-       if (!(serv = kmalloc(sizeof(*serv), GFP_KERNEL)))
+       if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL)))
                return NULL;
-       memset(serv, 0, sizeof(*serv));
        serv->sv_name      = prog->pg_name;
        serv->sv_program   = prog;
        serv->sv_nrthreads = 1;
@@ -159,11 +158,10 @@ svc_create_thread(svc_thread_fn func, struct svc_serv *serv)
        struct svc_rqst *rqstp;
        int             error = -ENOMEM;
 
-       rqstp = kmalloc(sizeof(*rqstp), GFP_KERNEL);
+       rqstp = kzalloc(sizeof(*rqstp), GFP_KERNEL);
        if (!rqstp)
                goto out;
 
-       memset(rqstp, 0, sizeof(*rqstp));
        init_waitqueue_head(&rqstp->rq_wait);
 
        if (!(rqstp->rq_argp = kmalloc(serv->sv_xdrsize, GFP_KERNEL))
index a27905a..d9a9573 100644 (file)
@@ -1322,11 +1322,10 @@ svc_setup_socket(struct svc_serv *serv, struct socket *sock,
        struct sock     *inet;
 
        dprintk("svc: svc_setup_socket %p\n", sock);
-       if (!(svsk = kmalloc(sizeof(*svsk), GFP_KERNEL))) {
+       if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) {
                *errp = -ENOMEM;
                return NULL;
        }
-       memset(svsk, 0, sizeof(*svsk));
 
        inet = sock->sk;
 
index 02060d0..313b68d 100644 (file)
@@ -908,9 +908,8 @@ static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc
        struct rpc_xprt *xprt;
        struct rpc_rqst *req;
 
-       if ((xprt = kmalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL)
+       if ((xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL)
                return ERR_PTR(-ENOMEM);
-       memset(xprt, 0, sizeof(*xprt)); /* Nnnngh! */
 
        xprt->addr = *ap;
 
index 21006b1..ee678ed 100644 (file)
@@ -1276,10 +1276,9 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to)
 
        xprt->max_reqs = xprt_udp_slot_table_entries;
        slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]);
-       xprt->slot = kmalloc(slot_table_size, GFP_KERNEL);
+       xprt->slot = kzalloc(slot_table_size, GFP_KERNEL);
        if (xprt->slot == NULL)
                return -ENOMEM;
-       memset(xprt->slot, 0, slot_table_size);
 
        xprt->prot = IPPROTO_UDP;
        xprt->port = xs_get_random_port();
@@ -1318,10 +1317,9 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to)
 
        xprt->max_reqs = xprt_tcp_slot_table_entries;
        slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]);
-       xprt->slot = kmalloc(slot_table_size, GFP_KERNEL);
+       xprt->slot = kzalloc(slot_table_size, GFP_KERNEL);
        if (xprt->slot == NULL)
                return -ENOMEM;
-       memset(xprt->slot, 0, slot_table_size);
 
        xprt->prot = IPPROTO_TCP;
        xprt->port = xs_get_random_port();
index 7ef17a4..75a5968 100644 (file)
@@ -665,11 +665,9 @@ int tipc_bearer_init(void)
        int res;
 
        write_lock_bh(&tipc_net_lock);
-       tipc_bearers = kmalloc(MAX_BEARERS * sizeof(struct bearer), GFP_ATOMIC);
-       media_list = kmalloc(MAX_MEDIA * sizeof(struct media), GFP_ATOMIC);
+       tipc_bearers = kcalloc(MAX_BEARERS, sizeof(struct bearer), GFP_ATOMIC);
+       media_list = kcalloc(MAX_MEDIA, sizeof(struct media), GFP_ATOMIC);
        if (tipc_bearers && media_list) {
-               memset(tipc_bearers, 0, MAX_BEARERS * sizeof(struct bearer));
-               memset(media_list, 0, MAX_MEDIA * sizeof(struct media));
                res = TIPC_OK;
        } else {
                kfree(tipc_bearers);
index 1dcb694..b46b518 100644 (file)
@@ -57,29 +57,25 @@ struct cluster *tipc_cltr_create(u32 addr)
        struct _zone *z_ptr;
        struct cluster *c_ptr;
        int max_nodes; 
-       int alloc;
 
-       c_ptr = (struct cluster *)kmalloc(sizeof(*c_ptr), GFP_ATOMIC);
+       c_ptr = kzalloc(sizeof(*c_ptr), GFP_ATOMIC);
        if (c_ptr == NULL) {
                warn("Cluster creation failure, no memory\n");
                return NULL;
        }
-       memset(c_ptr, 0, sizeof(*c_ptr));
 
        c_ptr->addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0);
        if (in_own_cluster(addr))
                max_nodes = LOWEST_SLAVE + tipc_max_slaves;
        else
                max_nodes = tipc_max_nodes + 1;
-       alloc = sizeof(void *) * (max_nodes + 1);
 
-       c_ptr->nodes = (struct node **)kmalloc(alloc, GFP_ATOMIC);
+       c_ptr->nodes = kcalloc(max_nodes + 1, sizeof(void*), GFP_ATOMIC);
        if (c_ptr->nodes == NULL) {
                warn("Cluster creation failure, no memory for node area\n");
                kfree(c_ptr);
                return NULL;
        }
-       memset(c_ptr->nodes, 0, alloc);
 
        if (in_own_cluster(addr))
                tipc_local_nodes = c_ptr->nodes;
index 2b84412..ee94de9 100644 (file)
@@ -295,7 +295,7 @@ struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr,
 {
        struct link_req *req;
 
-       req = (struct link_req *)kmalloc(sizeof(*req), GFP_ATOMIC);
+       req = kmalloc(sizeof(*req), GFP_ATOMIC);
        if (!req)
                return NULL;
 
index c10e18a..693f02e 100644 (file)
@@ -417,12 +417,11 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
        struct tipc_msg *msg;
        char *if_name;
 
-       l_ptr = (struct link *)kmalloc(sizeof(*l_ptr), GFP_ATOMIC);
+       l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC);
        if (!l_ptr) {
                warn("Link creation failed, no memory\n");
                return NULL;
        }
-       memset(l_ptr, 0, sizeof(*l_ptr));
 
        l_ptr->addr = peer;
        if_name = strchr(b_ptr->publ.name, ':') + 1;
index a6926ff..049242e 100644 (file)
@@ -117,14 +117,12 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper,
                                       u32 scope, u32 node, u32 port_ref,   
                                       u32 key)
 {
-       struct publication *publ =
-               (struct publication *)kmalloc(sizeof(*publ), GFP_ATOMIC);
+       struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC);
        if (publ == NULL) {
                warn("Publication creation failure, no memory\n");
                return NULL;
        }
 
-       memset(publ, 0, sizeof(*publ));
        publ->type = type;
        publ->lower = lower;
        publ->upper = upper;
@@ -144,11 +142,7 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper,
 
 static struct sub_seq *tipc_subseq_alloc(u32 cnt)
 {
-       u32 sz = cnt * sizeof(struct sub_seq);
-       struct sub_seq *sseq = (struct sub_seq *)kmalloc(sz, GFP_ATOMIC);
-
-       if (sseq)
-               memset(sseq, 0, sz);
+       struct sub_seq *sseq = kcalloc(cnt, sizeof(struct sub_seq), GFP_ATOMIC);
        return sseq;
 }
 
@@ -160,8 +154,7 @@ static struct sub_seq *tipc_subseq_alloc(u32 cnt)
 
 static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_head)
 {
-       struct name_seq *nseq = 
-               (struct name_seq *)kmalloc(sizeof(*nseq), GFP_ATOMIC);
+       struct name_seq *nseq = kzalloc(sizeof(*nseq), GFP_ATOMIC);
        struct sub_seq *sseq = tipc_subseq_alloc(1);
 
        if (!nseq || !sseq) {
@@ -171,7 +164,6 @@ static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_hea
                return NULL;
        }
 
-       memset(nseq, 0, sizeof(*nseq));
        spin_lock_init(&nseq->lock);
        nseq->type = type;
        nseq->sseqs = sseq;
@@ -1060,7 +1052,7 @@ int tipc_nametbl_init(void)
 {
        int array_size = sizeof(struct hlist_head) * tipc_nametbl_size;
 
-       table.types = (struct hlist_head *)kmalloc(array_size, GFP_ATOMIC);
+       table.types = kmalloc(array_size, GFP_ATOMIC);
        if (!table.types)
                return -ENOMEM;
 
index e5a359a..a991bf8 100644 (file)
@@ -160,14 +160,11 @@ void tipc_net_send_external_routes(u32 dest)
 
 static int net_init(void)
 {
-       u32 sz = sizeof(struct _zone *) * (tipc_max_zones + 1);
-
        memset(&tipc_net, 0, sizeof(tipc_net));
-       tipc_net.zones = (struct _zone **)kmalloc(sz, GFP_ATOMIC);
+       tipc_net.zones = kcalloc(tipc_max_zones + 1, sizeof(struct _zone *), GFP_ATOMIC);
        if (!tipc_net.zones) {
                return -ENOMEM;
        }
-       memset(tipc_net.zones, 0, sz);
        return TIPC_OK;
 }
 
index 3251c8d..b9c8c6b 100644 (file)
@@ -226,12 +226,11 @@ u32 tipc_createport_raw(void *usr_handle,
        struct tipc_msg *msg;
        u32 ref;
 
-       p_ptr = kmalloc(sizeof(*p_ptr), GFP_ATOMIC);
+       p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC);
        if (!p_ptr) {
                warn("Port creation failed, no memory\n");
                return 0;
        }
-       memset(p_ptr, 0, sizeof(*p_ptr));
        ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock);
        if (!ref) {
                warn("Port creation failed, reference table exhausted\n");
@@ -1058,7 +1057,7 @@ int tipc_createport(u32 user_ref,
        struct port *p_ptr; 
        u32 ref;
 
-       up_ptr = (struct user_port *)kmalloc(sizeof(*up_ptr), GFP_ATOMIC);
+       up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC);
        if (!up_ptr) {
                warn("Port creation failed, no memory\n");
                return -ENOMEM;
index 596d3c8..e6d6ae2 100644 (file)
@@ -79,7 +79,7 @@ int tipc_ref_table_init(u32 requested_size, u32 start)
        while (sz < requested_size) {
                sz <<= 1;
        }
-       table = (struct reference *)vmalloc(sz * sizeof(struct reference));
+       table = vmalloc(sz * sizeof(*table));
        if (table == NULL)
                return -ENOMEM;
 
index e19b4bc..c51600b 100644 (file)
@@ -393,12 +393,11 @@ static void subscr_named_msg_event(void *usr_handle,
 
        /* Create subscriber object */
 
-       subscriber = kmalloc(sizeof(struct subscriber), GFP_ATOMIC);
+       subscriber = kzalloc(sizeof(struct subscriber), GFP_ATOMIC);
        if (subscriber == NULL) {
                warn("Subscriber rejected, no memory\n");
                return;
        }
-       memset(subscriber, 0, sizeof(struct subscriber));
        INIT_LIST_HEAD(&subscriber->subscription_list);
        INIT_LIST_HEAD(&subscriber->subscriber_list);
        subscriber->ref = tipc_ref_acquire(subscriber, &subscriber->lock);
index 1e3ae57..04d1b9b 100644 (file)
@@ -82,9 +82,8 @@ static int reg_init(void)
        
        spin_lock_bh(&reg_lock);
        if (!users) {
-               users = (struct tipc_user *)kmalloc(USER_LIST_SIZE, GFP_ATOMIC);
+               users = kzalloc(USER_LIST_SIZE, GFP_ATOMIC);
                if (users) {
-                       memset(users, 0, USER_LIST_SIZE);
                        for (i = 1; i <= MAX_USERID; i++) {
                                users[i].next = i - 1;
                        }
index 316c487..f5b00ea 100644 (file)
@@ -52,13 +52,12 @@ struct _zone *tipc_zone_create(u32 addr)
                return NULL;
        }
 
-       z_ptr = (struct _zone *)kmalloc(sizeof(*z_ptr), GFP_ATOMIC);
+       z_ptr = kzalloc(sizeof(*z_ptr), GFP_ATOMIC);
        if (!z_ptr) {
                warn("Zone creation failed, insufficient memory\n");
                return NULL;
        }
 
-       memset(z_ptr, 0, sizeof(*z_ptr));
        z_num = tipc_zone(addr);
        z_ptr->addr = tipc_addr(z_num, 0, 0);
        tipc_net.zones[z_num] = z_ptr;
index f70475b..6f29092 100644 (file)
@@ -663,11 +663,10 @@ static int unix_autobind(struct socket *sock)
                goto out;
 
        err = -ENOMEM;
-       addr = kmalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL);
+       addr = kzalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL);
        if (!addr)
                goto out;
 
-       memset(addr, 0, sizeof(*addr) + sizeof(short) + 16);
        addr->name->sun_family = AF_UNIX;
        atomic_set(&addr->refcnt, 1);
 
index a690cf7..6f39faa 100644 (file)
@@ -370,12 +370,11 @@ static int wanpipe_listen_rcv (struct sk_buff *skb,  struct sock *sk)
          * used by the ioctl call to read call information
          * and to execute commands. 
          */    
-       if ((mbox_ptr = kmalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) {
+       if ((mbox_ptr = kzalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) {
                wanpipe_kill_sock_irq (newsk);
                release_device(dev);            
                return -ENOMEM;
        }
-       memset(mbox_ptr, 0, sizeof(mbox_cmd_t));
        memcpy(mbox_ptr,skb->data,skb->len);
 
        /* Register the lcn on which incoming call came
@@ -507,11 +506,10 @@ static struct sock *wanpipe_alloc_socket(void)
        if ((sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, &wanpipe_proto, 1)) == NULL)
                return NULL;
 
-       if ((wan_opt = kmalloc(sizeof(struct wanpipe_opt), GFP_ATOMIC)) == NULL) {
+       if ((wan_opt = kzalloc(sizeof(struct wanpipe_opt), GFP_ATOMIC)) == NULL) {
                sk_free(sk);
                return NULL;
        }
-       memset(wan_opt, 0x00, sizeof(struct wanpipe_opt));
 
        wp_sk(sk) = wan_opt;
 
@@ -2011,10 +2009,9 @@ static int set_ioctl_cmd (struct sock *sk, void *arg)
 
                dev_put(dev);
                
-               if ((mbox_ptr = kmalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL)
+               if ((mbox_ptr = kzalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL)
                        return -ENOMEM;
 
-               memset(mbox_ptr, 0, sizeof(mbox_cmd_t));
                wp_sk(sk)->mbox = mbox_ptr;
 
                wanpipe_link_driver(dev,sk);
index ad8e8a7..9479659 100644 (file)
@@ -642,18 +642,16 @@ static int wanrouter_device_new_if(struct wan_device *wandev,
 
        if (cnf->config_id == WANCONFIG_MPPP) {
 #ifdef CONFIG_WANPIPE_MULTPPP
-               pppdev = kmalloc(sizeof(struct ppp_device), GFP_KERNEL);
+               pppdev = kzalloc(sizeof(struct ppp_device), GFP_KERNEL);
                err = -ENOBUFS;
                if (pppdev == NULL)
                        goto out;
-               memset(pppdev, 0, sizeof(struct ppp_device));
-               pppdev->dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+               pppdev->dev = kzalloc(sizeof(struct net_device), GFP_KERNEL);
                if (pppdev->dev == NULL) {
                        kfree(pppdev);
                        err = -ENOBUFS;
                        goto out;
                }
-               memset(pppdev->dev, 0, sizeof(struct net_device));
                err = wandev->new_if(wandev, (struct net_device *)pppdev, cnf);
                dev = pppdev->dev;
 #else
@@ -663,11 +661,10 @@ static int wanrouter_device_new_if(struct wan_device *wandev,
                goto out;
 #endif
        } else {
-               dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+               dev = kzalloc(sizeof(struct net_device), GFP_KERNEL);
                err = -ENOBUFS;
                if (dev == NULL)
                        goto out;
-               memset(dev, 0, sizeof(struct net_device));
                err = wandev->new_if(wandev, dev, cnf);
        }
 
index 405b741..f35bc67 100644 (file)
@@ -307,10 +307,9 @@ struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp)
 {
        struct xfrm_policy *policy;
 
-       policy = kmalloc(sizeof(struct xfrm_policy), gfp);
+       policy = kzalloc(sizeof(struct xfrm_policy), gfp);
 
        if (policy) {
-               memset(policy, 0, sizeof(struct xfrm_policy));
                atomic_set(&policy->refcnt, 1);
                rwlock_init(&policy->lock);
                init_timer(&policy->timer);
index 43f00fc..0021aad 100644 (file)
@@ -194,10 +194,9 @@ struct xfrm_state *xfrm_state_alloc(void)
 {
        struct xfrm_state *x;
 
-       x = kmalloc(sizeof(struct xfrm_state), GFP_ATOMIC);
+       x = kzalloc(sizeof(struct xfrm_state), GFP_ATOMIC);
 
        if (x) {
-               memset(x, 0, sizeof(struct xfrm_state));
                atomic_set(&x->refcnt, 1);
                atomic_set(&x->tunnel_users, 0);
                INIT_LIST_HEAD(&x->bydst);