Merge master.kernel.org:/home/rmk/linux-2.6-serial
authorLinus Torvalds <torvalds@g5.osdl.org>
Fri, 17 Feb 2006 16:13:38 +0000 (08:13 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 17 Feb 2006 16:13:38 +0000 (08:13 -0800)
146 files changed:
Documentation/kernel-parameters.txt
Documentation/scsi/ChangeLog.megaraid_sas
Makefile
arch/arm/kernel/calls.S
arch/arm/kernel/setup.c
arch/arm/kernel/smp.c
arch/arm/kernel/sys_oabi-compat.c
arch/arm/mach-integrator/platsmp.c
arch/arm/mach-iop3xx/iop321-setup.c
arch/arm/mach-iop3xx/iop331-setup.c
arch/arm/mach-ixp4xx/nslu2-setup.c
arch/arm/mach-realview/platsmp.c
arch/arm/plat-omap/pm.c
arch/i386/kernel/cpu/transmeta.c
arch/x86_64/defconfig
arch/x86_64/kernel/apic.c
arch/x86_64/kernel/entry.S
arch/x86_64/kernel/head.S
arch/x86_64/kernel/io_apic.c
arch/x86_64/kernel/nmi.c
arch/x86_64/kernel/time.c
arch/x86_64/mm/k8topology.c
arch/x86_64/mm/numa.c
arch/x86_64/mm/srat.c
drivers/ide/ide-taskfile.c
drivers/input/keyboard/Makefile
drivers/input/misc/Makefile
drivers/input/misc/ixp4xx-beeper.c
drivers/input/mouse/logips2pp.c
drivers/input/mouse/trackpoint.c
drivers/input/mouse/trackpoint.h
drivers/input/serio/Makefile
drivers/input/touchscreen/ads7846.c
drivers/message/fusion/mptbase.c
drivers/message/fusion/mptbase.h
drivers/message/fusion/mptctl.c
drivers/message/fusion/mptctl.h
drivers/message/fusion/mptscsih.c
drivers/mmc/mmci.c
drivers/s390/scsi/zfcp_dbf.c
drivers/s390/scsi/zfcp_def.h
drivers/s390/scsi/zfcp_erp.c
drivers/s390/scsi/zfcp_ext.h
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_scsi.c
drivers/s390/scsi/zfcp_sysfs_adapter.c
drivers/scsi/3w-9xxx.c
drivers/scsi/aacraid/aachba.c
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aacraid/commctrl.c
drivers/scsi/aacraid/comminit.c
drivers/scsi/aacraid/commsup.c
drivers/scsi/aacraid/dpcsup.c
drivers/scsi/aacraid/linit.c
drivers/scsi/gdth.c
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/iscsi_tcp.c
drivers/scsi/iscsi_tcp.h
drivers/scsi/megaraid.c
drivers/scsi/megaraid.h
drivers/scsi/megaraid/megaraid_sas.c
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_rscn.c
drivers/scsi/qla2xxx/qla_sup.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/sym53c8xx_2/sym_hipd.c
drivers/video/neofb.c
drivers/video/s3c2410fb.c
fs/cifs/file.c
fs/exec.c
fs/ocfs2/dlm/dlmcommon.h
fs/ocfs2/dlm/dlmconvert.c
fs/ocfs2/dlm/dlmlock.c
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/dlm/dlmrecovery.c
fs/ocfs2/journal.c
fs/ocfs2/journal.h
include/asm-alpha/mman.h
include/asm-arm/mman.h
include/asm-arm/smp.h
include/asm-arm/unistd.h
include/asm-arm26/mman.h
include/asm-cris/mman.h
include/asm-frv/mman.h
include/asm-generic/mman.h [new file with mode: 0644]
include/asm-h8300/mman.h
include/asm-i386/mman.h
include/asm-ia64/mman.h
include/asm-m32r/mman.h
include/asm-m68k/mman.h
include/asm-mips/mman.h
include/asm-parisc/mman.h
include/asm-powerpc/mman.h
include/asm-s390/mman.h
include/asm-sh/mman.h
include/asm-sparc/mman.h
include/asm-sparc64/mman.h
include/asm-v850/mman.h
include/asm-x86_64/mman.h
include/asm-x86_64/proto.h
include/asm-xtensa/mman.h
include/linux/kernel.h
include/linux/ktime.h
include/linux/mm.h
include/linux/netfilter.h
include/linux/netfilter_ipv4.h
include/linux/ptrace.h
include/net/ip.h
include/net/xfrm.h
include/scsi/iscsi_if.h
include/scsi/scsi.h
include/scsi/scsi_transport_iscsi.h
include/video/neomagic.h
kernel/cpuset.c
kernel/fork.c
kernel/power/snapshot.c
kernel/ptrace.c
kernel/sysctl.c
lib/radix-tree.c
mm/memory.c
net/bridge/br_stp_if.c
net/ipv4/ip_gre.c
net/ipv4/ip_output.c
net/ipv4/ipip.c
net/ipv4/netfilter.c
net/ipv4/netfilter/ip_nat_standalone.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
net/ipv4/xfrm4_output.c
net/ipv6/icmp.c
net/ipv6/netfilter/ip6t_REJECT.c
net/netfilter/Kconfig
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_conntrack_proto_udp.c

index 84370363da809a67733cd346e429af2e56bef91c..b874771385cda9df928fc651dee1e7585c6a08ff 100644 (file)
@@ -1133,6 +1133,8 @@ running once the system is up.
                                Mechanism 1.
                conf2           [IA-32] Force use of PCI Configuration
                                Mechanism 2.
+               nommconf        [IA-32,X86_64] Disable use of MMCONFIG for PCI
+                               Configuration
                nosort          [IA-32] Don't sort PCI devices according to
                                order given by the PCI BIOS. This sorting is
                                done to get a device order compatible with
@@ -1636,6 +1638,9 @@ running once the system is up.
                        Format:
                        <irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
 
+       norandmaps      Don't use address space randomization
+                       Equivalent to echo 0 > /proc/sys/kernel/randomize_va_space
+
 
 ______________________________________________________________________
 Changelog:
index f8c16cbf56ba0a96f97392ea514430daffbb5576..2dafa63bd370bd1632f08f73687e210f08636494 100644 (file)
@@ -1,3 +1,26 @@
+1 Release Date    : Wed Feb 03 14:31:44 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com>
+2 Current Version : 00.00.02.04
+3 Older Version   : 00.00.02.04 
+
+i.     Support for 1078 type (ppc IOP) controller, device id : 0x60 added.
+       During initialization, depending on the device id, the template members 
+       are initialized with function pointers specific to the ppc or 
+       xscale controllers.  
+
+               -Sumant Patro <Sumant.Patro@lsil.com>
+               
+1 Release Date    : Fri Feb 03 14:16:25 PST 2006 - Sumant Patro 
+                                                       <Sumant.Patro@lsil.com>
+2 Current Version : 00.00.02.04
+3 Older Version   : 00.00.02.02 
+i.     Register 16 byte CDB capability with scsi midlayer 
+
+       "Ths patch properly registers the 16 byte command length capability of the 
+       megaraid_sas controlled hardware with the scsi midlayer. All megaraid_sas 
+       hardware supports 16 byte CDB's."
+
+               -Joshua Giles <joshua_giles@dell.com> 
+
 1 Release Date    : Mon Jan 23 14:09:01 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com>
 2 Current Version : 00.00.02.02
 3 Older Version   : 00.00.02.01 
index 74d67b2c35d9166c313f01c3c77960f8210c4b94..48d569d46ae1c023e6e9f0311612e50f78cb90bb 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -106,13 +106,12 @@ KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd)
 $(if $(KBUILD_OUTPUT),, \
      $(error output directory "$(saved-output)" does not exist))
 
-.PHONY: $(MAKECMDGOALS) cdbuilddir
-$(MAKECMDGOALS) _all: cdbuilddir
+.PHONY: $(MAKECMDGOALS)
 
-cdbuilddir:
+$(filter-out _all,$(MAKECMDGOALS)) _all:
        $(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
        KBUILD_SRC=$(CURDIR) \
-       KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile $(MAKECMDGOALS)
+       KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile $@
 
 # Leave processing to above invocation of make
 skip-makefile := 1
index 8c3035d5ffc9c28c7c6ae416397b6341184c203b..3173924a9b6022f6e4b30e00f414e7e5e9e2dbde 100644 (file)
                CALL(sys_statfs)
 /* 100 */      CALL(sys_fstatfs)
                CALL(sys_ni_syscall)
-               CALL(OBSOLETE(sys_socketcall))
+               CALL(OBSOLETE(ABI(sys_socketcall, sys_oabi_socketcall)))
                CALL(sys_syslog)
                CALL(sys_setitimer)
 /* 105 */      CALL(sys_getitimer)
index c45d10d07bde95f73034f47fd26877c41548ba08..68273b4dc8820b39a3e3c87456203fbecd65dde1 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/root_dev.h>
 #include <linux/cpu.h>
 #include <linux/interrupt.h>
+#include <linux/smp.h>
 
 #include <asm/cpu.h>
 #include <asm/elf.h>
@@ -771,6 +772,10 @@ void __init setup_arch(char **cmdline_p)
        paging_init(&meminfo, mdesc);
        request_standard_resources(&meminfo, mdesc);
 
+#ifdef CONFIG_SMP
+       smp_init_cpus();
+#endif
+
        cpu_init();
 
        /*
index 7338948bd7d38046e355807e73c44413d3db40d7..02aa300c46337fede228bf70d302433f4a12c548 100644 (file)
@@ -338,7 +338,6 @@ void __init smp_prepare_boot_cpu(void)
 
        per_cpu(cpu_data, cpu).idle = current;
 
-       cpu_set(cpu, cpu_possible_map);
        cpu_set(cpu, cpu_present_map);
        cpu_set(cpu, cpu_online_map);
 }
index 9d4b76409c6446a99173a160d6e4a4349a015dd3..8e2f9bc3368b0600f99c6eef4ae6c3cc70db1fe3 100644 (file)
@@ -64,6 +64,7 @@
  * sys_connect:
  * sys_sendmsg:
  * sys_sendto:
+ * sys_socketcall:
  *
  *   struct sockaddr_un loses its padding with EABI.  Since the size of the
  *   structure is used as a validation test in unix_mkname(), we need to
@@ -78,6 +79,7 @@
 #include <linux/eventpoll.h>
 #include <linux/sem.h>
 #include <linux/socket.h>
+#include <linux/net.h>
 #include <asm/ipc.h>
 #include <asm/uaccess.h>
 
@@ -408,3 +410,31 @@ asmlinkage long sys_oabi_sendmsg(int fd, struct msghdr __user *msg, unsigned fla
        return sys_sendmsg(fd, msg, flags);
 }
 
+asmlinkage long sys_oabi_socketcall(int call, unsigned long __user *args)
+{
+       unsigned long r = -EFAULT, a[6];
+
+       switch (call) {
+       case SYS_BIND:
+               if (copy_from_user(a, args, 3 * sizeof(long)) == 0)
+                       r = sys_oabi_bind(a[0], (struct sockaddr __user *)a[1], a[2]);
+               break;
+       case SYS_CONNECT:
+               if (copy_from_user(a, args, 3 * sizeof(long)) == 0)
+                       r = sys_oabi_connect(a[0], (struct sockaddr __user *)a[1], a[2]);
+               break;
+       case SYS_SENDTO:
+               if (copy_from_user(a, args, 6 * sizeof(long)) == 0)
+                       r = sys_oabi_sendto(a[0], (void __user *)a[1], a[2], a[3],
+                                           (struct sockaddr __user *)a[4], a[5]);
+               break;
+       case SYS_SENDMSG:
+               if (copy_from_user(a, args, 3 * sizeof(long)) == 0)
+                       r = sys_oabi_sendmsg(a[0], (struct msghdr __user *)a[1], a[2]);
+               break;
+       default:
+               r = sys_socketcall(call, args);
+       }
+
+       return r;
+}
index ea10bd8c972c4bf4d6df17c0ef0faf77871f4f7f..1bc8534ef0c696d5fca65a19dbe10b47be3f7d66 100644 (file)
@@ -140,6 +140,18 @@ static void __init poke_milo(void)
        mb();
 }
 
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+void __init smp_init_cpus(void)
+{
+       unsigned int i, ncores = get_core_count();
+
+       for (i = 0; i < ncores; i++)
+               cpu_set(i, cpu_possible_map);
+}
+
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
        unsigned int ncores = get_core_count();
@@ -176,14 +188,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
                max_cpus = ncores;
 
        /*
-        * Initialise the possible/present maps.
-        * cpu_possible_map describes the set of CPUs which may be present
-        * cpu_present_map describes the set of CPUs populated
+        * Initialise the present map, which describes the set of CPUs
+        * actually populated at the present time.
         */
-       for (i = 0; i < max_cpus; i++) {
-               cpu_set(i, cpu_possible_map);
+       for (i = 0; i < max_cpus; i++)
                cpu_set(i, cpu_present_map);
-       }
 
        /*
         * Do we need any more CPUs? If so, then let them know where
index e4f4c52d93d44a4606f4bdb8ba36d91b5355b4f6..0ebbcb20c6ae2ab3a43177a019c51ec254d16400 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/config.h>
-#include <linux/init.h>
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/platform_device.h>
index 63585485123e50ae208e5ea9426efe0e50780296..2d6abe5be14df2a8e41dd8f8c3ee1ec39c0df582 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/config.h>
-#include <linux/init.h>
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/platform_device.h>
index da9340a5343419c926b52a195ad3782c76cdcc3b..f260a9d34f707637142865a8962d6784b8ff341a 100644 (file)
@@ -27,8 +27,6 @@ static struct flash_platform_data nslu2_flash_data = {
 };
 
 static struct resource nslu2_flash_resource = {
-       .start                  = NSLU2_FLASH_BASE,
-       .end                    = NSLU2_FLASH_BASE + NSLU2_FLASH_SIZE,
        .flags                  = IORESOURCE_MEM,
 };
 
@@ -116,6 +114,10 @@ static void __init nslu2_init(void)
 {
        ixp4xx_sys_init();
 
+       nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+       nslu2_flash_resource.end =
+               IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
+
        pm_power_off = nslu2_power_off;
 
        platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices));
index a8fbd76d8be5855e97eea74502f949cde0abf828..b8484e15dacb7f3e8f3d69ca09ea58334ea47b42 100644 (file)
@@ -143,6 +143,18 @@ static void __init poke_milo(void)
        mb();
 }
 
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+void __init smp_init_cpus(void)
+{
+       unsigned int i, ncores = get_core_count();
+
+       for (i = 0; i < ncores; i++)
+               cpu_set(i, cpu_possible_map);
+}
+
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
        unsigned int ncores = get_core_count();
@@ -179,14 +191,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
        local_timer_setup(cpu);
 
        /*
-        * Initialise the possible/present maps.
-        * cpu_possible_map describes the set of CPUs which may be present
-        * cpu_present_map describes the set of CPUs populated
+        * Initialise the present map, which describes the set of CPUs
+        * actually populated at the present time.
         */
-       for (i = 0; i < max_cpus; i++) {
-               cpu_set(i, cpu_possible_map);
+       for (i = 0; i < max_cpus; i++)
                cpu_set(i, cpu_present_map);
-       }
 
        /*
         * Do we need any more CPUs? If so, then let them know where
index 1a24e2c10714e498942cdaae1d3386af6f9f7b37..093efd786f211c9ffbdba88646c7485531882aed 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/pm.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
-#include <linux/pm.h>
 #include <linux/interrupt.h>
 
 #include <asm/io.h>
index bdbeb77f4e22fa9e7f6636cf03c03e8bb59c4dd6..7214c9b577ab91329ecdb261926e2cdde6e729fd 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/kernel.h>
+#include <linux/mm.h>
 #include <linux/init.h>
 #include <asm/processor.h>
 #include <asm/msr.h>
index 56832929a54398279bcd4f218b264d12dd793e10..b337136f28b6ff0e854eb7efee86a661c50f0b39 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc1-git2
-# Thu Jan 19 10:05:21 2006
+# Linux kernel version: 2.6.16-rc3
+# Mon Feb 13 22:31:24 2006
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -21,7 +21,6 @@ CONFIG_DMI=y
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
@@ -267,6 +266,7 @@ CONFIG_NET=y
 #
 # Networking options
 #
+# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -446,7 +446,6 @@ CONFIG_BLK_DEV_PIIX=y
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 CONFIG_BLK_DEV_PDC202XX_NEW=y
-# CONFIG_PDC202XX_FORCE is not set
 # CONFIG_BLK_DEV_SVWKS is not set
 # CONFIG_BLK_DEV_SIIMAGE is not set
 # CONFIG_BLK_DEV_SIS5513 is not set
@@ -573,7 +572,33 @@ CONFIG_FUSION_MAX_SGE=128
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
+CONFIG_IEEE1394=y
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+# CONFIG_IEEE1394_OUI_DB is not set
+# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+
+#
+# Texas Instruments PCILynx requires I2C
+#
+CONFIG_IEEE1394_OHCI1394=y
+
+#
+# Protocol Drivers
+#
+# CONFIG_IEEE1394_VIDEO1394 is not set
+# CONFIG_IEEE1394_SBP2 is not set
+# CONFIG_IEEE1394_ETH1394 is not set
+# CONFIG_IEEE1394_DV1394 is not set
+CONFIG_IEEE1394_RAWIO=y
 
 #
 # I2O device support
@@ -772,6 +797,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -871,6 +897,7 @@ CONFIG_HPET_MMAP=y
 #
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_HDAPS is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
@@ -1101,7 +1128,6 @@ CONFIG_USB_MON=y
 # EDAC - error detection and reporting (RAS)
 #
 # CONFIG_EDAC is not set
-# CONFIG_EDAC_POLL is not set
 
 #
 # Firmware Drivers
@@ -1291,14 +1317,12 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_INFO is not set
+CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_FORCED_INLINING is not set
-# CONFIG_UNWIND_INFO is not set
 # CONFIG_RCU_TORTURE_TEST is not set
-CONFIG_INIT_DEBUG=y
 # CONFIG_DEBUG_RODATA is not set
 # CONFIG_IOMMU_DEBUG is not set
 
index 7a0a3e8d5d7265ed23e1f0cf0ae1f108b64645e8..e5b14c57eaa0644fa8e4106a445b58e3d1f51e1d 100644 (file)
@@ -1152,6 +1152,7 @@ __setup("noapicmaintimer", setup_noapicmaintimer);
 static __init int setup_apicpmtimer(char *s)
 {
        apic_calibrate_pmtmr = 1;
+       notsc_setup(NULL);
        return setup_apicmaintimer(NULL);
 }
 __setup("apicpmtimer", setup_apicpmtimer);
index b150c87a08c6b3131909d8af5b567699e58ce098..7c10e9009d611173d13fddf90650a9dfe78ec7db 100644 (file)
@@ -554,6 +554,7 @@ iret_label:
        /* running with kernel gs */
 bad_iret:
        movq $-9999,%rdi        /* better code? */
+       sti
        jmp do_exit                     
        .previous       
        
index 692c737feddb05393525c3753e0ab285adc7164b..02fc7fa0ea28e26445015a743c919681e3b6dead 100644 (file)
@@ -213,6 +213,11 @@ ENTRY(early_idt_handler)
        cmpl $2,early_recursion_flag(%rip)
        jz  1f
        call dump_stack
+#ifdef CONFIG_KALLSYMS 
+       leaq early_idt_ripmsg(%rip),%rdi
+       movq 8(%rsp),%rsi       # get rip again
+       call __print_symbol
+#endif
 1:     hlt
        jmp 1b
 early_recursion_flag:
@@ -220,6 +225,8 @@ early_recursion_flag:
 
 early_idt_msg:
        .asciz "PANIC: early exception rip %lx error %lx cr2 %lx\n"
+early_idt_ripmsg:
+       .asciz "RIP %s\n"
 
 .code32
 ENTRY(no_long_mode)
index 4282d72b2a260e28c2aa2c9c272b8b8ef8621d7b..2585c1d92b26bd2b9443433f9a1b83c25e36dc3e 100644 (file)
@@ -30,6 +30,9 @@
 #include <linux/mc146818rtc.h>
 #include <linux/acpi.h>
 #include <linux/sysdev.h>
+#ifdef CONFIG_ACPI
+#include <acpi/acpi_bus.h>
+#endif
 
 #include <asm/io.h>
 #include <asm/smp.h>
@@ -260,6 +263,8 @@ __setup("apic", enable_ioapic_setup);
 
    And another hack to disable the IOMMU on VIA chipsets.
 
+   ... and others. Really should move this somewhere else.
+
    Kludge-O-Rama. */
 void __init check_ioapic(void) 
 { 
@@ -307,6 +312,17 @@ void __init check_ioapic(void)
                                case PCI_VENDOR_ID_ATI:
                                        if (apic_runs_main_timer != 0)
                                                break;
+#ifdef CONFIG_ACPI
+                                       /* Don't do this for laptops right
+                                          right now because their timer
+                                          doesn't necessarily tick in C2/3 */
+                                       if (acpi_fadt.revision >= 3 &&
+                       (acpi_fadt.plvl2_lat + acpi_fadt.plvl3_lat) < 1100) {
+                                               printk(KERN_INFO
+"ATI board detected, but seems to be a laptop. Timer might be shakey, sorry\n");
+                                               break;
+                                       }
+#endif                                 
                                        printk(KERN_INFO
             "ATI board detected. Using APIC/PM timer.\n");
                                        apic_runs_main_timer = 1;
index 8be407a1f62d11db0c06fc73cb4e0208037e986d..5bf17e41cd2d2622138e030dc8f90ccc0d499d7f 100644 (file)
@@ -236,6 +236,7 @@ static void enable_lapic_nmi_watchdog(void)
 {
        if (nmi_active < 0) {
                nmi_watchdog = NMI_LOCAL_APIC;
+               touch_nmi_watchdog();
                setup_apic_nmi_watchdog();
        }
 }
@@ -456,15 +457,17 @@ static DEFINE_PER_CPU(int, nmi_touch);
 
 void touch_nmi_watchdog (void)
 {
-       int i;
+       if (nmi_watchdog > 0) {
+               unsigned cpu;
 
-       /*
-        * Tell other CPUs to reset their alert counters. We cannot
-        * do it ourselves because the alert count increase is not
-        * atomic.
-        */
-       for (i = 0; i < NR_CPUS; i++)
-               per_cpu(nmi_touch, i) = 1;
+               /*
+                * Tell other CPUs to reset their alert counters. We cannot
+                * do it ourselves because the alert count increase is not
+                * atomic.
+                */
+               for_each_present_cpu (cpu)
+                       per_cpu(nmi_touch, cpu) = 1;
+       }
 
        touch_softlockup_watchdog();
 }
index 3c58c30506a104c00d505b234b6261947fc4c8a3..67841d11ed1ff978aada750c1445b93001e20d1e 100644 (file)
@@ -1327,8 +1327,7 @@ static int __init nohpet_setup(char *s)
 
 __setup("nohpet", nohpet_setup);
 
-
-static int __init notsc_setup(char *s)
+int __init notsc_setup(char *s)
 {
        notsc = 1;
        return 0;
index a5663e0bb01cad0a23fb9deab8b415829256c10f..dd60e71fdba6fe827a2c61028cd88ad0cb5f9abe 100644 (file)
@@ -155,7 +155,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
        if (!found)
                return -1; 
 
-       memnode_shift = compute_hash_shift(nodes, numnodes);
+       memnode_shift = compute_hash_shift(nodes, 8);
        if (memnode_shift < 0) { 
                printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n"); 
                return -1; 
index 6ef9f9a762356c955fe3927fbed882b663e0dd2e..22e51beee8d377cc4adcb5173414f7ce2bddadc4 100644 (file)
@@ -351,7 +351,7 @@ void __init init_cpu_to_node(void)
                        continue;
                if (apicid_to_node[apicid] == NUMA_NO_NODE)
                        continue;
-               cpu_to_node[i] = apicid_to_node[apicid];
+               numa_set_node(i,apicid_to_node[apicid]);
        }
 }
 
index cd25300726fc7ac184009b3cf926f758eeb4c1bb..482c2576736942a3f41d75737caeb3b458d2dbcc 100644 (file)
@@ -228,7 +228,8 @@ static int nodes_cover_memory(void)
        }
 
        e820ram = end_pfn - e820_hole_size(0, end_pfn);
-       if (pxmram < e820ram) {
+       /* We seem to lose 3 pages somewhere. Allow a bit of slack. */
+       if ((long)(e820ram - pxmram) >= 1*1024*1024) {
                printk(KERN_ERR
        "SRAT: PXMs only cover %luMB of your %luMB e820 RAM. Not used.\n",
                        (pxmram << PAGE_SHIFT) >> 20,
@@ -270,7 +271,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
                return -1;
        }
 
-       memnode_shift = compute_hash_shift(nodes, nodes_weight(nodes_parsed));
+       memnode_shift = compute_hash_shift(nodes, MAX_NUMNODES);
        if (memnode_shift < 0) {
                printk(KERN_ERR
                     "SRAT: No NUMA node hash function found. Contact maintainer\n");
index 9834dce4e20fa93715c62f63f8d457eed6510ce5..0606bd2f6020fe7c3a3fc2485cf05e7893880fc1 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
+#include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/major.h>
 #include <linux/errno.h>
@@ -314,6 +315,8 @@ static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
        if (rq->bio)    /* fs request */
                rq->errors = 0;
 
+       touch_softlockup_watchdog();
+
        switch (drive->hwif->data_phase) {
        case TASKFILE_MULTI_IN:
        case TASKFILE_MULTI_OUT:
index 6e0afbb223832e3b1b038aee8d949adcc9eb441b..2708167ba17585c062a74d7d7e5ac7946da99ad2 100644 (file)
@@ -11,7 +11,6 @@ obj-$(CONFIG_KEYBOARD_XTKBD)          += xtkbd.o
 obj-$(CONFIG_KEYBOARD_AMIGA)           += amikbd.o
 obj-$(CONFIG_KEYBOARD_LOCOMO)          += locomokbd.o
 obj-$(CONFIG_KEYBOARD_NEWTON)          += newtonkbd.o
-obj-$(CONFIG_KEYBOARD_98KBD)           += 98kbd.o
 obj-$(CONFIG_KEYBOARD_CORGI)           += corgikbd.o
 obj-$(CONFIG_KEYBOARD_SPITZ)           += spitzkbd.o
 obj-$(CONFIG_KEYBOARD_HIL)             += hil_kbd.o
index 184c4129470db801c2146d485ca98a95ac50b0fd..415c49178985d6fe0f4547e3457f090d4a18820a 100644 (file)
@@ -7,7 +7,6 @@
 obj-$(CONFIG_INPUT_SPARCSPKR)          += sparcspkr.o
 obj-$(CONFIG_INPUT_PCSPKR)             += pcspkr.o
 obj-$(CONFIG_INPUT_M68K_BEEP)          += m68kspkr.o
-obj-$(CONFIG_INPUT_98SPKR)             += 98spkr.o
 obj-$(CONFIG_INPUT_UINPUT)             += uinput.o
 obj-$(CONFIG_INPUT_WISTRON_BTNS)       += wistron_btns.o
 obj-$(CONFIG_HP_SDC_RTC)               += hp_sdc_rtc.o
index d448bb5e48697ca59a17c75bc8cf228b39b4746a..3a6ae85cd69c718407fe7e991181fc711c85fa23 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/input.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
+#include <linux/interrupt.h>
 #include <asm/hardware.h>
 
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
index c88520d3d13cadc2c6b03819ab2ff9ade3861dd5..40333d61093c805383ed3f7ae245dfdd12a51f95 100644 (file)
@@ -232,6 +232,7 @@ static struct ps2pp_info *get_model_info(unsigned char model)
                { 88,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
                { 96,   0,                      0 },
                { 97,   PS2PP_KIND_TP3,         PS2PP_WHEEL | PS2PP_HWHEEL },
+               { 99,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
                { 100,  PS2PP_KIND_MX,                                  /* MX510 */
                                PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
                                PS2PP_EXTRA_BTN | PS2PP_NAV_BTN },
index b4898d8a68e21e14769c312e770048e16f28e2a6..6d9ec9ab1b9069d2b050a2a5d350e7ea09c00cb8 100644 (file)
@@ -68,15 +68,19 @@ struct trackpoint_attr_data {
        size_t field_offset;
        unsigned char command;
        unsigned char mask;
+       unsigned char inverted;
 };
 
 static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse, void *data, char *buf)
 {
        struct trackpoint_data *tp = psmouse->private;
        struct trackpoint_attr_data *attr = data;
-       unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
+       unsigned char value = *(unsigned char *)((char *)tp + attr->field_offset);
+
+       if (attr->inverted)
+               value = !value;
 
-       return sprintf(buf, "%u\n", *field);
+       return sprintf(buf, "%u\n", value);
 }
 
 static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data,
@@ -120,6 +124,9 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data,
        if (*rest || value > 1)
                return -EINVAL;
 
+       if (attr->inverted)
+               value = !value;
+
        if (*field != value) {
                *field = value;
                trackpoint_toggle_bit(&psmouse->ps2dev, attr->command, attr->mask);
@@ -129,11 +136,12 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data,
 }
 
 
-#define TRACKPOINT_BIT_ATTR(_name, _command, _mask)                            \
+#define TRACKPOINT_BIT_ATTR(_name, _command, _mask, _inv)                              \
        static struct trackpoint_attr_data trackpoint_attr_##_name = {          \
                .field_offset   = offsetof(struct trackpoint_data, _name),      \
                .command        = _command,                                     \
                .mask           = _mask,                                        \
+               .inverted       = _inv,                                         \
        };                                                                      \
        PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO,                           \
                            &trackpoint_attr_##_name,                           \
@@ -150,9 +158,9 @@ TRACKPOINT_INT_ATTR(upthresh, TP_UP_THRESH);
 TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME);
 TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV);
 
-TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON);
-TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK);
-TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV);
+TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, 0);
+TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK, 0);
+TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV, 1);
 
 static struct attribute *trackpoint_attrs[] = {
        &psmouse_attr_sensitivity.dattr.attr,
index 9857d8b6ad66520fe71d0e7b0ed8476cd0417479..050298b1a09d214b6ecf2bd7ffa09255d86364e5 100644 (file)
@@ -78,7 +78,7 @@
 
 #define TP_TOGGLE_MB           0x23    /* Disable/Enable Middle Button */
 #define TP_MASK_MB                     0x01
-#define TP_TOGGLE_EXT_DEV      0x23    /* Toggle external device */
+#define TP_TOGGLE_EXT_DEV      0x23    /* Disable external device */
 #define TP_MASK_EXT_DEV                        0x02
 #define TP_TOGGLE_DRIFT                0x23    /* Drift Correction */
 #define TP_MASK_DRIFT                  0x80
 #define TP_DEF_MB              0x00
 #define TP_DEF_PTSON           0x00
 #define TP_DEF_SKIPBACK                0x00
-#define TP_DEF_EXT_DEV         0x01
+#define TP_DEF_EXT_DEV         0x00    /* 0 means enabled */
 
 #define MAKE_PS2_CMD(params, results, cmd) ((params<<12) | (results<<8) | (cmd))
 
index 678a8599f9ffb7bb6a12518fd4a3176ad3a31578..4155197867a33be98b0f106cff9eb243c2e98440 100644 (file)
@@ -13,7 +13,6 @@ obj-$(CONFIG_SERIO_RPCKBD)    += rpckbd.o
 obj-$(CONFIG_SERIO_SA1111)     += sa1111ps2.o
 obj-$(CONFIG_SERIO_AMBAKMI)    += ambakmi.o
 obj-$(CONFIG_SERIO_Q40KBD)     += q40kbd.o
-obj-$(CONFIG_SERIO_98KBD)      += 98kbd-io.o
 obj-$(CONFIG_SERIO_GSCPS2)     += gscps2.o
 obj-$(CONFIG_HP_SDC)           += hp_sdc.o
 obj-$(CONFIG_HIL_MLC)          += hp_sdc_mlc.o hil_mlc.o
index b45a45ca7cc961c6152cb702cde8ae768b8b156e..8c12a974b411a75093c2f65319b4c88761bc5dd7 100644 (file)
 
 #define        TS_POLL_PERIOD  msecs_to_jiffies(10)
 
+/* this driver doesn't aim at the peak continuous sample rate */
+#define        SAMPLE_BITS     (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */)
+
 struct ts_event {
        /* For portability, we can't read 12 bit values using SPI (which
         * would make the controller deliver them as native byteorder u16
-        * with msbs zeroed).  Instead, we read them as two 8-byte values,
+        * with msbs zeroed).  Instead, we read them as two 8-bit values,
         * which need byteswapping then range adjustment.
         */
        __be16 x;
@@ -60,7 +63,7 @@ struct ts_event {
 };
 
 struct ads7846 {
-       struct input_dev        input;
+       struct input_dev        *input;
        char                    phys[32];
 
        struct spi_device       *spi;
@@ -68,6 +71,7 @@ struct ads7846 {
        u16                     vref_delay_usecs;
        u16                     x_plate_ohms;
 
+       u8                      read_x, read_y, read_z1, read_z2;
        struct ts_event         tc;
 
        struct spi_transfer     xfer[8];
@@ -117,10 +121,10 @@ struct ads7846 {
 #define        READ_12BIT_DFR(x) (ADS_START | ADS_A2A1A0_d_ ## x \
        | ADS_12_BIT | ADS_DFR)
 
-static const u8        read_y  = READ_12BIT_DFR(y)  | ADS_PD10_ADC_ON;
-static const u8        read_z1 = READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON;
-static const u8        read_z2 = READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON;
-static const u8        read_x  = READ_12BIT_DFR(x)  | ADS_PD10_PDOWN;  /* LAST */
+#define        READ_Y  (READ_12BIT_DFR(y)  | ADS_PD10_ADC_ON)
+#define        READ_Z1 (READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON)
+#define        READ_Z2 (READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON)
+#define        READ_X  (READ_12BIT_DFR(x)  | ADS_PD10_PDOWN)   /* LAST */
 
 /* single-ended samples need to first power up reference voltage;
  * we leave both ADC and VREF powered
@@ -128,8 +132,8 @@ static const u8     read_x  = READ_12BIT_DFR(x)  | ADS_PD10_PDOWN;  /* LAST */
 #define        READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \
        | ADS_12_BIT | ADS_SER)
 
-static const u8        ref_on = READ_12BIT_DFR(x) | ADS_PD10_ALL_ON;
-static const u8        ref_off = READ_12BIT_DFR(y) | ADS_PD10_PDOWN;
+#define        REF_ON  (READ_12BIT_DFR(x) | ADS_PD10_ALL_ON)
+#define        REF_OFF (READ_12BIT_DFR(y) | ADS_PD10_PDOWN)
 
 /*--------------------------------------------------------------------------*/
 
@@ -138,7 +142,9 @@ static const u8     ref_off = READ_12BIT_DFR(y) | ADS_PD10_PDOWN;
  */
 
 struct ser_req {
+       u8                      ref_on;
        u8                      command;
+       u8                      ref_off;
        u16                     scratch;
        __be16                  sample;
        struct spi_message      msg;
@@ -152,7 +158,7 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
        struct ser_req          *req = kzalloc(sizeof *req, SLAB_KERNEL);
        int                     status;
        int                     sample;
-       int                     i;
+       int                     i;
 
        if (!req)
                return -ENOMEM;
@@ -160,7 +166,8 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
        INIT_LIST_HEAD(&req->msg.transfers);
 
        /* activate reference, so it has time to settle; */
-       req->xfer[0].tx_buf = &ref_on;
+       req->ref_on = REF_ON;
+       req->xfer[0].tx_buf = &req->ref_on;
        req->xfer[0].len = 1;
        req->xfer[1].rx_buf = &req->scratch;
        req->xfer[1].len = 2;
@@ -182,7 +189,8 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
        /* REVISIT:  take a few more samples, and compare ... */
 
        /* turn off reference */
-       req->xfer[4].tx_buf = &ref_off;
+       req->ref_off = REF_OFF;
+       req->xfer[4].tx_buf = &req->ref_off;
        req->xfer[4].len = 1;
        req->xfer[5].rx_buf = &req->scratch;
        req->xfer[5].len = 2;
@@ -236,11 +244,12 @@ SHOW(vbatt)
 
 static void ads7846_rx(void *ads)
 {
-       struct ads7846  *ts = ads;
-       unsigned        Rt;
-       unsigned        sync = 0;
-       u16             x, y, z1, z2;
-       unsigned long   flags;
+       struct ads7846          *ts = ads;
+       struct input_dev        *input_dev = ts->input;
+       unsigned                Rt;
+       unsigned                sync = 0;
+       u16                     x, y, z1, z2;
+       unsigned long           flags;
 
        /* adjust:  12 bit samples (left aligned), built from
         * two 8 bit values writen msb-first.
@@ -276,21 +285,21 @@ static void ads7846_rx(void *ads)
         * won't notice that, even if nPENIRQ never fires ...
         */
        if (!ts->pendown && Rt != 0) {
-               input_report_key(&ts->input, BTN_TOUCH, 1);
+               input_report_key(input_dev, BTN_TOUCH, 1);
                sync = 1;
        } else if (ts->pendown && Rt == 0) {
-               input_report_key(&ts->input, BTN_TOUCH, 0);
+               input_report_key(input_dev, BTN_TOUCH, 0);
                sync = 1;
        }
 
        if (Rt) {
-               input_report_abs(&ts->input, ABS_X, x);
-               input_report_abs(&ts->input, ABS_Y, y);
-               input_report_abs(&ts->input, ABS_PRESSURE, Rt);
+               input_report_abs(input_dev, ABS_X, x);
+               input_report_abs(input_dev, ABS_Y, y);
+               input_report_abs(input_dev, ABS_PRESSURE, Rt);
                sync = 1;
        }
        if (sync)
-               input_sync(&ts->input);
+               input_sync(input_dev);
 
 #ifdef VERBOSE
        if (Rt || ts->pendown)
@@ -396,9 +405,10 @@ static int ads7846_resume(struct spi_device *spi)
 static int __devinit ads7846_probe(struct spi_device *spi)
 {
        struct ads7846                  *ts;
+       struct input_dev                *input_dev;
        struct ads7846_platform_data    *pdata = spi->dev.platform_data;
        struct spi_transfer             *x;
-       int                             i;
+       int                             err;
 
        if (!spi->irq) {
                dev_dbg(&spi->dev, "no IRQ?\n");
@@ -411,9 +421,9 @@ static int __devinit ads7846_probe(struct spi_device *spi)
        }
 
        /* don't exceed max specified sample rate */
-       if (spi->max_speed_hz > (125000 * 16)) {
+       if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) {
                dev_dbg(&spi->dev, "f(sample) %d KHz?\n",
-                               (spi->max_speed_hz/16)/1000);
+                               (spi->max_speed_hz/SAMPLE_BITS)/1000);
                return -EINVAL;
        }
 
@@ -423,13 +433,18 @@ static int __devinit ads7846_probe(struct spi_device *spi)
         * to discard the four garbage LSBs.
         */
 
-       if (!(ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL)))
-               return -ENOMEM;
+       ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!ts || !input_dev) {
+               err = -ENOMEM;
+               goto err_free_mem;
+       }
 
        dev_set_drvdata(&spi->dev, ts);
+       spi->dev.power.power_state = PMSG_ON;
 
        ts->spi = spi;
-       spi->dev.power.power_state = PMSG_ON;
+       ts->input = input_dev;
 
        init_timer(&ts->timer);
        ts->timer.data = (unsigned long) ts;
@@ -439,70 +454,80 @@ static int __devinit ads7846_probe(struct spi_device *spi)
        ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
        ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
 
-       init_input_dev(&ts->input);
+       snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id);
 
-       ts->input.dev = &spi->dev;
-       ts->input.name = "ADS784x Touchscreen";
-       snprintf(ts->phys, sizeof ts->phys, "%s/input0", spi->dev.bus_id);
-       ts->input.phys = ts->phys;
+       input_dev->name = "ADS784x Touchscreen";
+       input_dev->phys = ts->phys;
+       input_dev->cdev.dev = &spi->dev;
 
-       ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       ts->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-       input_set_abs_params(&ts->input, ABS_X,
+       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_set_abs_params(input_dev, ABS_X,
                        pdata->x_min ? : 0,
                        pdata->x_max ? : MAX_12BIT,
                        0, 0);
-       input_set_abs_params(&ts->input, ABS_Y,
+       input_set_abs_params(input_dev, ABS_Y,
                        pdata->y_min ? : 0,
                        pdata->y_max ? : MAX_12BIT,
                        0, 0);
-       input_set_abs_params(&ts->input, ABS_PRESSURE,
+       input_set_abs_params(input_dev, ABS_PRESSURE,
                        pdata->pressure_min, pdata->pressure_max, 0, 0);
 
-       input_register_device(&ts->input);
-
        /* set up the transfers to read touchscreen state; this assumes we
         * use formula #2 for pressure, not #3.
         */
+       INIT_LIST_HEAD(&ts->msg.transfers);
        x = ts->xfer;
 
        /* y- still on; turn on only y+ (and ADC) */
-       x->tx_buf = &read_y;
+       ts->read_y = READ_Y;
+       x->tx_buf = &ts->read_y;
        x->len = 1;
+       spi_message_add_tail(x, &ts->msg);
+
        x++;
        x->rx_buf = &ts->tc.y;
        x->len = 2;
-       x++;
+       spi_message_add_tail(x, &ts->msg);
 
        /* turn y+ off, x- on; we'll use formula #2 */
        if (ts->model == 7846) {
-               x->tx_buf = &read_z1;
+               x++;
+               ts->read_z1 = READ_Z1;
+               x->tx_buf = &ts->read_z1;
                x->len = 1;
+               spi_message_add_tail(x, &ts->msg);
+
                x++;
                x->rx_buf = &ts->tc.z1;
                x->len = 2;
-               x++;
+               spi_message_add_tail(x, &ts->msg);
 
-               x->tx_buf = &read_z2;
+               x++;
+               ts->read_z2 = READ_Z2;
+               x->tx_buf = &ts->read_z2;
                x->len = 1;
+               spi_message_add_tail(x, &ts->msg);
+
                x++;
                x->rx_buf = &ts->tc.z2;
                x->len = 2;
-               x++;
+               spi_message_add_tail(x, &ts->msg);
        }
 
        /* turn y- off, x+ on, then leave in lowpower */
-       x->tx_buf = &read_x;
+       x++;
+       ts->read_x = READ_X;
+       x->tx_buf = &ts->read_x;
        x->len = 1;
+       spi_message_add_tail(x, &ts->msg);
+
        x++;
        x->rx_buf = &ts->tc.x;
        x->len = 2;
-       x++;
-
-       CS_CHANGE(x[-1]);
+       CS_CHANGE(*x);
+       spi_message_add_tail(x, &ts->msg);
 
-       for (i = 0; i < x - ts->xfer; i++)
-               spi_message_add_tail(&ts->xfer[i], &ts->msg);
        ts->msg.complete = ads7846_rx;
        ts->msg.context = ts;
 
@@ -510,9 +535,8 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                        SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING,
                        spi->dev.bus_id, ts)) {
                dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
-               input_unregister_device(&ts->input);
-               kfree(ts);
-               return -EBUSY;
+               err = -EBUSY;
+               goto err_free_mem;
        }
 
        dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq);
@@ -534,7 +558,18 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                device_create_file(&spi->dev, &dev_attr_vbatt);
        device_create_file(&spi->dev, &dev_attr_vaux);
 
+       err = input_register_device(input_dev);
+       if (err)
+               goto err_free_irq;
+
        return 0;
+
+ err_free_irq:
+       free_irq(spi->irq, ts);
+ err_free_mem:
+       input_free_device(input_dev);
+       kfree(ts);
+       return err;
 }
 
 static int __devexit ads7846_remove(struct spi_device *spi)
@@ -554,7 +589,7 @@ static int __devexit ads7846_remove(struct spi_device *spi)
                device_remove_file(&spi->dev, &dev_attr_vbatt);
        device_remove_file(&spi->dev, &dev_attr_vaux);
 
-       input_unregister_device(&ts->input);
+       input_unregister_device(ts->input);
        kfree(ts);
 
        dev_dbg(&spi->dev, "unregistered touchscreen\n");
index 9a2c7605d49c930a45c10aaad9b3cc772dd2805e..642a61b6d0a4ebd3a89732c002a071dc633156ce 100644 (file)
@@ -452,8 +452,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
        } else if (func == MPI_FUNCTION_EVENT_ACK) {
                dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
                                ioc->name));
-       } else if (func == MPI_FUNCTION_CONFIG ||
-                  func == MPI_FUNCTION_TOOLBOX) {
+       } else if (func == MPI_FUNCTION_CONFIG) {
                CONFIGPARMS *pCfg;
                unsigned long flags;
 
@@ -5326,115 +5325,6 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
        return rc;
 }
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *     mpt_toolbox - Generic function to issue toolbox message
- *     @ioc - Pointer to an adapter structure
- *     @cfg - Pointer to a toolbox structure. Struct contains
- *             action, page address, direction, physical address
- *             and pointer to a configuration page header
- *             Page header is updated.
- *
- *     Returns 0 for success
- *     -EPERM if not allowed due to ISR context
- *     -EAGAIN if no msg frames currently available
- *     -EFAULT for non-successful reply or no reply (timeout)
- */
-int
-mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
-{
-       ToolboxIstwiReadWriteRequest_t  *pReq;
-       MPT_FRAME_HDR   *mf;
-       struct pci_dev  *pdev;
-       unsigned long    flags;
-       int              rc;
-       u32              flagsLength;
-       int              in_isr;
-
-       /*      Prevent calling wait_event() (below), if caller happens
-        *      to be in ISR context, because that is fatal!
-        */
-       in_isr = in_interrupt();
-       if (in_isr) {
-               dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
-                               ioc->name));
-               return -EPERM;
-       }
-
-       /* Get and Populate a free Frame
-        */
-       if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
-               dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
-                               ioc->name));
-               return -EAGAIN;
-       }
-       pReq = (ToolboxIstwiReadWriteRequest_t  *)mf;
-       pReq->Tool = pCfg->action;
-       pReq->Reserved = 0;
-       pReq->ChainOffset = 0;
-       pReq->Function = MPI_FUNCTION_TOOLBOX;
-       pReq->Reserved1 = 0;
-       pReq->Reserved2 = 0;
-       pReq->MsgFlags = 0;
-       pReq->Flags = pCfg->dir;
-       pReq->BusNum = 0;
-       pReq->Reserved3 = 0;
-       pReq->NumAddressBytes = 0x01;
-       pReq->Reserved4 = 0;
-       pReq->DataLength = cpu_to_le16(0x04);
-       pdev = ioc->pcidev;
-       if (pdev->devfn & 1)
-               pReq->DeviceAddr = 0xB2;
-       else
-               pReq->DeviceAddr = 0xB0;
-       pReq->Addr1 = 0;
-       pReq->Addr2 = 0;
-       pReq->Addr3 = 0;
-       pReq->Reserved5 = 0;
-
-       /* Add a SGE to the config request.
-        */
-
-       flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
-
-       mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
-
-       dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
-               ioc->name, pReq->Tool));
-
-       /* Append pCfg pointer to end of mf
-        */
-       *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) =  (void *) pCfg;
-
-       /* Initalize the timer
-        */
-       init_timer(&pCfg->timer);
-       pCfg->timer.data = (unsigned long) ioc;
-       pCfg->timer.function = mpt_timer_expired;
-       pCfg->wait_done = 0;
-
-       /* Set the timer; ensure 10 second minimum */
-       if (pCfg->timeout < 10)
-               pCfg->timer.expires = jiffies + HZ*10;
-       else
-               pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
-
-       /* Add to end of Q, set timer and then issue this command */
-       spin_lock_irqsave(&ioc->FreeQlock, flags);
-       list_add_tail(&pCfg->linkage, &ioc->configQ);
-       spin_unlock_irqrestore(&ioc->FreeQlock, flags);
-
-       add_timer(&pCfg->timer);
-       mpt_put_msg_frame(mpt_base_index, ioc, mf);
-       wait_event(mpt_waitq, pCfg->wait_done);
-
-       /* mf has been freed - do not access */
-
-       rc = pCfg->status;
-
-       return rc;
-}
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *     mpt_timer_expired - Call back for timer process.
@@ -6142,7 +6032,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
        if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
                int idx;
 
-               idx = ioc->eventContext % ioc->eventLogSize;
+               idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
 
                ioc->events[idx].event = event;
                ioc->events[idx].eventContext = ioc->eventContext;
@@ -6540,7 +6430,6 @@ EXPORT_SYMBOL(mpt_lan_index);
 EXPORT_SYMBOL(mpt_stm_index);
 EXPORT_SYMBOL(mpt_HardResetHandler);
 EXPORT_SYMBOL(mpt_config);
-EXPORT_SYMBOL(mpt_toolbox);
 EXPORT_SYMBOL(mpt_findImVolumes);
 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
 EXPORT_SYMBOL(mpt_alloc_fw_memory);
index ea2649ecad1fcccb9f19e33cc8bf1cce9276bd96..723d543009530262d3f2bdbe68ea3486108856f5 100644 (file)
@@ -616,6 +616,7 @@ typedef struct _MPT_ADAPTER
         * increments by 32 bytes
         */
        int                      errata_flag_1064;
+       int                      aen_event_read_flag; /* flag to indicate event log was read*/
        u8                       FirstWhoInit;
        u8                       upload_fw;     /* If set, do a fw upload */
        u8                       reload_fw;     /* Force a FW Reload on next reset */
@@ -1026,7 +1027,6 @@ extern u32         mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
 extern void     mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
 extern int      mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
 extern int      mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
-extern int      mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
 extern void     mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
 extern void     mpt_free_fw_memory(MPT_ADAPTER *ioc);
 extern int      mpt_findImVolumes(MPT_ADAPTER *ioc);
index bdf709987982b37509646e553f2482dd2d3d60c7..9b64e07400da464606d1153fce1f6c20f1eb7d4d 100644 (file)
@@ -136,6 +136,12 @@ static void mptctl_free_tm_flags(MPT_ADAPTER *ioc);
  */
 static int  mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
 
+/*
+ * Event Handler function
+ */
+static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
+struct fasync_struct *async_queue=NULL;
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  * Scatter gather list (SGL) sizes and limits...
@@ -385,18 +391,18 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
        }
 
        /* Now wait for the command to complete */
-       ii = wait_event_interruptible_timeout(mptctl_wait,
+       ii = wait_event_timeout(mptctl_wait,
             ioctl->wait_done == 1,
             HZ*5 /* 5 second timeout */);
 
        if(ii <=0 && (ioctl->wait_done != 1 ))  {
+               mpt_free_msg_frame(hd->ioc, mf);
                ioctl->wait_done = 0;
                retval = -1; /* return failure */
        }
 
 mptctl_bus_reset_done:
 
-       mpt_free_msg_frame(hd->ioc, mf);
        mptctl_free_tm_flags(ioctl->ioc);
        return retval;
 }
@@ -471,6 +477,69 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
        return 1;
 }
 
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* ASYNC Event Notification Support */
+static int
+mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
+{
+       u8 event;
+
+       event = le32_to_cpu(pEvReply->Event) & 0xFF;
+
+       dctlprintk(("%s() called\n", __FUNCTION__));
+       if(async_queue == NULL)
+               return 1;
+
+       /* Raise SIGIO for persistent events.
+        * TODO - this define is not in MPI spec yet,
+        * but they plan to set it to 0x21
+        */
+        if (event == 0x21 ) {
+               ioc->aen_event_read_flag=1;
+               dctlprintk(("Raised SIGIO to application\n"));
+               devtprintk(("Raised SIGIO to application\n"));
+               kill_fasync(&async_queue, SIGIO, POLL_IN);
+               return 1;
+        }
+
+       /* This flag is set after SIGIO was raised, and
+        * remains set until the application has read
+        * the event log via ioctl=MPTEVENTREPORT
+        */
+       if(ioc->aen_event_read_flag)
+               return 1;
+
+       /* Signal only for the events that are
+        * requested for by the application
+        */
+       if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
+               ioc->aen_event_read_flag=1;
+               dctlprintk(("Raised SIGIO to application\n"));
+               devtprintk(("Raised SIGIO to application\n"));
+               kill_fasync(&async_queue, SIGIO, POLL_IN);
+       }
+       return 1;
+}
+
+static int
+mptctl_fasync(int fd, struct file *filep, int mode)
+{
+       MPT_ADAPTER     *ioc;
+
+       list_for_each_entry(ioc, &ioc_list, list)
+               ioc->aen_event_read_flag=0;
+
+       dctlprintk(("%s() called\n", __FUNCTION__));
+       return fasync_helper(fd, filep, mode, &async_queue);
+}
+
+static int
+mptctl_release(struct inode *inode, struct file *filep)
+{
+       dctlprintk(("%s() called\n", __FUNCTION__));
+       return fasync_helper(-1, filep, 0, &async_queue);
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  MPT ioctl handler
@@ -674,22 +743,23 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
        u16                      iocstat;
        pFWDownloadReply_t       ReplyMsg = NULL;
 
-       dctlprintk((KERN_INFO "mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id));
+       dctlprintk(("mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id));
 
-       dctlprintk((KERN_INFO "DbG: kfwdl.bufp  = %p\n", ufwbuf));
-       dctlprintk((KERN_INFO "DbG: kfwdl.fwlen = %d\n", (int)fwlen));
-       dctlprintk((KERN_INFO "DbG: kfwdl.ioc   = %04xh\n", ioc));
+       dctlprintk(("DbG: kfwdl.bufp  = %p\n", ufwbuf));
+       dctlprintk(("DbG: kfwdl.fwlen = %d\n", (int)fwlen));
+       dctlprintk(("DbG: kfwdl.ioc   = %04xh\n", ioc));
 
-       if ((ioc = mpt_verify_adapter(ioc, &iocp)) < 0) {
-               dctlprintk(("%s@%d::_ioctl_fwdl - ioc%d not found!\n",
-                               __FILE__, __LINE__, ioc));
+       if (mpt_verify_adapter(ioc, &iocp) < 0) {
+               dctlprintk(("ioctl_fwdl - ioc%d not found!\n",
+                                ioc));
                return -ENODEV; /* (-6) No such device or address */
-       }
+       } else {
 
-       /*  Valid device. Get a message frame and construct the FW download message.
-        */
-       if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
-               return -EAGAIN;
+               /*  Valid device. Get a message frame and construct the FW download message.
+               */
+               if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
+                       return -EAGAIN;
+       }
        dlmsg = (FWDownload_t*) mf;
        ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
        sgOut = (char *) (ptsge + 1);
@@ -702,7 +772,11 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
        dlmsg->ChainOffset = 0;
        dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD;
        dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0;
-       dlmsg->MsgFlags = 0;
+       if (iocp->facts.MsgVersion >= MPI_VERSION_01_05)
+               dlmsg->MsgFlags = MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT;
+       else
+               dlmsg->MsgFlags = 0;
+
 
        /* Set up the Transaction SGE.
         */
@@ -754,7 +828,7 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
                goto fwdl_out;
        }
 
-       dctlprintk((KERN_INFO "DbG: sgl buffer  = %p, sgfrags = %d\n", sgl, numfrags));
+       dctlprintk(("DbG: sgl buffer  = %p, sgfrags = %d\n", sgl, numfrags));
 
        /*
         * Parse SG list, copying sgl itself,
@@ -803,11 +877,11 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
        /*
         * Finally, perform firmware download.
         */
-       iocp->ioctl->wait_done = 0;
+       ReplyMsg = NULL;
        mpt_put_msg_frame(mptctl_id, iocp, mf);
 
        /* Now wait for the command to complete */
-       ret = wait_event_interruptible_timeout(mptctl_wait,
+       ret = wait_event_timeout(mptctl_wait,
             iocp->ioctl->wait_done == 1,
             HZ*60);
 
@@ -1145,7 +1219,9 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
        /* Fill in the data and return the structure to the calling
         * program
         */
-       if (ioc->bus_type == FC)
+       if (ioc->bus_type == SAS)
+               karg->adapterType = MPT_IOCTL_INTERFACE_SAS;
+       else if (ioc->bus_type == FC)
                karg->adapterType = MPT_IOCTL_INTERFACE_FC;
        else
                karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;
@@ -1170,12 +1246,11 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
                karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
                karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
        } else if (cim_rev == 2) {
-               /* Get the PCI bus, device, function and segment ID numbers 
+               /* Get the PCI bus, device, function and segment ID numbers
                   for the IOC */
                karg->pciInfo.u.bits.busNumber = pdev->bus->number;
                karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
                karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
-               karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
                karg->pciInfo.segmentID = pci_domain_nr(pdev->bus);
        }
 
@@ -1500,7 +1575,7 @@ mptctl_eventquery (unsigned long arg)
                return -ENODEV;
        }
 
-       karg.eventEntries = ioc->eventLogSize;
+       karg.eventEntries = MPTCTL_EVENT_LOG_SIZE;
        karg.eventTypes = ioc->eventTypes;
 
        /* Copy the data from kernel memory to user memory
@@ -1550,7 +1625,6 @@ mptctl_eventenable (unsigned long arg)
                memset(ioc->events, 0, sz);
                ioc->alloc_total += sz;
 
-               ioc->eventLogSize = MPTCTL_EVENT_LOG_SIZE;
                ioc->eventContext = 0;
         }
 
@@ -1590,7 +1664,7 @@ mptctl_eventreport (unsigned long arg)
        maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);
 
 
-       max = ioc->eventLogSize < maxEvents ? ioc->eventLogSize : maxEvents;
+       max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents;
 
        /* If fewer than 1 event is requested, there must have
         * been some type of error.
@@ -1598,6 +1672,9 @@ mptctl_eventreport (unsigned long arg)
        if ((max < 1) || !ioc->events)
                return -ENODATA;
 
+       /* reset this flag so SIGIO can restart */
+       ioc->aen_event_read_flag=0;
+
        /* Copy the data from kernel memory to user memory
         */
        numBytes = max * sizeof(MPT_IOCTL_EVENTS);
@@ -1817,6 +1894,8 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
        case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
        case MPI_FUNCTION_FW_DOWNLOAD:
        case MPI_FUNCTION_FC_PRIMITIVE_SEND:
+       case MPI_FUNCTION_TOOLBOX:
+       case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
                break;
 
        case MPI_FUNCTION_SCSI_IO_REQUEST:
@@ -1837,7 +1916,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
                                goto done_free_mem;
                        }
 
-                       pScsiReq->MsgFlags = mpt_msg_flags();
+                       pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
+                       pScsiReq->MsgFlags |= mpt_msg_flags();
+
 
                        /* verify that app has not requested
                         *      more sense data than driver
@@ -1888,6 +1969,25 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
                }
                break;
 
+       case MPI_FUNCTION_SMP_PASSTHROUGH:
+               /* Check mf->PassthruFlags to determine if
+                * transfer is ImmediateMode or not.
+                * Immediate mode returns data in the ReplyFrame.
+                * Else, we are sending request and response data
+                * in two SGLs at the end of the mf.
+                */
+               break;
+
+       case MPI_FUNCTION_SATA_PASSTHROUGH:
+               if (!ioc->sh) {
+                       printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+                               "SCSI driver is not loaded. \n",
+                                       __FILE__, __LINE__);
+                       rc = -EFAULT;
+                       goto done_free_mem;
+               }
+               break;
+
        case MPI_FUNCTION_RAID_ACTION:
                /* Just add a SGE
                 */
@@ -1900,7 +2000,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
                        int scsidir = MPI_SCSIIO_CONTROL_READ;
                        int dataSize;
 
-                       pScsiReq->MsgFlags = mpt_msg_flags();
+                       pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
+                       pScsiReq->MsgFlags |= mpt_msg_flags();
+
 
                        /* verify that app has not requested
                         *      more sense data than driver
@@ -2130,7 +2232,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
 
        /* Now wait for the command to complete */
        timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
-       timeout = wait_event_interruptible_timeout(mptctl_wait,
+       timeout = wait_event_timeout(mptctl_wait,
             ioc->ioctl->wait_done == 1,
             HZ*timeout);
 
@@ -2246,13 +2348,16 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
        hp_host_info_t  __user *uarg = (void __user *) arg;
        MPT_ADAPTER             *ioc;
        struct pci_dev          *pdev;
-       char                    *pbuf;
+       char                    *pbuf=NULL;
        dma_addr_t              buf_dma;
        hp_host_info_t          karg;
        CONFIGPARMS             cfg;
        ConfigPageHeader_t      hdr;
        int                     iocnum;
        int                     rc, cim_rev;
+       ToolboxIstwiReadWriteRequest_t  *IstwiRWRequest;
+       MPT_FRAME_HDR           *mf = NULL;
+       MPIHeader_t             *mpi_hdr;
 
        dctlprintk((": mptctl_hp_hostinfo called.\n"));
        /* Reset long to int. Should affect IA64 and SPARC only
@@ -2370,7 +2475,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
 
        karg.base_io_addr = pci_resource_start(pdev, 0);
 
-       if (ioc->bus_type == FC)
+       if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
                karg.bus_phys_width = HP_BUS_WIDTH_UNK;
        else
                karg.bus_phys_width = HP_BUS_WIDTH_16;
@@ -2388,20 +2493,67 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
                }
        }
 
-       cfg.pageAddr = 0;
-       cfg.action = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
-       cfg.dir = MPI_TB_ISTWI_FLAGS_READ;
-       cfg.timeout = 10;
+       /* 
+        * Gather ISTWI(Industry Standard Two Wire Interface) Data
+        */
+       if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
+               dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
+                   ioc->name,__FUNCTION__));
+               goto out;
+       }
+
+       IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
+       mpi_hdr = (MPIHeader_t *) mf;
+       memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
+       IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
+       IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
+       IstwiRWRequest->MsgContext = mpi_hdr->MsgContext;
+       IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
+       IstwiRWRequest->NumAddressBytes = 0x01;
+       IstwiRWRequest->DataLength = cpu_to_le16(0x04);
+       if (pdev->devfn & 1)
+               IstwiRWRequest->DeviceAddr = 0xB2;
+       else
+               IstwiRWRequest->DeviceAddr = 0xB0;
+
        pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
-       if (pbuf) {
-               cfg.physAddr = buf_dma;
-               if ((mpt_toolbox(ioc, &cfg)) == 0) {
-                       karg.rsvd = *(u32 *)pbuf;
-               }
-               pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
-               pbuf = NULL;
+       if (!pbuf)
+               goto out;
+       mpt_add_sge((char *)&IstwiRWRequest->SGL,
+           (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);
+
+       ioc->ioctl->wait_done = 0;
+       mpt_put_msg_frame(mptctl_id, ioc, mf);
+
+       rc = wait_event_timeout(mptctl_wait,
+            ioc->ioctl->wait_done == 1,
+            HZ*MPT_IOCTL_DEFAULT_TIMEOUT /* 10 sec */);
+
+       if(rc <=0 && (ioc->ioctl->wait_done != 1 )) {
+               /* 
+                * Now we need to reset the board
+                */
+               mpt_free_msg_frame(ioc, mf);
+               mptctl_timeout_expired(ioc->ioctl);
+               goto out;
        }
 
+       /* 
+        *ISTWI Data Definition
+        * pbuf[0] = FW_VERSION = 0x4
+        * pbuf[1] = Bay Count = 6 or 4 or 2, depending on
+        *  the config, you should be seeing one out of these three values
+        * pbuf[2] = Drive Installed Map = bit pattern depend on which
+        *   bays have drives in them
+        * pbuf[3] = Checksum (0x100 = (byte0 + byte2 + byte3)
+        */
+       if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID)
+               karg.rsvd = *(u32 *)pbuf;
+
+ out:
+       if (pbuf)
+               pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
+
        /* Copy the data from kernel memory to user memory
         */
        if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
@@ -2459,7 +2611,7 @@ mptctl_hp_targetinfo(unsigned long arg)
 
        /*  There is nothing to do for FCP parts.
         */
-       if (ioc->bus_type == FC)
+       if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
                return 0;
 
        if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
@@ -2569,6 +2721,8 @@ mptctl_hp_targetinfo(unsigned long arg)
 static struct file_operations mptctl_fops = {
        .owner =        THIS_MODULE,
        .llseek =       no_llseek,
+       .release =      mptctl_release,
+       .fasync =       mptctl_fasync,
        .unlocked_ioctl = mptctl_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = compat_mpctl_ioctl,
@@ -2813,6 +2967,11 @@ static int __init mptctl_init(void)
                /* FIXME! */
        }
 
+       if (mpt_event_register(mptctl_id, mptctl_event_process) == 0) {
+               devtprintk((KERN_INFO MYNAM
+                 ": Registered for IOC event notifications\n"));
+       }
+
        return 0;
 
 out_fail:
index 518996e03481088f81ae3ce3ad165c205fb0c4a9..a2f8a97992e68106b04514e1b4c404ebc0f24ef7 100644 (file)
@@ -169,8 +169,10 @@ struct mpt_ioctl_pci_info2 {
  *  Read only.
  *  Data starts at offset 0xC
  */
-#define MPT_IOCTL_INTERFACE_FC         (0x01)
 #define MPT_IOCTL_INTERFACE_SCSI       (0x00)
+#define MPT_IOCTL_INTERFACE_FC         (0x01)
+#define MPT_IOCTL_INTERFACE_FC_IP      (0x02)
+#define MPT_IOCTL_INTERFACE_SAS                (0x03)
 #define MPT_IOCTL_VERSION_LENGTH       (32)
 
 struct mpt_ioctl_iocinfo {
index 05789e50546491df632331c58b6b5ff3e867f4fa..4fee6befc93d0e900fa66fae4e837ef8ac054b51 100644 (file)
@@ -2489,7 +2489,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
                                int idx;
                                MPT_ADAPTER *ioc = hd->ioc;
 
-                               idx = ioc->eventContext % ioc->eventLogSize;
+                               idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
                                ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
                                ioc->events[idx].eventContext = ioc->eventContext;
 
index 37ee7f8dc82fe305195472e0ad5dd281e5c5f219..9fef29d978b5e676fead18b320f86cbd19c533b4 100644 (file)
@@ -97,6 +97,13 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
        if (data->flags & MMC_DATA_READ) {
                datactrl |= MCI_DPSM_DIRECTION;
                irqmask = MCI_RXFIFOHALFFULLMASK;
+
+               /*
+                * If we have less than a FIFOSIZE of bytes to transfer,
+                * trigger a PIO interrupt as soon as any data is available.
+                */
+               if (host->size < MCI_FIFOSIZE)
+                       irqmask |= MCI_RXDATAAVLBLMASK;
        } else {
                /*
                 * We don't actually need to include "FIFO empty" here
index 4d7d47cf2394a38ea9d4d760cfecd12bbc10f149..a5f2ba9a8fdb57079f04d8074ed112b93c3d8209 100644 (file)
@@ -710,10 +710,9 @@ static inline void
 _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
                            struct zfcp_adapter *adapter,
                            struct scsi_cmnd *scsi_cmnd,
-                           struct zfcp_fsf_req *new_fsf_req)
+                           struct zfcp_fsf_req *fsf_req,
+                           struct zfcp_fsf_req *old_fsf_req)
 {
-       struct zfcp_fsf_req *fsf_req =
-           (struct zfcp_fsf_req *)scsi_cmnd->host_scribble;
        struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf;
        struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
        unsigned long flags;
@@ -727,19 +726,20 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
                if (offset == 0) {
                        strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
                        strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE);
-                       if (scsi_cmnd->device) {
-                               rec->scsi_id = scsi_cmnd->device->id;
-                               rec->scsi_lun = scsi_cmnd->device->lun;
+                       if (scsi_cmnd != NULL) {
+                               if (scsi_cmnd->device) {
+                                       rec->scsi_id = scsi_cmnd->device->id;
+                                       rec->scsi_lun = scsi_cmnd->device->lun;
+                               }
+                               rec->scsi_result = scsi_cmnd->result;
+                               rec->scsi_cmnd = (unsigned long)scsi_cmnd;
+                               rec->scsi_serial = scsi_cmnd->serial_number;
+                               memcpy(rec->scsi_opcode, &scsi_cmnd->cmnd,
+                                       min((int)scsi_cmnd->cmd_len,
+                                               ZFCP_DBF_SCSI_OPCODE));
+                               rec->scsi_retries = scsi_cmnd->retries;
+                               rec->scsi_allowed = scsi_cmnd->allowed;
                        }
-                       rec->scsi_result = scsi_cmnd->result;
-                       rec->scsi_cmnd = (unsigned long)scsi_cmnd;
-                       rec->scsi_serial = scsi_cmnd->serial_number;
-                       memcpy(rec->scsi_opcode,
-                              &scsi_cmnd->cmnd,
-                              min((int)scsi_cmnd->cmd_len,
-                                  ZFCP_DBF_SCSI_OPCODE));
-                       rec->scsi_retries = scsi_cmnd->retries;
-                       rec->scsi_allowed = scsi_cmnd->allowed;
                        if (fsf_req != NULL) {
                                fcp_rsp = (struct fcp_rsp_iu *)
                                    &(fsf_req->qtcb->bottom.io.fcp_rsp);
@@ -772,15 +772,8 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
                                rec->fsf_seqno = fsf_req->seq_no;
                                rec->fsf_issued = fsf_req->issued;
                        }
-                       if (new_fsf_req != NULL) {
-                               rec->type.new_fsf_req.fsf_reqid =
-                                   (unsigned long)
-                                   new_fsf_req;
-                               rec->type.new_fsf_req.fsf_seqno =
-                                   new_fsf_req->seq_no;
-                               rec->type.new_fsf_req.fsf_issued =
-                                   new_fsf_req->issued;
-                       }
+                       rec->type.old_fsf_reqid =
+                                   (unsigned long) old_fsf_req;
                } else {
                        strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
                        dump->total_size = buflen;
@@ -801,19 +794,21 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
 inline void
 zfcp_scsi_dbf_event_result(const char *tag, int level,
                           struct zfcp_adapter *adapter,
-                          struct scsi_cmnd *scsi_cmnd)
+                          struct scsi_cmnd *scsi_cmnd,
+                          struct zfcp_fsf_req *fsf_req)
 {
-       _zfcp_scsi_dbf_event_common("rslt",
-                                   tag, level, adapter, scsi_cmnd, NULL);
+       _zfcp_scsi_dbf_event_common("rslt", tag, level,
+                       adapter, scsi_cmnd, fsf_req, NULL);
 }
 
 inline void
 zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,
                          struct scsi_cmnd *scsi_cmnd,
-                         struct zfcp_fsf_req *new_fsf_req)
+                         struct zfcp_fsf_req *new_fsf_req,
+                         struct zfcp_fsf_req *old_fsf_req)
 {
-       _zfcp_scsi_dbf_event_common("abrt",
-                                   tag, 1, adapter, scsi_cmnd, new_fsf_req);
+       _zfcp_scsi_dbf_event_common("abrt", tag, 1,
+                       adapter, scsi_cmnd, new_fsf_req, old_fsf_req);
 }
 
 inline void
@@ -823,7 +818,7 @@ zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
        struct zfcp_adapter *adapter = unit->port->adapter;
 
        _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst",
-                                   tag, 1, adapter, scsi_cmnd, NULL);
+                       tag, 1, adapter, scsi_cmnd, NULL, NULL);
 }
 
 static int
@@ -856,6 +851,10 @@ zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view,
                             rec->scsi_retries);
        len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x",
                             rec->scsi_allowed);
+       if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) {
+               len += zfcp_dbf_view(out_buf + len, "old_fsf_reqid", "0x%0Lx",
+                                    rec->type.old_fsf_reqid);
+       }
        len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",
                             rec->fsf_reqid);
        len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",
@@ -883,21 +882,6 @@ zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view,
                                       min((int)rec->type.fcp.sns_info_len,
                                           ZFCP_DBF_SCSI_FCP_SNS_INFO), 0,
                                       rec->type.fcp.sns_info_len);
-       } else if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) {
-               len += zfcp_dbf_view(out_buf + len, "fsf_reqid_abort", "0x%0Lx",
-                                    rec->type.new_fsf_req.fsf_reqid);
-               len += zfcp_dbf_view(out_buf + len, "fsf_seqno_abort", "0x%08x",
-                                    rec->type.new_fsf_req.fsf_seqno);
-               len += zfcp_dbf_stck(out_buf + len, "fsf_issued",
-                                    rec->type.new_fsf_req.fsf_issued);
-       } else if ((strncmp(rec->tag, "trst", ZFCP_DBF_TAG_SIZE) == 0) ||
-                  (strncmp(rec->tag, "lrst", ZFCP_DBF_TAG_SIZE) == 0)) {
-               len += zfcp_dbf_view(out_buf + len, "fsf_reqid_reset", "0x%0Lx",
-                                    rec->type.new_fsf_req.fsf_reqid);
-               len += zfcp_dbf_view(out_buf + len, "fsf_seqno_reset", "0x%08x",
-                                    rec->type.new_fsf_req.fsf_seqno);
-               len += zfcp_dbf_stck(out_buf + len, "fsf_issued",
-                                    rec->type.new_fsf_req.fsf_issued);
        }
 
        len += sprintf(out_buf + len, "\n");
index e260d19fa717f212e60d3e7bbb40d0de652a47e7..7f551d66f47f88c9005b27e90bce227bb409d5af 100644 (file)
@@ -152,11 +152,6 @@ typedef u32 scsi_lun_t;
 #define ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP  100
 #define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES      7
 
-/* Retry 5 times every 2 second, then every minute */
-#define ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES  5
-#define ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP    200
-#define ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP     6000
-
 /* timeout value for "default timer" for fsf requests */
 #define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ);
 
@@ -429,11 +424,7 @@ struct zfcp_scsi_dbf_record {
        u32 fsf_seqno;
        u64 fsf_issued;
        union {
-               struct {
-                       u64 fsf_reqid;
-                       u32 fsf_seqno;
-                       u64 fsf_issued;
-               } new_fsf_req;
+               u64 old_fsf_reqid;
                struct {
                        u8 rsp_validity;
                        u8 rsp_scsi_status;
@@ -915,8 +906,6 @@ struct zfcp_adapter {
        wwn_t                   peer_wwnn;         /* P2P peer WWNN */
        wwn_t                   peer_wwpn;         /* P2P peer WWPN */
        u32                     peer_d_id;         /* P2P peer D_ID */
-       wwn_t                   physical_wwpn;     /* WWPN of physical port */
-       u32                     physical_s_id;     /* local FC port ID */
        struct ccw_device       *ccw_device;       /* S/390 ccw device */
        u8                      fc_service_class;
        u32                     hydra_version;     /* Hydra version */
index da947e662031f6114b02121591b0f912ac41ff73..e3c4bdd29a60805ee36c8d24b54966ab71c43b01 100644 (file)
@@ -2246,15 +2246,6 @@ zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action)
 {
        int retval;
 
-       if ((atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
-                             &erp_action->adapter->status)) &&
-           (erp_action->adapter->adapter_features &
-            FSF_FEATURE_HBAAPI_MANAGEMENT)) {
-               zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);
-               atomic_set(&erp_action->adapter->erp_counter, 0);
-               return ZFCP_ERP_FAILED;
-       }
-
        retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action);
        if (retval == ZFCP_ERP_FAILED)
                return ZFCP_ERP_FAILED;
@@ -2266,13 +2257,6 @@ zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action)
        return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action);
 }
 
-/*
- * function:   
- *
- * purpose:    
- *
- * returns:
- */
 static int
 zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
 {
@@ -2350,48 +2334,40 @@ static int
 zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
 {
        int ret;
-       int retries;
-       int sleep;
-       struct zfcp_adapter *adapter = erp_action->adapter;
+       struct zfcp_adapter *adapter;
 
+       adapter = erp_action->adapter;
        atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
 
-       retries = 0;
-       do {
-               write_lock(&adapter->erp_lock);
-               zfcp_erp_action_to_running(erp_action);
-               write_unlock(&adapter->erp_lock);
-               zfcp_erp_timeout_init(erp_action);
-               ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL);
-               if (ret == -EOPNOTSUPP) {
-                       debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp");
-                       return ZFCP_ERP_SUCCEEDED;
-               } else if (ret) {
-                       debug_text_event(adapter->erp_dbf, 3, "a_xport_failed");
-                       return ZFCP_ERP_FAILED;
-               }
-               debug_text_event(adapter->erp_dbf, 6, "a_xport_ok");
+       write_lock(&adapter->erp_lock);
+       zfcp_erp_action_to_running(erp_action);
+       write_unlock(&adapter->erp_lock);
 
-               down(&adapter->erp_ready_sem);
-               if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
-                       ZFCP_LOG_INFO("error: exchange of port data "
-                                     "for adapter %s timed out\n",
-                                     zfcp_get_busid_by_adapter(adapter));
-                       break;
-               }
-               if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
-                                     &adapter->status))
-                       break;
+       zfcp_erp_timeout_init(erp_action);
+       ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL);
+       if (ret == -EOPNOTSUPP) {
+               debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp");
+               return ZFCP_ERP_SUCCEEDED;
+       } else if (ret) {
+               debug_text_event(adapter->erp_dbf, 3, "a_xport_failed");
+               return ZFCP_ERP_FAILED;
+       }
+       debug_text_event(adapter->erp_dbf, 6, "a_xport_ok");
 
-               if (retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES) {
-                       sleep = ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP;
-                       retries++;
-               } else
-                       sleep = ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP;
-               schedule_timeout(sleep);
-       } while (1);
+       ret = ZFCP_ERP_SUCCEEDED;
+       down(&adapter->erp_ready_sem);
+       if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
+               ZFCP_LOG_INFO("error: exchange port data timed out (adapter "
+                             "%s)\n", zfcp_get_busid_by_adapter(adapter));
+               ret = ZFCP_ERP_FAILED;
+       }
+       if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status)) {
+               ZFCP_LOG_INFO("error: exchange port data failed (adapter "
+                             "%s\n", zfcp_get_busid_by_adapter(adapter));
+               ret = ZFCP_ERP_FAILED;
+       }
 
-       return ZFCP_ERP_SUCCEEDED;
+       return ret;
 }
 
 /*
@@ -3439,6 +3415,8 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
                                                "(adapter %s, wwpn=0x%016Lx)\n",
                                                zfcp_get_busid_by_port(port),
                                                port->wwpn);
+                       else
+                               scsi_flush_work(adapter->scsi_host);
                }
                zfcp_port_put(port);
                break;
index c1ba7cf1b49619367973ed84b02d915c9a54b2b9..700f5402a978fc66bf6f7d734ef9c5d40061591c 100644 (file)
@@ -194,9 +194,10 @@ extern void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *);
 extern void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *);
 
 extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *,
-                                      struct scsi_cmnd *);
+                                      struct scsi_cmnd *,
+                                      struct zfcp_fsf_req *);
 extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *,
-                                     struct scsi_cmnd *,
+                                     struct scsi_cmnd *, struct zfcp_fsf_req *,
                                      struct zfcp_fsf_req *);
 extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *,
                                         struct scsi_cmnd *);
index 9f0cb3d820c06ce1753854e3946ebc4add466cfd..662ec571d73b5a891803ee745f593b74f544f0d3 100644 (file)
@@ -388,6 +388,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
        case FSF_PROT_LINK_DOWN:
                zfcp_fsf_link_down_info_eval(adapter,
                                             &prot_status_qual->link_down_info);
+               zfcp_erp_adapter_reopen(adapter, 0);
                fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
 
@@ -558,10 +559,8 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
 
        atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
 
-       if (link_down == NULL) {
-               zfcp_erp_adapter_reopen(adapter, 0);
-               return;
-       }
+       if (link_down == NULL)
+               goto out;
 
        switch (link_down->error_code) {
        case FSF_PSQ_LINK_NO_LIGHT:
@@ -643,16 +642,8 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
                                link_down->explanation_code,
                                link_down->vendor_specific_code);
 
-       switch (link_down->error_code) {
-       case FSF_PSQ_LINK_NO_LIGHT:
-       case FSF_PSQ_LINK_WRAP_PLUG:
-       case FSF_PSQ_LINK_NO_FCP:
-       case FSF_PSQ_LINK_FIRMWARE_UPDATE:
-               zfcp_erp_adapter_reopen(adapter, 0);
-               break;
-       default:
-               zfcp_erp_adapter_failed(adapter);
-       }
+ out:
+       zfcp_erp_adapter_failed(adapter);
 }
 
 /*
@@ -2304,6 +2295,35 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
        return retval;
 }
 
+/**
+ * zfcp_fsf_exchange_port_evaluate
+ * @fsf_req: fsf_req which belongs to xchg port data request
+ * @xchg_ok: specifies if xchg port data was incomplete or complete (0/1)
+ */
+static void
+zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
+{
+       struct zfcp_adapter *adapter;
+       struct fsf_qtcb *qtcb;
+       struct fsf_qtcb_bottom_port *bottom, *data;
+       struct Scsi_Host *shost;
+
+       adapter = fsf_req->adapter;
+       qtcb = fsf_req->qtcb;
+       bottom = &qtcb->bottom.port;
+       shost = adapter->scsi_host;
+
+       data = (struct fsf_qtcb_bottom_port*) fsf_req->data;
+       if (data)
+               memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port));
+
+       if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
+               fc_host_permanent_port_name(shost) = bottom->wwpn;
+       else
+               fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
+       fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
+       fc_host_supported_speeds(shost) = bottom->supported_speed;
+}
 
 /**
  * zfcp_fsf_exchange_port_data_handler - handler for exchange_port_data request
@@ -2312,38 +2332,26 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
 static void
 zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req)
 {
-       struct zfcp_adapter *adapter = fsf_req->adapter;
-       struct Scsi_Host *shost = adapter->scsi_host;
-       struct fsf_qtcb *qtcb = fsf_req->qtcb;
-       struct fsf_qtcb_bottom_port *bottom, *data;
+       struct zfcp_adapter *adapter;
+       struct fsf_qtcb *qtcb;
+
+       adapter = fsf_req->adapter;
+       qtcb = fsf_req->qtcb;
 
        if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
                return;
 
        switch (qtcb->header.fsf_status) {
         case FSF_GOOD:
+               zfcp_fsf_exchange_port_evaluate(fsf_req, 1);
                atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
-
-               bottom = &qtcb->bottom.port;
-               data = (struct fsf_qtcb_bottom_port*) fsf_req->data;
-               if (data)
-                       memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port));
-               if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
-                       fc_host_permanent_port_name(shost) = bottom->wwpn;
-               else
-                       fc_host_permanent_port_name(shost) =
-                               fc_host_port_name(shost);
-               fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
-               fc_host_supported_speeds(shost) = bottom->supported_speed;
                break;
-
        case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
+               zfcp_fsf_exchange_port_evaluate(fsf_req, 0);
                atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
-
                zfcp_fsf_link_down_info_eval(adapter,
                        &qtcb->header.fsf_status_qual.link_down_info);
                 break;
-
         default:
                debug_text_event(adapter->erp_dbf, 0, "xchg-port-ng");
                debug_event(adapter->erp_dbf, 0,
@@ -4203,11 +4211,11 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
        ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result);
 
        if (scpnt->result != 0)
-               zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt);
+               zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt, fsf_req);
        else if (scpnt->retries > 0)
-               zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt);
+               zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt, fsf_req);
        else
-               zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt);
+               zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt, fsf_req);
 
        /* cleanup pointer (need this especially for abort) */
        scpnt->host_scribble = NULL;
index e0803757c0fa054c8f23df5f43f477a501518b14..9f6b4d7a46f3342a2b853ee0d501b37e46b3b846 100644 (file)
@@ -242,7 +242,7 @@ zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result)
        if ((scpnt->device != NULL) && (scpnt->device->host != NULL))
                zfcp_scsi_dbf_event_result("fail", 4,
                        (struct zfcp_adapter*) scpnt->device->host->hostdata[0],
-                       scpnt);
+                       scpnt, NULL);
        /* return directly */
        scpnt->scsi_done(scpnt);
 }
@@ -446,7 +446,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
        old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble;
        if (!old_fsf_req) {
                write_unlock_irqrestore(&adapter->abort_lock, flags);
-               zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, new_fsf_req);
+               zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, NULL);
                retval = SUCCESS;
                goto out;
        }
@@ -460,6 +460,8 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
                                                 adapter, unit, 0);
        if (!new_fsf_req) {
                ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n");
+               zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL,
+                                         old_fsf_req);
                retval = FAILED;
                goto out;
        }
@@ -470,13 +472,16 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
 
        /* status should be valid since signals were not permitted */
        if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) {
-               zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req);
+               zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req,
+                                         NULL);
                retval = SUCCESS;
        } else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) {
-               zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req);
+               zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req,
+                                         NULL);
                retval = SUCCESS;
        } else {
-               zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req);
+               zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req,
+                                         NULL);
                retval = FAILED;
        }
        zfcp_fsf_req_free(new_fsf_req);
index dfc07370f412acf1231303ac9ce5e3705a53d1d4..b29ac25e07f3a841b6cd7d45f11e78246faed459 100644 (file)
@@ -55,8 +55,6 @@ ZFCP_DEFINE_ADAPTER_ATTR(status, "0x%08x\n", atomic_read(&adapter->status));
 ZFCP_DEFINE_ADAPTER_ATTR(peer_wwnn, "0x%016llx\n", adapter->peer_wwnn);
 ZFCP_DEFINE_ADAPTER_ATTR(peer_wwpn, "0x%016llx\n", adapter->peer_wwpn);
 ZFCP_DEFINE_ADAPTER_ATTR(peer_d_id, "0x%06x\n", adapter->peer_d_id);
-ZFCP_DEFINE_ADAPTER_ATTR(physical_wwpn, "0x%016llx\n", adapter->physical_wwpn);
-ZFCP_DEFINE_ADAPTER_ATTR(physical_s_id, "0x%06x\n", adapter->physical_s_id);
 ZFCP_DEFINE_ADAPTER_ATTR(card_version, "0x%04x\n", adapter->hydra_version);
 ZFCP_DEFINE_ADAPTER_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version);
 ZFCP_DEFINE_ADAPTER_ATTR(hardware_version, "0x%08x\n",
@@ -241,8 +239,6 @@ static struct attribute *zfcp_adapter_attrs[] = {
        &dev_attr_peer_wwnn.attr,
        &dev_attr_peer_wwpn.attr,
        &dev_attr_peer_d_id.attr,
-       &dev_attr_physical_wwpn.attr,
-       &dev_attr_physical_s_id.attr,
        &dev_attr_card_version.attr,
        &dev_attr_lic_version.attr,
        &dev_attr_status.attr,
index 31c4975422729d46a47802e975c58c0cc8d46f6a..d9152d02088c81bb4c498360d5ed7232f10718dd 100644 (file)
@@ -61,6 +61,7 @@
                  Add support for embedded firmware error strings.
    2.26.02.003 - Correctly handle single sgl's with use_sg=1.
    2.26.02.004 - Add support for 9550SX controllers.
+   2.26.02.005 - Fix use_sg == 0 mapping on systems with 4GB or higher.
 */
 
 #include <linux/module.h>
@@ -84,7 +85,7 @@
 #include "3w-9xxx.h"
 
 /* Globals */
-#define TW_DRIVER_VERSION "2.26.02.004"
+#define TW_DRIVER_VERSION "2.26.02.005"
 static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
 static unsigned int twa_device_extension_count;
 static int twa_major = -1;
@@ -1408,7 +1409,7 @@ static dma_addr_t twa_map_scsi_single_data(TW_Device_Extension *tw_dev, int requ
        dma_addr_t mapping;
        struct scsi_cmnd *cmd = tw_dev->srb[request_id];
        struct pci_dev *pdev = tw_dev->tw_pci_dev;
-       int retval = 0;
+       dma_addr_t retval = 0;
 
        if (cmd->request_bufflen == 0) {
                retval = 0;
@@ -1798,7 +1799,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
        int i, sg_count;
        struct scsi_cmnd *srb = NULL;
        struct scatterlist *sglist = NULL;
-       u32 buffaddr = 0x0;
+       dma_addr_t buffaddr = 0x0;
        int retval = 1;
 
        if (tw_dev->srb[request_id]) {
index 7139659dd952e4cf36eb971c8491a5dcd4b42136..a16f8ded8f1dd683f266683757dd21ed0cf7fd43 100644 (file)
@@ -173,10 +173,10 @@ int aac_get_config_status(struct aac_dev *dev)
        int status = 0;
        struct fib * fibptr;
 
-       if (!(fibptr = fib_alloc(dev)))
+       if (!(fibptr = aac_fib_alloc(dev)))
                return -ENOMEM;
 
-       fib_init(fibptr);
+       aac_fib_init(fibptr);
        {
                struct aac_get_config_status *dinfo;
                dinfo = (struct aac_get_config_status *) fib_data(fibptr);
@@ -186,7 +186,7 @@ int aac_get_config_status(struct aac_dev *dev)
                dinfo->count = cpu_to_le32(sizeof(((struct aac_get_config_status_resp *)NULL)->data));
        }
 
-       status = fib_send(ContainerCommand,
+       status = aac_fib_send(ContainerCommand,
                            fibptr,
                            sizeof (struct aac_get_config_status),
                            FsaNormal,
@@ -209,30 +209,30 @@ int aac_get_config_status(struct aac_dev *dev)
                        status = -EINVAL;
                }
        }
-       fib_complete(fibptr);
+       aac_fib_complete(fibptr);
        /* Send a CT_COMMIT_CONFIG to enable discovery of devices */
        if (status >= 0) {
                if (commit == 1) {
                        struct aac_commit_config * dinfo;
-                       fib_init(fibptr);
+                       aac_fib_init(fibptr);
                        dinfo = (struct aac_commit_config *) fib_data(fibptr);
        
                        dinfo->command = cpu_to_le32(VM_ContainerConfig);
                        dinfo->type = cpu_to_le32(CT_COMMIT_CONFIG);
        
-                       status = fib_send(ContainerCommand,
+                       status = aac_fib_send(ContainerCommand,
                                    fibptr,
                                    sizeof (struct aac_commit_config),
                                    FsaNormal,
                                    1, 1,
                                    NULL, NULL);
-                       fib_complete(fibptr);
+                       aac_fib_complete(fibptr);
                } else if (commit == 0) {
                        printk(KERN_WARNING
                          "aac_get_config_status: Foreign device configurations are being ignored\n");
                }
        }
-       fib_free(fibptr);
+       aac_fib_free(fibptr);
        return status;
 }
 
@@ -255,15 +255,15 @@ int aac_get_containers(struct aac_dev *dev)
 
        instance = dev->scsi_host_ptr->unique_id;
 
-       if (!(fibptr = fib_alloc(dev)))
+       if (!(fibptr = aac_fib_alloc(dev)))
                return -ENOMEM;
 
-       fib_init(fibptr);
+       aac_fib_init(fibptr);
        dinfo = (struct aac_get_container_count *) fib_data(fibptr);
        dinfo->command = cpu_to_le32(VM_ContainerConfig);
        dinfo->type = cpu_to_le32(CT_GET_CONTAINER_COUNT);
 
-       status = fib_send(ContainerCommand,
+       status = aac_fib_send(ContainerCommand,
                    fibptr,
                    sizeof (struct aac_get_container_count),
                    FsaNormal,
@@ -272,7 +272,7 @@ int aac_get_containers(struct aac_dev *dev)
        if (status >= 0) {
                dresp = (struct aac_get_container_count_resp *)fib_data(fibptr);
                maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries);
-               fib_complete(fibptr);
+               aac_fib_complete(fibptr);
        }
 
        if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
@@ -280,7 +280,7 @@ int aac_get_containers(struct aac_dev *dev)
        fsa_dev_ptr = (struct fsa_dev_info *) kmalloc(
          sizeof(*fsa_dev_ptr) * maximum_num_containers, GFP_KERNEL);
        if (!fsa_dev_ptr) {
-               fib_free(fibptr);
+               aac_fib_free(fibptr);
                return -ENOMEM;
        }
        memset(fsa_dev_ptr, 0, sizeof(*fsa_dev_ptr) * maximum_num_containers);
@@ -294,14 +294,14 @@ int aac_get_containers(struct aac_dev *dev)
 
                fsa_dev_ptr[index].devname[0] = '\0';
 
-               fib_init(fibptr);
+               aac_fib_init(fibptr);
                dinfo = (struct aac_query_mount *) fib_data(fibptr);
 
                dinfo->command = cpu_to_le32(VM_NameServe);
                dinfo->count = cpu_to_le32(index);
                dinfo->type = cpu_to_le32(FT_FILESYS);
 
-               status = fib_send(ContainerCommand,
+               status = aac_fib_send(ContainerCommand,
                                    fibptr,
                                    sizeof (struct aac_query_mount),
                                    FsaNormal,
@@ -319,7 +319,7 @@ int aac_get_containers(struct aac_dev *dev)
                        dinfo->count = cpu_to_le32(index);
                        dinfo->type = cpu_to_le32(FT_FILESYS);
 
-                       if (fib_send(ContainerCommand,
+                       if (aac_fib_send(ContainerCommand,
                                    fibptr,
                                    sizeof(struct aac_query_mount),
                                    FsaNormal,
@@ -347,7 +347,7 @@ int aac_get_containers(struct aac_dev *dev)
                        if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY)
                                    fsa_dev_ptr[index].ro = 1;
                }
-               fib_complete(fibptr);
+               aac_fib_complete(fibptr);
                /*
                 *      If there are no more containers, then stop asking.
                 */
@@ -355,7 +355,7 @@ int aac_get_containers(struct aac_dev *dev)
                        break;
                }
        }
-       fib_free(fibptr);
+       aac_fib_free(fibptr);
        return status;
 }
 
@@ -413,8 +413,8 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
 
        scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
 
-       fib_complete(fibptr);
-       fib_free(fibptr);
+       aac_fib_complete(fibptr);
+       aac_fib_free(fibptr);
        scsicmd->scsi_done(scsicmd);
 }
 
@@ -430,10 +430,10 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid)
 
        dev = (struct aac_dev *)scsicmd->device->host->hostdata;
 
-       if (!(cmd_fibcontext = fib_alloc(dev)))
+       if (!(cmd_fibcontext = aac_fib_alloc(dev)))
                return -ENOMEM;
 
-       fib_init(cmd_fibcontext);
+       aac_fib_init(cmd_fibcontext);
        dinfo = (struct aac_get_name *) fib_data(cmd_fibcontext);
 
        dinfo->command = cpu_to_le32(VM_ContainerConfig);
@@ -441,7 +441,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid)
        dinfo->cid = cpu_to_le32(cid);
        dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data));
 
-       status = fib_send(ContainerCommand, 
+       status = aac_fib_send(ContainerCommand,
                  cmd_fibcontext, 
                  sizeof (struct aac_get_name),
                  FsaNormal, 
@@ -455,14 +455,14 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid)
        if (status == -EINPROGRESS) 
                return 0;
                
-       printk(KERN_WARNING "aac_get_container_name: fib_send failed with status: %d.\n", status);
-       fib_complete(cmd_fibcontext);
-       fib_free(cmd_fibcontext);
+       printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status);
+       aac_fib_complete(cmd_fibcontext);
+       aac_fib_free(cmd_fibcontext);
        return -1;
 }
 
 /**
- *     probe_container         -       query a logical volume
+ *     aac_probe_container             -       query a logical volume
  *     @dev: device to query
  *     @cid: container identifier
  *
@@ -470,7 +470,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid)
  *     is updated in the struct fsa_dev_info structure rather than returned.
  */
  
-int probe_container(struct aac_dev *dev, int cid)
+int aac_probe_container(struct aac_dev *dev, int cid)
 {
        struct fsa_dev_info *fsa_dev_ptr;
        int status;
@@ -482,10 +482,10 @@ int probe_container(struct aac_dev *dev, int cid)
        fsa_dev_ptr = dev->fsa_dev;
        instance = dev->scsi_host_ptr->unique_id;
 
-       if (!(fibptr = fib_alloc(dev)))
+       if (!(fibptr = aac_fib_alloc(dev)))
                return -ENOMEM;
 
-       fib_init(fibptr);
+       aac_fib_init(fibptr);
 
        dinfo = (struct aac_query_mount *)fib_data(fibptr);
 
@@ -493,14 +493,14 @@ int probe_container(struct aac_dev *dev, int cid)
        dinfo->count = cpu_to_le32(cid);
        dinfo->type = cpu_to_le32(FT_FILESYS);
 
-       status = fib_send(ContainerCommand,
+       status = aac_fib_send(ContainerCommand,
                            fibptr,
                            sizeof(struct aac_query_mount),
                            FsaNormal,
                            1, 1,
                            NULL, NULL);
        if (status < 0) {
-               printk(KERN_WARNING "aacraid: probe_container query failed.\n");
+               printk(KERN_WARNING "aacraid: aac_probe_container query failed.\n");
                goto error;
        }
 
@@ -512,7 +512,7 @@ int probe_container(struct aac_dev *dev, int cid)
                dinfo->count = cpu_to_le32(cid);
                dinfo->type = cpu_to_le32(FT_FILESYS);
 
-               if (fib_send(ContainerCommand,
+               if (aac_fib_send(ContainerCommand,
                            fibptr,
                            sizeof(struct aac_query_mount),
                            FsaNormal,
@@ -535,8 +535,8 @@ int probe_container(struct aac_dev *dev, int cid)
        }
 
 error:
-       fib_complete(fibptr);
-       fib_free(fibptr);
+       aac_fib_complete(fibptr);
+       aac_fib_free(fibptr);
 
        return status;
 }
@@ -700,14 +700,14 @@ int aac_get_adapter_info(struct aac_dev* dev)
        struct aac_bus_info *command;
        struct aac_bus_info_response *bus_info;
 
-       if (!(fibptr = fib_alloc(dev)))
+       if (!(fibptr = aac_fib_alloc(dev)))
                return -ENOMEM;
 
-       fib_init(fibptr);
+       aac_fib_init(fibptr);
        info = (struct aac_adapter_info *) fib_data(fibptr);
        memset(info,0,sizeof(*info));
 
-       rcode = fib_send(RequestAdapterInfo,
+       rcode = aac_fib_send(RequestAdapterInfo,
                         fibptr, 
                         sizeof(*info),
                         FsaNormal, 
@@ -716,8 +716,8 @@ int aac_get_adapter_info(struct aac_dev* dev)
                         NULL);
 
        if (rcode < 0) {
-               fib_complete(fibptr);
-               fib_free(fibptr);
+               aac_fib_complete(fibptr);
+               aac_fib_free(fibptr);
                return rcode;
        }
        memcpy(&dev->adapter_info, info, sizeof(*info));
@@ -725,13 +725,13 @@ int aac_get_adapter_info(struct aac_dev* dev)
        if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) {
                struct aac_supplement_adapter_info * info;
 
-               fib_init(fibptr);
+               aac_fib_init(fibptr);
 
                info = (struct aac_supplement_adapter_info *) fib_data(fibptr);
 
                memset(info,0,sizeof(*info));
 
-               rcode = fib_send(RequestSupplementAdapterInfo,
+               rcode = aac_fib_send(RequestSupplementAdapterInfo,
                                 fibptr,
                                 sizeof(*info),
                                 FsaNormal,
@@ -748,7 +748,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
         * GetBusInfo 
         */
 
-       fib_init(fibptr);
+       aac_fib_init(fibptr);
 
        bus_info = (struct aac_bus_info_response *) fib_data(fibptr);
 
@@ -761,7 +761,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
        command->MethodId = cpu_to_le32(1);
        command->CtlCmd = cpu_to_le32(GetBusInfo);
 
-       rcode = fib_send(ContainerCommand,
+       rcode = aac_fib_send(ContainerCommand,
                         fibptr,
                         sizeof (*bus_info),
                         FsaNormal,
@@ -891,8 +891,8 @@ int aac_get_adapter_info(struct aac_dev* dev)
                }
        }
 
-       fib_complete(fibptr);
-       fib_free(fibptr);
+       aac_fib_complete(fibptr);
+       aac_fib_free(fibptr);
 
        return rcode;
 }
@@ -976,8 +976,8 @@ static void io_callback(void *context, struct fib * fibptr)
                    ? sizeof(scsicmd->sense_buffer)
                    : sizeof(dev->fsa_dev[cid].sense_data));
        }
-       fib_complete(fibptr);
-       fib_free(fibptr);
+       aac_fib_complete(fibptr);
+       aac_fib_free(fibptr);
 
        scsicmd->scsi_done(scsicmd);
 }
@@ -1062,11 +1062,11 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
        /*
         *      Alocate and initialize a Fib
         */
-       if (!(cmd_fibcontext = fib_alloc(dev))) {
+       if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
                return -1;
        }
 
-       fib_init(cmd_fibcontext);
+       aac_fib_init(cmd_fibcontext);
 
        if (dev->raw_io_interface) {
                struct aac_raw_io *readcmd;
@@ -1086,7 +1086,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
                /*
                 *      Now send the Fib to the adapter
                 */
-               status = fib_send(ContainerRawIo,
+               status = aac_fib_send(ContainerRawIo,
                          cmd_fibcontext, 
                          fibsize, 
                          FsaNormal, 
@@ -1112,7 +1112,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
                /*
                 *      Now send the Fib to the adapter
                 */
-               status = fib_send(ContainerCommand64, 
+               status = aac_fib_send(ContainerCommand64,
                          cmd_fibcontext, 
                          fibsize, 
                          FsaNormal, 
@@ -1136,7 +1136,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
                /*
                 *      Now send the Fib to the adapter
                 */
-               status = fib_send(ContainerCommand, 
+               status = aac_fib_send(ContainerCommand,
                          cmd_fibcontext, 
                          fibsize, 
                          FsaNormal, 
@@ -1153,14 +1153,14 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
        if (status == -EINPROGRESS) 
                return 0;
                
-       printk(KERN_WARNING "aac_read: fib_send failed with status: %d.\n", status);
+       printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status);
        /*
         *      For some reason, the Fib didn't queue, return QUEUE_FULL
         */
        scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL;
        scsicmd->scsi_done(scsicmd);
-       fib_complete(cmd_fibcontext);
-       fib_free(cmd_fibcontext);
+       aac_fib_complete(cmd_fibcontext);
+       aac_fib_free(cmd_fibcontext);
        return 0;
 }
 
@@ -1228,12 +1228,12 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
        /*
         *      Allocate and initialize a Fib then setup a BlockWrite command
         */
-       if (!(cmd_fibcontext = fib_alloc(dev))) {
+       if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
                scsicmd->result = DID_ERROR << 16;
                scsicmd->scsi_done(scsicmd);
                return 0;
        }
-       fib_init(cmd_fibcontext);
+       aac_fib_init(cmd_fibcontext);
 
        if (dev->raw_io_interface) {
                struct aac_raw_io *writecmd;
@@ -1253,7 +1253,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
                /*
                 *      Now send the Fib to the adapter
                 */
-               status = fib_send(ContainerRawIo,
+               status = aac_fib_send(ContainerRawIo,
                          cmd_fibcontext, 
                          fibsize, 
                          FsaNormal, 
@@ -1279,7 +1279,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
                /*
                 *      Now send the Fib to the adapter
                 */
-               status = fib_send(ContainerCommand64, 
+               status = aac_fib_send(ContainerCommand64,
                          cmd_fibcontext, 
                          fibsize, 
                          FsaNormal, 
@@ -1305,7 +1305,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
                /*
                 *      Now send the Fib to the adapter
                 */
-               status = fib_send(ContainerCommand, 
+               status = aac_fib_send(ContainerCommand,
                          cmd_fibcontext, 
                          fibsize, 
                          FsaNormal, 
@@ -1322,15 +1322,15 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
                return 0;
        }
 
-       printk(KERN_WARNING "aac_write: fib_send failed with status: %d\n", status);
+       printk(KERN_WARNING "aac_write: aac_fib_send failed with status: %d\n", status);
        /*
         *      For some reason, the Fib didn't queue, return QUEUE_FULL
         */
        scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL;
        scsicmd->scsi_done(scsicmd);
 
-       fib_complete(cmd_fibcontext);
-       fib_free(cmd_fibcontext);
+       aac_fib_complete(cmd_fibcontext);
+       aac_fib_free(cmd_fibcontext);
        return 0;
 }
 
@@ -1369,8 +1369,8 @@ static void synchronize_callback(void *context, struct fib *fibptr)
                          sizeof(cmd->sense_buffer)));
        }
 
-       fib_complete(fibptr);
-       fib_free(fibptr);
+       aac_fib_complete(fibptr);
+       aac_fib_free(fibptr);
        cmd->scsi_done(cmd);
 }
 
@@ -1407,10 +1407,10 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
         *      Allocate and initialize a Fib
         */
        if (!(cmd_fibcontext = 
-           fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) 
+           aac_fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata)))
                return SCSI_MLQUEUE_HOST_BUSY;
 
-       fib_init(cmd_fibcontext);
+       aac_fib_init(cmd_fibcontext);
 
        synchronizecmd = fib_data(cmd_fibcontext);
        synchronizecmd->command = cpu_to_le32(VM_ContainerConfig);
@@ -1422,7 +1422,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
        /*
         *      Now send the Fib to the adapter
         */
-       status = fib_send(ContainerCommand,
+       status = aac_fib_send(ContainerCommand,
                  cmd_fibcontext,
                  sizeof(struct aac_synchronize),
                  FsaNormal,
@@ -1437,9 +1437,9 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
                return 0;
 
        printk(KERN_WARNING 
-               "aac_synchronize: fib_send failed with status: %d.\n", status);
-       fib_complete(cmd_fibcontext);
-       fib_free(cmd_fibcontext);
+               "aac_synchronize: aac_fib_send failed with status: %d.\n", status);
+       aac_fib_complete(cmd_fibcontext);
+       aac_fib_free(cmd_fibcontext);
        return SCSI_MLQUEUE_HOST_BUSY;
 }
 
@@ -1465,7 +1465,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
         *      itself.
         */
        if (scmd_id(scsicmd) != host->this_id) {
-               if ((scsicmd->device->channel == 0) ){
+               if ((scsicmd->device->channel == CONTAINER_CHANNEL)) {
                        if( (scsicmd->device->id >= dev->maximum_num_containers) || (scsicmd->device->lun != 0)){ 
                                scsicmd->result = DID_NO_CONNECT << 16;
                                scsicmd->scsi_done(scsicmd);
@@ -1488,7 +1488,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
                                case READ_CAPACITY:
                                case TEST_UNIT_READY:
                                        spin_unlock_irq(host->host_lock);
-                                       probe_container(dev, cid);
+                                       aac_probe_container(dev, cid);
                                        if ((fsa_dev_ptr[cid].valid & 1) == 0)
                                                fsa_dev_ptr[cid].valid = 0;
                                        spin_lock_irq(host->host_lock);
@@ -1935,33 +1935,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
        case SRB_STATUS_ERROR_RECOVERY:
        case SRB_STATUS_PENDING:
        case SRB_STATUS_SUCCESS:
-               if(scsicmd->cmnd[0] == INQUIRY ){
-                       u8 b;
-                       u8 b1;
-                       /* We can't expose disk devices because we can't tell whether they
-                        * are the raw container drives or stand alone drives.  If they have
-                        * the removable bit set then we should expose them though.
-                        */
-                       b = (*(u8*)scsicmd->buffer)&0x1f;
-                       b1 = ((u8*)scsicmd->buffer)[1];
-                       if( b==TYPE_TAPE || b==TYPE_WORM || b==TYPE_ROM || b==TYPE_MOD|| b==TYPE_MEDIUM_CHANGER 
-                                       || (b==TYPE_DISK && (b1&0x80)) ){
-                               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
-                       /*
-                        * We will allow disk devices if in RAID/SCSI mode and
-                        * the channel is 2
-                        */
-                       } else if ((dev->raid_scsi_mode) &&
-                                       (scmd_channel(scsicmd) == 2)) {
-                               scsicmd->result = DID_OK << 16 | 
-                                               COMMAND_COMPLETE << 8;
-                       } else {
-                               scsicmd->result = DID_NO_CONNECT << 16 | 
-                                               COMMAND_COMPLETE << 8;
-                       }
-               } else {
-                       scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
-               }
+               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
                break;
        case SRB_STATUS_DATA_OVERRUN:
                switch(scsicmd->cmnd[0]){
@@ -1981,28 +1955,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
                        scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;
                        break;
                case INQUIRY: {
-                       u8 b;
-                       u8 b1;
-                       /* We can't expose disk devices because we can't tell whether they
-                       * are the raw container drives or stand alone drives
-                       */
-                       b = (*(u8*)scsicmd->buffer)&0x0f;
-                       b1 = ((u8*)scsicmd->buffer)[1];
-                       if( b==TYPE_TAPE || b==TYPE_WORM || b==TYPE_ROM || b==TYPE_MOD|| b==TYPE_MEDIUM_CHANGER
-                                       || (b==TYPE_DISK && (b1&0x80)) ){
-                               scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
-                       /*
-                        * We will allow disk devices if in RAID/SCSI mode and
-                        * the channel is 2
-                        */
-                       } else if ((dev->raid_scsi_mode) &&
-                                       (scmd_channel(scsicmd) == 2)) {
-                               scsicmd->result = DID_OK << 16 | 
-                                               COMMAND_COMPLETE << 8;
-                       } else {
-                               scsicmd->result = DID_NO_CONNECT << 16 | 
-                                               COMMAND_COMPLETE << 8;
-                       }
+                       scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
                        break;
                }
                default:
@@ -2089,8 +2042,8 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
         */
        scsicmd->result |= le32_to_cpu(srbreply->scsi_status);
 
-       fib_complete(fibptr);
-       fib_free(fibptr);
+       aac_fib_complete(fibptr);
+       aac_fib_free(fibptr);
        scsicmd->scsi_done(scsicmd);
 }
 
@@ -2142,10 +2095,10 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
        /*
         *      Allocate and initialize a Fib then setup a BlockWrite command
         */
-       if (!(cmd_fibcontext = fib_alloc(dev))) {
+       if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
                return -1;
        }
-       fib_init(cmd_fibcontext);
+       aac_fib_init(cmd_fibcontext);
 
        srbcmd = (struct aac_srb*) fib_data(cmd_fibcontext);
        srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);
@@ -2179,7 +2132,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
                /*
                 *      Now send the Fib to the adapter
                 */
-               status = fib_send(ScsiPortCommand64, cmd_fibcontext, 
+               status = aac_fib_send(ScsiPortCommand64, cmd_fibcontext,
                                fibsize, FsaNormal, 0, 1,
                                  (fib_callback) aac_srb_callback, 
                                  (void *) scsicmd);
@@ -2201,7 +2154,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
                /*
                 *      Now send the Fib to the adapter
                 */
-               status = fib_send(ScsiPortCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1,
+               status = aac_fib_send(ScsiPortCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1,
                                  (fib_callback) aac_srb_callback, (void *) scsicmd);
        }
        /*
@@ -2211,9 +2164,9 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
                return 0;
        }
 
-       printk(KERN_WARNING "aac_srb: fib_send failed with status: %d\n", status);
-       fib_complete(cmd_fibcontext);
-       fib_free(cmd_fibcontext);
+       printk(KERN_WARNING "aac_srb: aac_fib_send failed with status: %d\n", status);
+       aac_fib_complete(cmd_fibcontext);
+       aac_fib_free(cmd_fibcontext);
 
        return -1;
 }
index 66dbb6d2c506afe1ce904b66db2aa76f3b93c72e..2d430b7e8cf406953ff2c7f7ff1dcba81d433624 100644 (file)
@@ -1774,16 +1774,16 @@ static inline u32 cap_to_cyls(sector_t capacity, u32 divisor)
 struct scsi_cmnd;
 
 const char *aac_driverinfo(struct Scsi_Host *);
-struct fib *fib_alloc(struct aac_dev *dev);
-int fib_setup(struct aac_dev *dev);
-void fib_map_free(struct aac_dev *dev);
-void fib_free(struct fib * context);
-void fib_init(struct fib * context);
+struct fib *aac_fib_alloc(struct aac_dev *dev);
+int aac_fib_setup(struct aac_dev *dev);
+void aac_fib_map_free(struct aac_dev *dev);
+void aac_fib_free(struct fib * context);
+void aac_fib_init(struct fib * context);
 void aac_printf(struct aac_dev *dev, u32 val);
-int fib_send(u16 command, struct fib * context, unsigned long size, int priority, int wait, int reply, fib_callback callback, void *ctxt);
+int aac_fib_send(u16 command, struct fib * context, unsigned long size, int priority, int wait, int reply, fib_callback callback, void *ctxt);
 int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry);
 void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum);
-int fib_complete(struct fib * context);
+int aac_fib_complete(struct fib * context);
 #define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data)
 struct aac_dev *aac_init_adapter(struct aac_dev *dev);
 int aac_get_config_status(struct aac_dev *dev);
@@ -1799,11 +1799,11 @@ unsigned int aac_command_normal(struct aac_queue * q);
 unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index);
 int aac_command_thread(struct aac_dev * dev);
 int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx);
-int fib_adapter_complete(struct fib * fibptr, unsigned short size);
+int aac_fib_adapter_complete(struct fib * fibptr, unsigned short size);
 struct aac_driver_ident* aac_get_driver_ident(int devtype);
 int aac_get_adapter_info(struct aac_dev* dev);
 int aac_send_shutdown(struct aac_dev *dev);
-int probe_container(struct aac_dev *dev, int cid);
+int aac_probe_container(struct aac_dev *dev, int cid);
 extern int numacb;
 extern int acbsize;
 extern char aac_driver_version[];
index 4fe79cd7c957664bf8a686b18d46fe490b131d7a..47fefca72695d02f3959b7a4e5c846a9c611c9bf 100644 (file)
@@ -63,7 +63,7 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
        unsigned size;
        int retval;
 
-       fibptr = fib_alloc(dev);
+       fibptr = aac_fib_alloc(dev);
        if(fibptr == NULL) {
                return -ENOMEM;
        }
@@ -73,7 +73,7 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
         *      First copy in the header so that we can check the size field.
         */
        if (copy_from_user((void *)kfib, arg, sizeof(struct aac_fibhdr))) {
-               fib_free(fibptr);
+               aac_fib_free(fibptr);
                return -EFAULT;
        }
        /*
@@ -110,13 +110,13 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
                 */
                kfib->header.XferState = 0;
        } else {
-               retval = fib_send(le16_to_cpu(kfib->header.Command), fibptr,
+               retval = aac_fib_send(le16_to_cpu(kfib->header.Command), fibptr,
                                le16_to_cpu(kfib->header.Size) , FsaNormal,
                                1, 1, NULL, NULL);
                if (retval) {
                        goto cleanup;
                }
-               if (fib_complete(fibptr) != 0) {
+               if (aac_fib_complete(fibptr) != 0) {
                        retval = -EINVAL;
                        goto cleanup;
                }
@@ -138,7 +138,7 @@ cleanup:
                fibptr->hw_fib_pa = hw_fib_pa;
                fibptr->hw_fib = hw_fib;
        }
-       fib_free(fibptr);
+       aac_fib_free(fibptr);
        return retval;
 }
 
@@ -464,10 +464,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
        /*
         *      Allocate and initialize a Fib then setup a BlockWrite command
         */
-       if (!(srbfib = fib_alloc(dev))) {
+       if (!(srbfib = aac_fib_alloc(dev))) {
                return -ENOMEM;
        }
-       fib_init(srbfib);
+       aac_fib_init(srbfib);
 
        srbcmd = (struct aac_srb*) fib_data(srbfib);
 
@@ -601,7 +601,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 
                srbcmd->count = cpu_to_le32(byte_count);
                psg->count = cpu_to_le32(sg_indx+1);
-               status = fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL);
+               status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL);
        } else {
                struct user_sgmap* upsg = &user_srbcmd->sg;
                struct sgmap* psg = &srbcmd->sg;
@@ -649,7 +649,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
                }
                srbcmd->count = cpu_to_le32(byte_count);
                psg->count = cpu_to_le32(sg_indx+1);
-               status = fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
+               status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
        }
 
        if (status != 0){
@@ -684,8 +684,8 @@ cleanup:
        for(i=0; i <= sg_indx; i++){
                kfree(sg_list[i]);
        }
-       fib_complete(srbfib);
-       fib_free(srbfib);
+       aac_fib_complete(srbfib);
+       aac_fib_free(srbfib);
 
        return rcode;
 }
index 82821d331c07322211d4a9f72f4f21862deb9b53..1628d094943df1c85f425f0392730b0318549076 100644 (file)
@@ -185,17 +185,17 @@ int aac_send_shutdown(struct aac_dev * dev)
        struct aac_close *cmd;
        int status;
 
-       fibctx = fib_alloc(dev);
+       fibctx = aac_fib_alloc(dev);
        if (!fibctx)
                return -ENOMEM;
-       fib_init(fibctx);
+       aac_fib_init(fibctx);
 
        cmd = (struct aac_close *) fib_data(fibctx);
 
        cmd->command = cpu_to_le32(VM_CloseAll);
        cmd->cid = cpu_to_le32(0xffffffff);
 
-       status = fib_send(ContainerCommand,
+       status = aac_fib_send(ContainerCommand,
                          fibctx,
                          sizeof(struct aac_close),
                          FsaNormal,
@@ -203,8 +203,8 @@ int aac_send_shutdown(struct aac_dev * dev)
                          NULL, NULL);
 
        if (status == 0)
-               fib_complete(fibctx);
-       fib_free(fibctx);
+               aac_fib_complete(fibctx);
+       aac_fib_free(fibctx);
        return status;
 }
 
@@ -427,7 +427,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
        /*
         *      Initialize the list of fibs
         */
-       if(fib_setup(dev)<0){
+       if (aac_fib_setup(dev) < 0) {
                kfree(dev->queues);
                return NULL;
        }
index 014cc8d54a9fc26861598a3f9182f763476dd5c5..609fd19b18449d69fdcfe403e2035a9f54e780e4 100644 (file)
@@ -67,27 +67,27 @@ static int fib_map_alloc(struct aac_dev *dev)
 }
 
 /**
- *     fib_map_free            -       free the fib objects
+ *     aac_fib_map_free                -       free the fib objects
  *     @dev: Adapter to free
  *
  *     Free the PCI mappings and the memory allocated for FIB blocks
  *     on this adapter.
  */
 
-void fib_map_free(struct aac_dev *dev)
+void aac_fib_map_free(struct aac_dev *dev)
 {
        pci_free_consistent(dev->pdev, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), dev->hw_fib_va, dev->hw_fib_pa);
 }
 
 /**
- *     fib_setup       -       setup the fibs
+ *     aac_fib_setup   -       setup the fibs
  *     @dev: Adapter to set up
  *
  *     Allocate the PCI space for the fibs, map it and then intialise the
  *     fib area, the unmapped fib data and also the free list
  */
 
-int fib_setup(struct aac_dev * dev)
+int aac_fib_setup(struct aac_dev * dev)
 {
        struct fib *fibptr;
        struct hw_fib *hw_fib_va;
@@ -134,14 +134,14 @@ int fib_setup(struct aac_dev * dev)
 }
 
 /**
- *     fib_alloc       -       allocate a fib
+ *     aac_fib_alloc   -       allocate a fib
  *     @dev: Adapter to allocate the fib for
  *
  *     Allocate a fib from the adapter fib pool. If the pool is empty we
  *     return NULL.
  */
  
-struct fib * fib_alloc(struct aac_dev *dev)
+struct fib *aac_fib_alloc(struct aac_dev *dev)
 {
        struct fib * fibptr;
        unsigned long flags;
@@ -170,14 +170,14 @@ struct fib * fib_alloc(struct aac_dev *dev)
 }
 
 /**
- *     fib_free        -       free a fib
+ *     aac_fib_free    -       free a fib
  *     @fibptr: fib to free up
  *
  *     Frees up a fib and places it on the appropriate queue
  *     (either free or timed out)
  */
  
-void fib_free(struct fib * fibptr)
+void aac_fib_free(struct fib *fibptr)
 {
        unsigned long flags;
 
@@ -188,7 +188,7 @@ void fib_free(struct fib * fibptr)
                fibptr->dev->timeout_fib = fibptr;
        } else {
                if (fibptr->hw_fib->header.XferState != 0) {
-                       printk(KERN_WARNING "fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", 
+                       printk(KERN_WARNING "aac_fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n",
                                 (void*)fibptr, 
                                 le32_to_cpu(fibptr->hw_fib->header.XferState));
                }
@@ -199,13 +199,13 @@ void fib_free(struct fib * fibptr)
 }
 
 /**
- *     fib_init        -       initialise a fib
+ *     aac_fib_init    -       initialise a fib
  *     @fibptr: The fib to initialize
  *     
  *     Set up the generic fib fields ready for use
  */
  
-void fib_init(struct fib *fibptr)
+void aac_fib_init(struct fib *fibptr)
 {
        struct hw_fib *hw_fib = fibptr->hw_fib;
 
@@ -362,7 +362,7 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f
  */
 
 /**
- *     fib_send        -       send a fib to the adapter
+ *     aac_fib_send    -       send a fib to the adapter
  *     @command: Command to send
  *     @fibptr: The fib
  *     @size: Size of fib data area
@@ -378,7 +378,9 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f
  *     response FIB is received from the adapter.
  */
  
-int fib_send(u16 command, struct fib * fibptr, unsigned long size,  int priority, int wait, int reply, fib_callback callback, void * callback_data)
+int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
+               int priority, int wait, int reply, fib_callback callback,
+               void *callback_data)
 {
        struct aac_dev * dev = fibptr->dev;
        struct hw_fib * hw_fib = fibptr->hw_fib;
@@ -493,7 +495,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size,  int priority
                q->numpending++;
                *(q->headers.producer) = cpu_to_le32(index + 1);
                spin_unlock_irqrestore(q->lock, qflags);
-               dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
+               dprintk((KERN_DEBUG "aac_fib_send: inserting a queue entry at index %d.\n",index));
                if (!(nointr & aac_config.irq_mod))
                        aac_adapter_notify(dev, AdapNormCmdQueue);
        }
@@ -520,7 +522,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size,  int priority
                                        list_del(&fibptr->queue);
                                        spin_unlock_irqrestore(q->lock, qflags);
                                        if (wait == -1) {
-                                               printk(KERN_ERR "aacraid: fib_send: first asynchronous command timed out.\n"
+                                               printk(KERN_ERR "aacraid: aac_fib_send: first asynchronous command timed out.\n"
                                                  "Usually a result of a PCI interrupt routing problem;\n"
                                                  "update mother board BIOS or consider utilizing one of\n"
                                                  "the SAFE mode kernel options (acpi, apic etc)\n");
@@ -624,7 +626,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid)
 }        
 
 /**
- *     fib_adapter_complete    -       complete adapter issued fib
+ *     aac_fib_adapter_complete        -       complete adapter issued fib
  *     @fibptr: fib to complete
  *     @size: size of fib
  *
@@ -632,7 +634,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid)
  *     the adapter.
  */
 
-int fib_adapter_complete(struct fib * fibptr, unsigned short size)
+int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
 {
        struct hw_fib * hw_fib = fibptr->hw_fib;
        struct aac_dev * dev = fibptr->dev;
@@ -683,20 +685,20 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
        }
        else 
        {
-               printk(KERN_WARNING "fib_adapter_complete: Unknown xferstate detected.\n");
+               printk(KERN_WARNING "aac_fib_adapter_complete: Unknown xferstate detected.\n");
                BUG();
        }   
        return 0;
 }
 
 /**
- *     fib_complete    -       fib completion handler
+ *     aac_fib_complete        -       fib completion handler
  *     @fib: FIB to complete
  *
  *     Will do all necessary work to complete a FIB.
  */
  
-int fib_complete(struct fib * fibptr)
+int aac_fib_complete(struct fib *fibptr)
 {
        struct hw_fib * hw_fib = fibptr->hw_fib;
 
@@ -995,14 +997,14 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
        if (!dev || !dev->scsi_host_ptr)
                return;
        /*
-        * force reload of disk info via probe_container
+        * force reload of disk info via aac_probe_container
         */
        if ((device_config_needed == CHANGE)
         && (dev->fsa_dev[container].valid == 1))
                dev->fsa_dev[container].valid = 2;
        if ((device_config_needed == CHANGE) ||
                        (device_config_needed == ADD))
-               probe_container(dev, container);
+               aac_probe_container(dev, container);
        device = scsi_device_lookup(dev->scsi_host_ptr, 
                CONTAINER_TO_CHANNEL(container), 
                CONTAINER_TO_ID(container), 
@@ -1104,7 +1106,7 @@ int aac_command_thread(struct aac_dev * dev)
                                /* Handle Driver Notify Events */
                                aac_handle_aif(dev, fib);
                                *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
-                               fib_adapter_complete(fib, (u16)sizeof(u32));
+                               aac_fib_adapter_complete(fib, (u16)sizeof(u32));
                        } else {
                                struct list_head *entry;
                                /* The u32 here is important and intended. We are using
@@ -1241,7 +1243,7 @@ int aac_command_thread(struct aac_dev * dev)
                                 *      Set the status of this FIB
                                 */
                                *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
-                               fib_adapter_complete(fib, sizeof(u32));
+                               aac_fib_adapter_complete(fib, sizeof(u32));
                                spin_unlock_irqrestore(&dev->fib_lock, flagv);
                                /* Free up the remaining resources */
                                hw_fib_p = hw_fib_pool;
index 439948ef82516535d66e2cec3df0e515530e119a..f6bcb9486f859897464bd649a4758403a8936488 100644 (file)
@@ -206,7 +206,7 @@ unsigned int aac_command_normal(struct aac_queue *q)
                         *      Set the status of this FIB
                         */
                        *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
-                       fib_adapter_complete(fib, sizeof(u32));
+                       aac_fib_adapter_complete(fib, sizeof(u32));
                        spin_lock_irqsave(q->lock, flags);
                }               
        }
index 0bf5f9a943e8a548d779b022246d63348f5c3c77..2716178905625911a1364dd559b7f3907e1846a9 100644 (file)
@@ -385,17 +385,45 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev,
 
 static int aac_slave_configure(struct scsi_device *sdev)
 {
-       struct Scsi_Host *host = sdev->host;
+       if (sdev_channel(sdev) == CONTAINER_CHANNEL) {
+               sdev->skip_ms_page_8 = 1;
+               sdev->skip_ms_page_3f = 1;
+       }
+       if ((sdev->type == TYPE_DISK) &&
+                       (sdev_channel(sdev) != CONTAINER_CHANNEL)) {
+               struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;
+               if (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))
+                       sdev->no_uld_attach = 1;
+       }
+       if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
+                       (sdev_channel(sdev) == CONTAINER_CHANNEL)) {
+               struct scsi_device * dev;
+               struct Scsi_Host *host = sdev->host;
+               unsigned num_lsu = 0;
+               unsigned num_one = 0;
+               unsigned depth;
 
-       if (sdev->tagged_supported)
-               scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, 128);
-       else
+               __shost_for_each_device(dev, host) {
+                       if (dev->tagged_supported && (dev->type == TYPE_DISK) &&
+                               (sdev_channel(dev) == CONTAINER_CHANNEL))
+                               ++num_lsu;
+                       else
+                               ++num_one;
+               }
+               if (num_lsu == 0)
+                       ++num_lsu;
+               depth = (host->can_queue - num_one) / num_lsu;
+               if (depth > 256)
+                       depth = 256;
+               else if (depth < 2)
+                       depth = 2;
+               scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, depth);
+               if (!(((struct aac_dev *)host->hostdata)->adapter_info.options &
+                               AAC_OPT_NEW_COMM))
+                       blk_queue_max_segment_size(sdev->request_queue, 65536);
+       } else
                scsi_adjust_queue_depth(sdev, 0, 1);
 
-       if (!(((struct aac_dev *)host->hostdata)->adapter_info.options
-         & AAC_OPT_NEW_COMM))
-               blk_queue_max_segment_size(sdev->request_queue, 65536);
-
        return 0;
 }
 
@@ -870,7 +898,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
  
        /*
         * max channel will be the physical channels plus 1 virtual channel
-        * all containers are on the virtual channel 0
+        * all containers are on the virtual channel 0 (CONTAINER_CHANNEL)
         * physical channels are address by their actual physical number+1
         */
        if (aac->nondasd_support == 1)
@@ -913,7 +941,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
        aac_adapter_disable_int(aac);
        free_irq(pdev->irq, aac);
  out_unmap:
-       fib_map_free(aac);
+       aac_fib_map_free(aac);
        pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys);
        kfree(aac->queues);
        iounmap(aac->regs.sa);
@@ -947,7 +975,7 @@ static void __devexit aac_remove_one(struct pci_dev *pdev)
 
        aac_send_shutdown(aac);
        aac_adapter_disable_int(aac);
-       fib_map_free(aac);
+       aac_fib_map_free(aac);
        pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr,
                        aac->comm_phys);
        kfree(aac->queues);
index bd3ffdf6c800088d5e6de6b915a6727eaa912757..62e3cda859afccb44dda94dc9c2a6d2ab0a18d31 100644 (file)
@@ -2816,7 +2816,7 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive)
             }
 #endif
 
-        } else {
+        } else if (scp->request_bufflen) {
             scp->SCp.Status = GDTH_MAP_SINGLE;
             scp->SCp.Message = (read_write == 1 ? 
                 PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
index 27acf78cf8d8c580c0f24a56f15a20bc04f989c9..2bba5e55d7bc6110d44aa6720280e12d4b79cbe6 100644 (file)
@@ -4235,35 +4235,6 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd)
                ipr_erp_start(ioa_cfg, ipr_cmd);
 }
 
-/**
- * ipr_save_ioafp_mode_select - Save adapters mode select data
- * @ioa_cfg:   ioa config struct
- * @scsi_cmd:  scsi command struct
- *
- * This function saves mode select data for the adapter to
- * use following an adapter reset.
- *
- * Return value:
- *     0 on success / SCSI_MLQUEUE_HOST_BUSY on failure
- **/
-static int ipr_save_ioafp_mode_select(struct ipr_ioa_cfg *ioa_cfg,
-                                      struct scsi_cmnd *scsi_cmd)
-{
-       if (!ioa_cfg->saved_mode_pages) {
-               ioa_cfg->saved_mode_pages  = kmalloc(sizeof(struct ipr_mode_pages),
-                                                    GFP_ATOMIC);
-               if (!ioa_cfg->saved_mode_pages) {
-                       dev_err(&ioa_cfg->pdev->dev,
-                               "IOA mode select buffer allocation failed\n");
-                       return SCSI_MLQUEUE_HOST_BUSY;
-               }
-       }
-
-       memcpy(ioa_cfg->saved_mode_pages, scsi_cmd->buffer, scsi_cmd->cmnd[4]);
-       ioa_cfg->saved_mode_page_len = scsi_cmd->cmnd[4];
-       return 0;
-}
-
 /**
  * ipr_queuecommand - Queue a mid-layer request
  * @scsi_cmd:  scsi command struct
@@ -4338,9 +4309,6 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
            (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE))
                ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
 
-       if (ipr_is_ioa_resource(res) && scsi_cmd->cmnd[0] == MODE_SELECT)
-               rc = ipr_save_ioafp_mode_select(ioa_cfg, scsi_cmd);
-
        if (likely(rc == 0))
                rc = ipr_build_ioadl(ioa_cfg, ipr_cmd);
 
@@ -4829,17 +4797,11 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd)
        int length;
 
        ENTER;
-       if (ioa_cfg->saved_mode_pages) {
-               memcpy(mode_pages, ioa_cfg->saved_mode_pages,
-                      ioa_cfg->saved_mode_page_len);
-               length = ioa_cfg->saved_mode_page_len;
-       } else {
-               ipr_scsi_bus_speed_limit(ioa_cfg);
-               ipr_check_term_power(ioa_cfg, mode_pages);
-               ipr_modify_ioafp_mode_page_28(ioa_cfg, mode_pages);
-               length = mode_pages->hdr.length + 1;
-               mode_pages->hdr.length = 0;
-       }
+       ipr_scsi_bus_speed_limit(ioa_cfg);
+       ipr_check_term_power(ioa_cfg, mode_pages);
+       ipr_modify_ioafp_mode_page_28(ioa_cfg, mode_pages);
+       length = mode_pages->hdr.length + 1;
+       mode_pages->hdr.length = 0;
 
        ipr_build_mode_select(ipr_cmd, cpu_to_be32(IPR_IOA_RES_HANDLE), 0x11,
                              ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages),
@@ -5969,7 +5931,6 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg)
        }
 
        ipr_free_dump(ioa_cfg);
-       kfree(ioa_cfg->saved_mode_pages);
        kfree(ioa_cfg->trace);
 }
 
index b639332131f1b8cb7dd251cfbdf58af919553a55..fd360bfe56dda32627d97babf3a1d92d2d000b54 100644 (file)
@@ -36,8 +36,8 @@
 /*
  * Literals
  */
-#define IPR_DRIVER_VERSION "2.1.1"
-#define IPR_DRIVER_DATE "(November 15, 2005)"
+#define IPR_DRIVER_VERSION "2.1.2"
+#define IPR_DRIVER_DATE "(February 8, 2006)"
 
 /*
  * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -1000,7 +1000,6 @@ struct ipr_ioa_cfg {
        struct Scsi_Host *host;
        struct pci_dev *pdev;
        struct ipr_sglist *ucode_sglist;
-       struct ipr_mode_pages *saved_mode_pages;
        u8 saved_mode_page_len;
 
        struct work_struct work_q;
index 780bfcc67096cff51069cf94bc1e4ae6374ceafe..ff79e68b347c5c15828884991ff03a74902099fe 100644 (file)
@@ -146,7 +146,7 @@ iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
        spin_unlock_irqrestore(&session->lock, flags);
        set_bit(SUSPEND_BIT, &conn->suspend_tx);
        set_bit(SUSPEND_BIT, &conn->suspend_rx);
-       iscsi_conn_error(iscsi_handle(conn), err);
+       iscsi_conn_error(conn->cls_conn, err);
 }
 
 static inline int
@@ -244,12 +244,10 @@ iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
        if (sc->sc_data_direction == DMA_TO_DEVICE) {
                struct iscsi_data_task *dtask, *n;
                /* WRITE: cleanup Data-Out's if any */
-               spin_lock(&conn->lock);
                list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) {
                        list_del(&dtask->item);
                        mempool_free(dtask, ctask->datapool);
                }
-               spin_unlock(&conn->lock);
        }
        ctask->xmstate = XMSTATE_IDLE;
        ctask->r2t = NULL;
@@ -689,7 +687,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
                                break;
 
                        if (!conn->in.datalen) {
-                               rc = iscsi_recv_pdu(iscsi_handle(conn), hdr,
+                               rc = iscsi_recv_pdu(conn->cls_conn, hdr,
                                                    NULL, 0);
                                if (conn->login_mtask != mtask) {
                                        spin_lock(&session->lock);
@@ -737,7 +735,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
                        if (!conn->in.datalen) {
                                struct iscsi_mgmt_task *mtask;
 
-                               rc = iscsi_recv_pdu(iscsi_handle(conn), hdr,
+                               rc = iscsi_recv_pdu(conn->cls_conn, hdr,
                                                    NULL, 0);
                                mtask = (struct iscsi_mgmt_task *)
                                        session->mgmt_cmds[conn->in.itt -
@@ -761,7 +759,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
                                rc = iscsi_check_assign_cmdsn(session,
                                                 (struct iscsi_nopin*)hdr);
                                if (!rc && hdr->ttt != ISCSI_RESERVED_TAG)
-                                       rc = iscsi_recv_pdu(iscsi_handle(conn),
+                                       rc = iscsi_recv_pdu(conn->cls_conn,
                                                            hdr, NULL, 0);
                        } else
                                rc = ISCSI_ERR_PROTO;
@@ -1044,7 +1042,7 @@ iscsi_data_recv(struct iscsi_conn *conn)
                        goto exit;
                }
 
-               rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr,
+               rc = iscsi_recv_pdu(conn->cls_conn, conn->in.hdr,
                                    conn->data, conn->in.datalen);
 
                if (!rc && conn->datadgst_en &&
@@ -2428,19 +2426,20 @@ iscsi_pool_free(struct iscsi_queue *q, void **items)
 }
 
 static struct iscsi_cls_conn *
-iscsi_conn_create(struct Scsi_Host *shost, uint32_t conn_idx)
+iscsi_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
 {
+       struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
        struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
        struct iscsi_conn *conn;
        struct iscsi_cls_conn *cls_conn;
 
-       cls_conn = iscsi_create_conn(hostdata_session(shost->hostdata),
-                                    conn_idx);
+       cls_conn = iscsi_create_conn(cls_session, conn_idx);
        if (!cls_conn)
                return NULL;
        conn = cls_conn->dd_data;
+       memset(conn, 0, sizeof(*conn));
 
-       memset(conn, 0, sizeof(struct iscsi_conn));
+       conn->cls_conn = cls_conn;
        conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
        conn->in_progress = IN_PROGRESS_WAIT_HEADER;
        conn->id = conn_idx;
@@ -2452,8 +2451,6 @@ iscsi_conn_create(struct Scsi_Host *shost, uint32_t conn_idx)
        conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
        conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
 
-       spin_lock_init(&conn->lock);
-
        /* initialize general xmit PDU commands queue */
        conn->xmitqueue = kfifo_alloc(session->cmds_max * sizeof(void*),
                                        GFP_KERNEL, NULL);
@@ -2625,11 +2622,13 @@ iscsi_conn_destroy(struct iscsi_cls_conn *cls_conn)
 }
 
 static int
-iscsi_conn_bind(iscsi_sessionh_t sessionh, iscsi_connh_t connh,
-               uint32_t transport_fd, int is_leading)
+iscsi_conn_bind(struct iscsi_cls_session *cls_session,
+               struct iscsi_cls_conn *cls_conn, uint32_t transport_fd,
+               int is_leading)
 {
-       struct iscsi_session *session = iscsi_ptr(sessionh);
-       struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = iscsi_ptr(connh);
+       struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+       struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
+       struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data;
        struct sock *sk;
        struct socket *sock;
        int err;
@@ -2703,9 +2702,9 @@ iscsi_conn_bind(iscsi_sessionh_t sessionh, iscsi_connh_t connh,
 }
 
 static int
-iscsi_conn_start(iscsi_connh_t connh)
+iscsi_conn_start(struct iscsi_cls_conn *cls_conn)
 {
-       struct iscsi_conn *conn = iscsi_ptr(connh);
+       struct iscsi_conn *conn = cls_conn->dd_data;
        struct iscsi_session *session = conn->session;
        struct sock *sk;
 
@@ -2754,9 +2753,9 @@ iscsi_conn_start(iscsi_connh_t connh)
 }
 
 static void
-iscsi_conn_stop(iscsi_connh_t connh, int flag)
+iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
 {
-       struct iscsi_conn *conn = iscsi_ptr(connh);
+       struct iscsi_conn *conn = cls_conn->dd_data;
        struct iscsi_session *session = conn->session;
        struct sock *sk;
        unsigned long flags;
@@ -3253,9 +3252,9 @@ static struct scsi_host_template iscsi_sht = {
 
 static struct iscsi_transport iscsi_tcp_transport;
 
-static struct Scsi_Host *
+static struct iscsi_cls_session *
 iscsi_session_create(struct scsi_transport_template *scsit,
-                    uint32_t initial_cmdsn)
+                    uint32_t initial_cmdsn, uint32_t *sid)
 {
        struct Scsi_Host *shost;
        struct iscsi_session *session;
@@ -3268,13 +3267,14 @@ iscsi_session_create(struct scsi_transport_template *scsit,
        session = iscsi_hostdata(shost->hostdata);
        memset(session, 0, sizeof(struct iscsi_session));
        session->host = shost;
-       session->state = ISCSI_STATE_LOGGED_IN;
+       session->state = ISCSI_STATE_FREE;
        session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX;
        session->cmds_max = ISCSI_XMIT_CMDS_MAX;
        session->cmdsn = initial_cmdsn;
        session->exp_cmdsn = initial_cmdsn + 1;
        session->max_cmdsn = initial_cmdsn + 1;
        session->max_r2t = 1;
+       *sid = shost->host_no;
 
        /* initialize SCSI PDU commands pool */
        if (iscsi_pool_init(&session->cmdpool, session->cmds_max,
@@ -3311,22 +3311,24 @@ iscsi_session_create(struct scsi_transport_template *scsit,
        if (iscsi_r2tpool_alloc(session))
                goto r2tpool_alloc_fail;
 
-       return shost;
+       return hostdata_session(shost->hostdata);
 
 r2tpool_alloc_fail:
        for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++)
                kfree(session->mgmt_cmds[cmd_i]->data);
-       iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
 immdata_alloc_fail:
+       iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
 mgmtpool_alloc_fail:
        iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
 cmdpool_alloc_fail:
+       iscsi_transport_destroy_session(shost);
        return NULL;
 }
 
 static void
-iscsi_session_destroy(struct Scsi_Host *shost)
+iscsi_session_destroy(struct iscsi_cls_session *cls_session)
 {
+       struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
        struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
        int cmd_i;
        struct iscsi_data_task *dtask, *n;
@@ -3350,10 +3352,10 @@ iscsi_session_destroy(struct Scsi_Host *shost)
 }
 
 static int
-iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param,
+iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
                     uint32_t value)
 {
-       struct iscsi_conn *conn = iscsi_ptr(connh);
+       struct iscsi_conn *conn = cls_conn->dd_data;
        struct iscsi_session *session = conn->session;
 
        spin_lock_bh(&session->lock);
@@ -3495,9 +3497,10 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param,
 }
 
 static int
-iscsi_session_get_param(struct Scsi_Host *shost,
+iscsi_session_get_param(struct iscsi_cls_session *cls_session,
                        enum iscsi_param param, uint32_t *value)
 {
+       struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
        struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
 
        switch(param) {
@@ -3539,9 +3542,10 @@ iscsi_session_get_param(struct Scsi_Host *shost,
 }
 
 static int
-iscsi_conn_get_param(void *data, enum iscsi_param param, uint32_t *value)
+iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
+                    enum iscsi_param param, uint32_t *value)
 {
-       struct iscsi_conn *conn = data;
+       struct iscsi_conn *conn = cls_conn->dd_data;
 
        switch(param) {
        case ISCSI_PARAM_MAX_RECV_DLENGTH:
@@ -3564,9 +3568,9 @@ iscsi_conn_get_param(void *data, enum iscsi_param param, uint32_t *value)
 }
 
 static void
-iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats)
+iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
 {
-       struct iscsi_conn *conn = iscsi_ptr(connh);
+       struct iscsi_conn *conn = cls_conn->dd_data;
 
        stats->txdata_octets = conn->txdata_octets;
        stats->rxdata_octets = conn->rxdata_octets;
@@ -3587,10 +3591,10 @@ iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats)
 }
 
 static int
-iscsi_conn_send_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, char *data,
-                   uint32_t data_size)
+iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr,
+                   char *data, uint32_t data_size)
 {
-       struct iscsi_conn *conn = iscsi_ptr(connh);
+       struct iscsi_conn *conn = cls_conn->dd_data;
        int rc;
 
        mutex_lock(&conn->xmitmutex);
index f95e61b76f70baf3ba5bdd45906439db5971c4ba..ba26741ac1544bd41ec348b95579432471d5d75b 100644 (file)
@@ -113,7 +113,10 @@ struct iscsi_tcp_recv {
        int                     datadgst;
 };
 
+struct iscsi_cls_conn;
+
 struct iscsi_conn {
+       struct iscsi_cls_conn   *cls_conn;      /* ptr to class connection */
        struct iscsi_hdr        hdr;            /* header placeholder */
        char                    hdrext[4*sizeof(__u16) +
                                    sizeof(__u32)];
@@ -143,7 +146,6 @@ struct iscsi_conn {
        struct iscsi_mgmt_task  *login_mtask;   /* mtask used for login/text */
        struct iscsi_mgmt_task  *mtask;         /* xmit mtask in progress */
        struct iscsi_cmd_task   *ctask;         /* xmit ctask in progress */
-       spinlock_t              lock;           /* FIXME: to be removed */
 
        /* old values for socket callbacks */
        void                    (*old_data_ready)(struct sock *, int);
index d101a8a6f4e86f4206bd3f70697af1f3506158ff..7144674bc8e677adae796bef8ed8a5cea0e0f323 100644 (file)
@@ -5049,7 +5049,7 @@ static struct pci_device_id megaraid_pci_tbl[] = {
 MODULE_DEVICE_TABLE(pci, megaraid_pci_tbl);
 
 static struct pci_driver megaraid_pci_driver = {
-       .name           = "megaraid",
+       .name           = "megaraid_legacy",
        .id_table       = megaraid_pci_tbl,
        .probe          = megaraid_probe_one,
        .remove         = __devexit_p(megaraid_remove_one),
index 4b3e0d6e5afacc6fbc05ae1085b2c02fcbe9fb28..4b75fe619d9cf44c7758d8636cfa47f453891bac 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/mutex.h>
 
 #define MEGARAID_VERSION       \
-       "v2.00.3 (Release Date: Wed Feb 19 08:51:30 EST 2003)\n"
+       "v2.00.4 (Release Date: Thu Feb 9 08:51:30 EST 2006)\n"
 
 /*
  * Driver features - change the values to enable or disable features in the
index a487f414960e5e9a6553c7c1b7dc7fe2042253c2..7de267e14458ba0bafaa1138c54537796c269bff 100644 (file)
@@ -10,7 +10,7 @@
  *        2 of the License, or (at your option) any later version.
  *
  * FILE                : megaraid_sas.c
- * Version     : v00.00.02.02
+ * Version     : v00.00.02.04
  *
  * Authors:
  *     Sreenivas Bagalkote     <Sreenivas.Bagalkote@lsil.com>
@@ -59,6 +59,12 @@ static struct pci_device_id megasas_pci_table[] = {
         PCI_ANY_ID,
         PCI_ANY_ID,
         },
+       {
+        PCI_VENDOR_ID_LSI_LOGIC,
+        PCI_DEVICE_ID_LSI_SAS1078R, // ppc IOP
+        PCI_ANY_ID,
+        PCI_ANY_ID,
+       },
        {
         PCI_VENDOR_ID_DELL,
         PCI_DEVICE_ID_DELL_PERC5, // xscale IOP
@@ -198,6 +204,86 @@ static struct megasas_instance_template megasas_instance_template_xscale = {
 *      to xscale (deviceid : 1064R, PERC5) controllers
 */
 
+/**
+*      The following functions are defined for ppc (deviceid : 0x60) 
+*      controllers
+*/
+
+/**
+ * megasas_enable_intr_ppc -   Enables interrupts
+ * @regs:                      MFI register set
+ */
+static inline void
+megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs)
+{
+       writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
+    
+       writel(~0x80000004, &(regs)->outbound_intr_mask);
+
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_read_fw_status_reg_ppc - returns the current FW status value
+ * @regs:                      MFI register set
+ */
+static u32
+megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs)
+{
+       return readl(&(regs)->outbound_scratch_pad);
+}
+
+/**
+ * megasas_clear_interrupt_ppc -       Check & clear interrupt
+ * @regs:                              MFI register set
+ */
+static int 
+megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
+{
+       u32 status;
+       /*
+        * Check if it is our interrupt
+        */
+       status = readl(&regs->outbound_intr_status);
+
+       if (!(status & MFI_REPLY_1078_MESSAGE_INTERRUPT)) {
+               return 1;
+       }
+
+       /*
+        * Clear the interrupt by writing back the same value
+        */
+       writel(status, &regs->outbound_doorbell_clear);
+
+       return 0;
+}
+/**
+ * megasas_fire_cmd_ppc -      Sends command to the FW
+ * @frame_phys_addr :          Physical address of cmd
+ * @frame_count :              Number of frames for the command
+ * @regs :                     MFI register set
+ */
+static inline void 
+megasas_fire_cmd_ppc(dma_addr_t frame_phys_addr, u32 frame_count, struct megasas_register_set __iomem *regs)
+{
+       writel((frame_phys_addr | (frame_count<<1))|1, 
+                       &(regs)->inbound_queue_port);
+}
+
+static struct megasas_instance_template megasas_instance_template_ppc = {
+       
+       .fire_cmd = megasas_fire_cmd_ppc,
+       .enable_intr = megasas_enable_intr_ppc,
+       .clear_intr = megasas_clear_intr_ppc,
+       .read_fw_status_reg = megasas_read_fw_status_reg_ppc,
+};
+
+/**
+*      This is the end of set of functions & definitions
+*      specific to ppc (deviceid : 0x60) controllers
+*/
+
 /**
  * megasas_disable_intr -      Disables interrupts
  * @regs:                      MFI register set
@@ -1607,7 +1693,17 @@ static int megasas_init_mfi(struct megasas_instance *instance)
 
        reg_set = instance->reg_set;
 
-       instance->instancet = &megasas_instance_template_xscale;
+       switch(instance->pdev->device)
+       {
+               case PCI_DEVICE_ID_LSI_SAS1078R:        
+                       instance->instancet = &megasas_instance_template_ppc;
+                       break;
+               case PCI_DEVICE_ID_LSI_SAS1064R:
+               case PCI_DEVICE_ID_DELL_PERC5:
+               default:
+                       instance->instancet = &megasas_instance_template_xscale;
+                       break;
+       }
 
        /*
         * We expect the FW state to be READY
@@ -1983,6 +2079,7 @@ static int megasas_io_attach(struct megasas_instance *instance)
        host->max_channel = MEGASAS_MAX_CHANNELS - 1;
        host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;
        host->max_lun = MEGASAS_MAX_LUN;
+       host->max_cmd_len = 16;
 
        /*
         * Notify the mid-layer about the new controller
index d6d166c0663ff664930b06432b4c2753c93631b3..89639f0c38ef2e3683f012328a763dd4755f6123 100644 (file)
@@ -18,9 +18,9 @@
 /**
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION                                "00.00.02.02"
-#define MEGASAS_RELDATE                                "Jan 23, 2006"
-#define MEGASAS_EXT_VERSION                    "Mon Jan 23 14:09:01 PST 2006"
+#define MEGASAS_VERSION                                "00.00.02.04"
+#define MEGASAS_RELDATE                                "Feb 03, 2006"
+#define MEGASAS_EXT_VERSION                    "Fri Feb 03 14:31:44 PST 2006"
 /*
  * =====================================
  * MegaRAID SAS MFI firmware definitions
@@ -553,31 +553,46 @@ struct megasas_ctrl_info {
 #define MFI_OB_INTR_STATUS_MASK                        0x00000002
 #define MFI_POLL_TIMEOUT_SECS                  10
 
+#define MFI_REPLY_1078_MESSAGE_INTERRUPT       0x80000000
+#define PCI_DEVICE_ID_LSI_SAS1078R             0x00000060
 struct megasas_register_set {
+       u32     reserved_0[4];                  /*0000h*/
 
-       u32 reserved_0[4];      /*0000h */
+       u32     inbound_msg_0;                  /*0010h*/
+       u32     inbound_msg_1;                  /*0014h*/
+       u32     outbound_msg_0;                 /*0018h*/
+       u32     outbound_msg_1;                 /*001Ch*/
 
-       u32 inbound_msg_0;      /*0010h */
-       u32 inbound_msg_1;      /*0014h */
-       u32 outbound_msg_0;     /*0018h */
-       u32 outbound_msg_1;     /*001Ch */
+       u32     inbound_doorbell;               /*0020h*/
+       u32     inbound_intr_status;            /*0024h*/
+       u32     inbound_intr_mask;              /*0028h*/
 
-       u32 inbound_doorbell;   /*0020h */
-       u32 inbound_intr_status;        /*0024h */
-       u32 inbound_intr_mask;  /*0028h */
+       u32     outbound_doorbell;              /*002Ch*/
+       u32     outbound_intr_status;           /*0030h*/
+       u32     outbound_intr_mask;             /*0034h*/
 
-       u32 outbound_doorbell;  /*002Ch */
-       u32 outbound_intr_status;       /*0030h */
-       u32 outbound_intr_mask; /*0034h */
+       u32     reserved_1[2];                  /*0038h*/
 
-       u32 reserved_1[2];      /*0038h */
+       u32     inbound_queue_port;             /*0040h*/
+       u32     outbound_queue_port;            /*0044h*/
 
-       u32 inbound_queue_port; /*0040h */
-       u32 outbound_queue_port;        /*0044h */
+       u32     reserved_2[22];                 /*0048h*/
 
-       u32 reserved_2;         /*004Ch */
+       u32     outbound_doorbell_clear;        /*00A0h*/
 
-       u32 index_registers[1004];      /*0050h */
+       u32     reserved_3[3];                  /*00A4h*/
+
+       u32     outbound_scratch_pad ;          /*00B0h*/
+
+       u32     reserved_4[3];                  /*00B4h*/
+
+       u32     inbound_low_queue_port ;        /*00C0h*/
+
+       u32     inbound_high_queue_port ;       /*00C4h*/
+
+       u32     reserved_5;                     /*00C8h*/
+       u32     index_registers[820];           /*00CCh*/
 
 } __attribute__ ((packed));
 
index b17ee62dd1a9ce67981d5bfc4ebf6ce2e7596898..92b3e13e9061d8b00d869d5c1ac07afcf30ff50d 100644 (file)
@@ -7,7 +7,6 @@
 #include "qla_def.h"
 
 #include <linux/vmalloc.h>
-#include <scsi/scsi_transport_fc.h>
 
 /* SYSFS attributes --------------------------------------------------------- */
 
@@ -114,7 +113,7 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, char *buf, loff_t off,
            struct device, kobj)));
        unsigned long   flags;
 
-       if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size)
+       if (!capable(CAP_SYS_ADMIN) || off != 0)
                return 0;
 
        /* Read NVRAM. */
@@ -123,7 +122,7 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, char *buf, loff_t off,
            ha->nvram_size);
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
-       return (count);
+       return ha->nvram_size;
 }
 
 static ssize_t
@@ -175,19 +174,150 @@ static struct bin_attribute sysfs_nvram_attr = {
                .mode = S_IRUSR | S_IWUSR,
                .owner = THIS_MODULE,
        },
-       .size = 0,
+       .size = 512,
        .read = qla2x00_sysfs_read_nvram,
        .write = qla2x00_sysfs_write_nvram,
 };
 
+static ssize_t
+qla2x00_sysfs_read_optrom(struct kobject *kobj, char *buf, loff_t off,
+    size_t count)
+{
+       struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
+           struct device, kobj)));
+
+       if (ha->optrom_state != QLA_SREADING)
+               return 0;
+       if (off > ha->optrom_size)
+               return 0;
+       if (off + count > ha->optrom_size)
+               count = ha->optrom_size - off;
+
+       memcpy(buf, &ha->optrom_buffer[off], count);
+
+       return count;
+}
+
+static ssize_t
+qla2x00_sysfs_write_optrom(struct kobject *kobj, char *buf, loff_t off,
+    size_t count)
+{
+       struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
+           struct device, kobj)));
+
+       if (ha->optrom_state != QLA_SWRITING)
+               return -EINVAL;
+       if (off > ha->optrom_size)
+               return -ERANGE;
+       if (off + count > ha->optrom_size)
+               count = ha->optrom_size - off;
+
+       memcpy(&ha->optrom_buffer[off], buf, count);
+
+       return count;
+}
+
+static struct bin_attribute sysfs_optrom_attr = {
+       .attr = {
+               .name = "optrom",
+               .mode = S_IRUSR | S_IWUSR,
+               .owner = THIS_MODULE,
+       },
+       .size = OPTROM_SIZE_24XX,
+       .read = qla2x00_sysfs_read_optrom,
+       .write = qla2x00_sysfs_write_optrom,
+};
+
+static ssize_t
+qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, char *buf, loff_t off,
+    size_t count)
+{
+       struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
+           struct device, kobj)));
+       int val;
+
+       if (off)
+               return 0;
+
+       if (sscanf(buf, "%d", &val) != 1)
+               return -EINVAL;
+
+       switch (val) {
+       case 0:
+               if (ha->optrom_state != QLA_SREADING &&
+                   ha->optrom_state != QLA_SWRITING)
+                       break;
+
+               ha->optrom_state = QLA_SWAITING;
+               vfree(ha->optrom_buffer);
+               ha->optrom_buffer = NULL;
+               break;
+       case 1:
+               if (ha->optrom_state != QLA_SWAITING)
+                       break;
+
+               ha->optrom_state = QLA_SREADING;
+               ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size);
+               if (ha->optrom_buffer == NULL) {
+                       qla_printk(KERN_WARNING, ha,
+                           "Unable to allocate memory for optrom retrieval "
+                           "(%x).\n", ha->optrom_size);
+
+                       ha->optrom_state = QLA_SWAITING;
+                       return count;
+               }
+
+               memset(ha->optrom_buffer, 0, ha->optrom_size);
+               ha->isp_ops.read_optrom(ha, ha->optrom_buffer, 0,
+                   ha->optrom_size);
+               break;
+       case 2:
+               if (ha->optrom_state != QLA_SWAITING)
+                       break;
+
+               ha->optrom_state = QLA_SWRITING;
+               ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size);
+               if (ha->optrom_buffer == NULL) {
+                       qla_printk(KERN_WARNING, ha,
+                           "Unable to allocate memory for optrom update "
+                           "(%x).\n", ha->optrom_size);
+
+                       ha->optrom_state = QLA_SWAITING;
+                       return count;
+               }
+               memset(ha->optrom_buffer, 0, ha->optrom_size);
+               break;
+       case 3:
+               if (ha->optrom_state != QLA_SWRITING)
+                       break;
+
+               ha->isp_ops.write_optrom(ha, ha->optrom_buffer, 0,
+                   ha->optrom_size);
+               break;
+       }
+       return count;
+}
+
+static struct bin_attribute sysfs_optrom_ctl_attr = {
+       .attr = {
+               .name = "optrom_ctl",
+               .mode = S_IWUSR,
+               .owner = THIS_MODULE,
+       },
+       .size = 0,
+       .write = qla2x00_sysfs_write_optrom_ctl,
+};
+
 void
 qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha)
 {
        struct Scsi_Host *host = ha->host;
 
        sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr);
-       sysfs_nvram_attr.size = ha->nvram_size;
        sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr);
+       sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr);
+       sysfs_create_bin_file(&host->shost_gendev.kobj,
+           &sysfs_optrom_ctl_attr);
 }
 
 void
@@ -197,6 +327,12 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha)
 
        sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr);
        sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr);
+       sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr);
+       sysfs_remove_bin_file(&host->shost_gendev.kobj,
+           &sysfs_optrom_ctl_attr);
+
+       if (ha->beacon_blink_led == 1)
+               ha->isp_ops.beacon_off(ha);
 }
 
 /* Scsi_Host attributes. */
@@ -384,6 +520,50 @@ qla2x00_zio_timer_store(struct class_device *cdev, const char *buf,
        return strlen(buf);
 }
 
+static ssize_t
+qla2x00_beacon_show(struct class_device *cdev, char *buf)
+{
+       scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+       int len = 0;
+
+       if (ha->beacon_blink_led)
+               len += snprintf(buf + len, PAGE_SIZE-len, "Enabled\n");
+       else
+               len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n");
+       return len;
+}
+
+static ssize_t
+qla2x00_beacon_store(struct class_device *cdev, const char *buf,
+    size_t count)
+{
+       scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+       int val = 0;
+       int rval;
+
+       if (IS_QLA2100(ha) || IS_QLA2200(ha))
+               return -EPERM;
+
+       if (test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)) {
+               qla_printk(KERN_WARNING, ha,
+                   "Abort ISP active -- ignoring beacon request.\n");
+               return -EBUSY;
+       }
+
+       if (sscanf(buf, "%d", &val) != 1)
+               return -EINVAL;
+
+       if (val)
+               rval = ha->isp_ops.beacon_on(ha);
+       else
+               rval = ha->isp_ops.beacon_off(ha);
+
+       if (rval != QLA_SUCCESS)
+               count = 0;
+
+       return count;
+}
+
 static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show,
        NULL);
 static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
@@ -398,6 +578,8 @@ static CLASS_DEVICE_ATTR(zio, S_IRUGO | S_IWUSR, qla2x00_zio_show,
     qla2x00_zio_store);
 static CLASS_DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show,
     qla2x00_zio_timer_store);
+static CLASS_DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show,
+    qla2x00_beacon_store);
 
 struct class_device_attribute *qla2x00_host_attrs[] = {
        &class_device_attr_driver_version,
@@ -411,6 +593,7 @@ struct class_device_attribute *qla2x00_host_attrs[] = {
        &class_device_attr_state,
        &class_device_attr_zio,
        &class_device_attr_zio_timer,
+       &class_device_attr_beacon,
        NULL,
 };
 
@@ -425,6 +608,49 @@ qla2x00_get_host_port_id(struct Scsi_Host *shost)
            ha->d_id.b.area << 8 | ha->d_id.b.al_pa;
 }
 
+static void
+qla2x00_get_host_speed(struct Scsi_Host *shost)
+{
+       scsi_qla_host_t *ha = to_qla_host(shost);
+       uint32_t speed = 0;
+
+       switch (ha->link_data_rate) {
+       case LDR_1GB:
+               speed = 1;
+               break;
+       case LDR_2GB:
+               speed = 2;
+               break;
+       case LDR_4GB:
+               speed = 4;
+               break;
+       }
+       fc_host_speed(shost) = speed;
+}
+
+static void
+qla2x00_get_host_port_type(struct Scsi_Host *shost)
+{
+       scsi_qla_host_t *ha = to_qla_host(shost);
+       uint32_t port_type = FC_PORTTYPE_UNKNOWN;
+
+       switch (ha->current_topology) {
+       case ISP_CFG_NL:
+               port_type = FC_PORTTYPE_LPORT;
+               break;
+       case ISP_CFG_FL:
+               port_type = FC_PORTTYPE_NLPORT;
+               break;
+       case ISP_CFG_N:
+               port_type = FC_PORTTYPE_PTP;
+               break;
+       case ISP_CFG_F:
+               port_type = FC_PORTTYPE_NPORT;
+               break;
+       }
+       fc_host_port_type(shost) = port_type;
+}
+
 static void
 qla2x00_get_starget_node_name(struct scsi_target *starget)
 {
@@ -512,6 +738,41 @@ qla2x00_issue_lip(struct Scsi_Host *shost)
        return 0;
 }
 
+static struct fc_host_statistics *
+qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
+{
+       scsi_qla_host_t *ha = to_qla_host(shost);
+       int rval;
+       uint16_t mb_stat[1];
+       link_stat_t stat_buf;
+       struct fc_host_statistics *pfc_host_stat;
+
+       pfc_host_stat = &ha->fc_host_stat;
+       memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics));
+
+       if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+               rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf,
+                   sizeof(stat_buf) / 4, mb_stat);
+       } else {
+               rval = qla2x00_get_link_status(ha, ha->loop_id, &stat_buf,
+                   mb_stat);
+       }
+       if (rval != 0) {
+               qla_printk(KERN_WARNING, ha,
+                   "Unable to retrieve host statistics (%d).\n", mb_stat[0]);
+               return pfc_host_stat;
+       }
+
+       pfc_host_stat->link_failure_count = stat_buf.link_fail_cnt;
+       pfc_host_stat->loss_of_sync_count = stat_buf.loss_sync_cnt;
+       pfc_host_stat->loss_of_signal_count = stat_buf.loss_sig_cnt;
+       pfc_host_stat->prim_seq_protocol_err_count = stat_buf.prim_seq_err_cnt;
+       pfc_host_stat->invalid_tx_word_count = stat_buf.inval_xmit_word_cnt;
+       pfc_host_stat->invalid_crc_count = stat_buf.inval_crc_cnt;
+
+       return pfc_host_stat;
+}
+
 struct fc_function_template qla2xxx_transport_functions = {
 
        .show_host_node_name = 1,
@@ -520,6 +781,10 @@ struct fc_function_template qla2xxx_transport_functions = {
 
        .get_host_port_id = qla2x00_get_host_port_id,
        .show_host_port_id = 1,
+       .get_host_speed = qla2x00_get_host_speed,
+       .show_host_speed = 1,
+       .get_host_port_type = qla2x00_get_host_port_type,
+       .show_host_port_type = 1,
 
        .dd_fcrport_size = sizeof(struct fc_port *),
        .show_rport_supported_classes = 1,
@@ -536,6 +801,7 @@ struct fc_function_template qla2xxx_transport_functions = {
        .show_rport_dev_loss_tmo = 1,
 
        .issue_fc_host_lip = qla2x00_issue_lip,
+       .get_fc_host_stats = qla2x00_get_fc_host_stats,
 };
 
 void
index bad066e5772acfce0079784ef2fada7c73a9a707..b31a03bbd14f4fd495dcc44fe6bfe367aa0c4c6a 100644 (file)
@@ -29,6 +29,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_transport_fc.h>
 
 #if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
 #if defined(CONFIG_SCSI_QLA21XX) || defined(CONFIG_SCSI_QLA21XX_MODULE)
 #define WRT_REG_WORD(addr, data)       writew(data,addr)
 #define WRT_REG_DWORD(addr, data)      writel(data,addr)
 
+/*
+ * The ISP2312 v2 chip cannot access the FLASH/GPIO registers via MMIO in an
+ * 133Mhz slot.
+ */
+#define RD_REG_WORD_PIO(addr)          (inw((unsigned long)addr))
+#define WRT_REG_WORD_PIO(addr, data)   (outw(data,(unsigned long)addr))
+
 /*
  * Fibre Channel device definitions.
  */
@@ -432,6 +440,9 @@ struct device_reg_2xxx {
 #define GPIO_LED_GREEN_ON_AMBER_OFF    0x0040
 #define GPIO_LED_GREEN_OFF_AMBER_ON    0x0080
 #define GPIO_LED_GREEN_ON_AMBER_ON     0x00C0
+#define GPIO_LED_ALL_OFF               0x0000
+#define GPIO_LED_RED_ON_OTHER_OFF      0x0001  /* isp2322 */
+#define GPIO_LED_RGA_ON                        0x00C1  /* isp2322: red green amber */
 
        union {
                struct {
@@ -2199,6 +2210,15 @@ struct isp_operations {
 
        void (*fw_dump) (struct scsi_qla_host *, int);
        void (*ascii_fw_dump) (struct scsi_qla_host *);
+
+       int (*beacon_on) (struct scsi_qla_host *);
+       int (*beacon_off) (struct scsi_qla_host *);
+       void (*beacon_blink) (struct scsi_qla_host *);
+
+       uint8_t * (*read_optrom) (struct scsi_qla_host *, uint8_t *,
+               uint32_t, uint32_t);
+       int (*write_optrom) (struct scsi_qla_host *, uint8_t *, uint32_t,
+               uint32_t);
 };
 
 /*
@@ -2331,6 +2351,10 @@ typedef struct scsi_qla_host {
        uint16_t        min_external_loopid;    /* First external loop Id */
 
        uint16_t        link_data_rate;         /* F/W operating speed */
+#define LDR_1GB                0
+#define LDR_2GB                1
+#define LDR_4GB                3
+#define LDR_UNKNOWN    0xFFFF
 
        uint8_t         current_topology;
        uint8_t         prev_topology;
@@ -2486,12 +2510,26 @@ typedef struct scsi_qla_host {
        uint8_t         *port_name;
        uint32_t    isp_abort_cnt;
 
+       /* Option ROM information. */
+       char            *optrom_buffer;
+       uint32_t        optrom_size;
+       int             optrom_state;
+#define QLA_SWAITING   0
+#define QLA_SREADING   1
+#define QLA_SWRITING   2
+
        /* Needed for BEACON */
        uint16_t        beacon_blink_led;
-       uint16_t        beacon_green_on;
+       uint8_t         beacon_color_state;
+#define QLA_LED_GRN_ON         0x01
+#define QLA_LED_YLW_ON         0x02
+#define QLA_LED_ABR_ON         0x04
+#define QLA_LED_ALL_ON         0x07    /* yellow, green, amber. */
+                                       /* ISP2322: red, green, amber. */
 
        uint16_t        zio_mode;
        uint16_t        zio_timer;
+       struct fc_host_statistics fc_host_stat;
 } scsi_qla_host_t;
 
 
@@ -2557,7 +2595,9 @@ struct _qla2x00stats  {
 /*
  * Flash support definitions
  */
-#define FLASH_IMAGE_SIZE       131072
+#define OPTROM_SIZE_2300       0x20000
+#define OPTROM_SIZE_2322       0x100000
+#define OPTROM_SIZE_24XX       0x100000
 
 #include "qla_gbl.h"
 #include "qla_dbg.h"
index 35266bd5d5383ba75919f1e285601577ad3abd54..ffdc2680f0490817f6d64a4dea44279fcef7831c 100644 (file)
@@ -75,12 +75,12 @@ extern void qla2x00_cmd_timeout(srb_t *);
 extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int);
 extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int);
 
-extern void qla2x00_blink_led(scsi_qla_host_t *);
-
 extern int qla2x00_down_timeout(struct semaphore *, unsigned long);
 
 extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
 
+extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
+
 /*
  * Global Function Prototypes in qla_iocb.c source file.
  */
@@ -185,6 +185,13 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *, uint16_t *,
 extern int
 qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map);
 
+extern int
+qla2x00_get_link_status(scsi_qla_host_t *, uint16_t, link_stat_t *,
+    uint16_t *);
+
+extern int
+qla24xx_get_isp_stats(scsi_qla_host_t *, uint32_t *, uint32_t, uint16_t *);
+
 extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *);
 extern int qla24xx_abort_target(fc_port_t *);
 
@@ -228,6 +235,22 @@ extern int qla2x00_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
 extern int qla24xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
     uint32_t);
 
+extern int qla2x00_beacon_on(struct scsi_qla_host *);
+extern int qla2x00_beacon_off(struct scsi_qla_host *);
+extern void qla2x00_beacon_blink(struct scsi_qla_host *);
+extern int qla24xx_beacon_on(struct scsi_qla_host *);
+extern int qla24xx_beacon_off(struct scsi_qla_host *);
+extern void qla24xx_beacon_blink(struct scsi_qla_host *);
+
+extern uint8_t *qla2x00_read_optrom_data(struct scsi_qla_host *, uint8_t *,
+    uint32_t, uint32_t);
+extern int qla2x00_write_optrom_data(struct scsi_qla_host *, uint8_t *,
+    uint32_t, uint32_t);
+extern uint8_t *qla24xx_read_optrom_data(struct scsi_qla_host *, uint8_t *,
+    uint32_t, uint32_t);
+extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *,
+    uint32_t, uint32_t);
+
 /*
  * Global Function Prototypes in qla_dbg.c source file.
  */
index e67bb099781818339b6a1ef6342694c54825860c..634ee174bff2a315e95fc29dd6fc41a72145480f 100644 (file)
@@ -8,7 +8,6 @@
 
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
-#include <scsi/scsi_transport_fc.h>
 
 #include "qla_devtbl.h"
 
index 7ec0b8d6f07b379548c5e3ba777fec2dfc78bfef..6544b6d0891d07826012baaf73ab173ae80d1ee7 100644 (file)
@@ -814,6 +814,7 @@ qla24xx_start_scsi(srb_t *sp)
        cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
 
        int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
+       host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
 
        /* Load SCSI command packet. */
        memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len);
index 71a46fcee8cc47d3b7e0cba5cf0aad80786f8d2b..42aa7a7c1a7313795fc4f30a9362f14740e7ce54 100644 (file)
@@ -402,9 +402,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                break;
 
        case MBA_LOOP_UP:               /* Loop Up Event */
-               ha->link_data_rate = 0;
                if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
                        link_speed = link_speeds[0];
+                       ha->link_data_rate = LDR_1GB;
                } else {
                        link_speed = link_speeds[LS_UNKNOWN];
                        if (mb[1] < 5)
@@ -436,7 +436,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                }
 
                ha->flags.management_server_logged_in = 0;
-               ha->link_data_rate = 0;
+               ha->link_data_rate = LDR_UNKNOWN;
                if (ql2xfdmienable)
                        set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
 
index 3099b379de9d89d554ebd1b5e9dde9d21fdb5d47..363dfdd042b08871c04e637fea9454978c52ea85 100644 (file)
@@ -7,7 +7,6 @@
 #include "qla_def.h"
 
 #include <linux/delay.h>
-#include <scsi/scsi_transport_fc.h>
 
 static void
 qla2x00_mbx_sem_timeout(unsigned long data)
@@ -1874,7 +1873,8 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma,
                mcp->mb[3] = LSW(id_list_dma);
                mcp->mb[6] = MSW(MSD(id_list_dma));
                mcp->mb[7] = LSW(MSD(id_list_dma));
-               mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2;
+               mcp->mb[8] = 0;
+               mcp->out_mb |= MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
        } else {
                mcp->mb[1] = MSW(id_list_dma);
                mcp->mb[2] = LSW(id_list_dma);
@@ -2017,8 +2017,109 @@ qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map)
 
        return rval;
 }
+#endif
+
+/*
+ * qla2x00_get_link_status
+ *
+ * Input:
+ *     ha = adapter block pointer.
+ *     loop_id = device loop ID.
+ *     ret_buf = pointer to link status return buffer.
+ *
+ * Returns:
+ *     0 = success.
+ *     BIT_0 = mem alloc error.
+ *     BIT_1 = mailbox error.
+ */
+int
+qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id,
+    link_stat_t *ret_buf, uint16_t *status)
+{
+       int rval;
+       mbx_cmd_t mc;
+       mbx_cmd_t *mcp = &mc;
+       link_stat_t *stat_buf;
+       dma_addr_t stat_buf_dma;
+
+       DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
+
+       stat_buf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &stat_buf_dma);
+       if (stat_buf == NULL) {
+               DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n",
+                   __func__, ha->host_no));
+               return BIT_0;
+       }
+       memset(stat_buf, 0, sizeof(link_stat_t));
+
+       mcp->mb[0] = MBC_GET_LINK_STATUS;
+       mcp->mb[2] = MSW(stat_buf_dma);
+       mcp->mb[3] = LSW(stat_buf_dma);
+       mcp->mb[6] = MSW(MSD(stat_buf_dma));
+       mcp->mb[7] = LSW(MSD(stat_buf_dma));
+       mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
+       mcp->in_mb = MBX_0;
+       if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+               mcp->mb[1] = loop_id;
+               mcp->mb[4] = 0;
+               mcp->mb[10] = 0;
+               mcp->out_mb |= MBX_10|MBX_4|MBX_1;
+               mcp->in_mb |= MBX_1;
+       } else if (HAS_EXTENDED_IDS(ha)) {
+               mcp->mb[1] = loop_id;
+               mcp->mb[10] = 0;
+               mcp->out_mb |= MBX_10|MBX_1;
+       } else {
+               mcp->mb[1] = loop_id << 8;
+               mcp->out_mb |= MBX_1;
+       }
+       mcp->tov = 30;
+       mcp->flags = IOCTL_CMD;
+       rval = qla2x00_mailbox_command(ha, mcp);
+
+       if (rval == QLA_SUCCESS) {
+               if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
+                       DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n",
+                           __func__, ha->host_no, mcp->mb[0]);)
+                       status[0] = mcp->mb[0];
+                       rval = BIT_1;
+               } else {
+                       /* copy over data -- firmware data is LE. */
+                       ret_buf->link_fail_cnt =
+                           le32_to_cpu(stat_buf->link_fail_cnt);
+                       ret_buf->loss_sync_cnt =
+                           le32_to_cpu(stat_buf->loss_sync_cnt);
+                       ret_buf->loss_sig_cnt =
+                           le32_to_cpu(stat_buf->loss_sig_cnt);
+                       ret_buf->prim_seq_err_cnt =
+                           le32_to_cpu(stat_buf->prim_seq_err_cnt);
+                       ret_buf->inval_xmit_word_cnt =
+                           le32_to_cpu(stat_buf->inval_xmit_word_cnt);
+                       ret_buf->inval_crc_cnt =
+                           le32_to_cpu(stat_buf->inval_crc_cnt);
+
+                       DEBUG11(printk("%s(%ld): stat dump: fail_cnt=%d "
+                           "loss_sync=%d loss_sig=%d seq_err=%d "
+                           "inval_xmt_word=%d inval_crc=%d.\n", __func__,
+                           ha->host_no, stat_buf->link_fail_cnt,
+                           stat_buf->loss_sync_cnt, stat_buf->loss_sig_cnt,
+                           stat_buf->prim_seq_err_cnt,
+                           stat_buf->inval_xmit_word_cnt,
+                           stat_buf->inval_crc_cnt);)
+               }
+       } else {
+               /* Failed. */
+               DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
+                   ha->host_no, rval);)
+               rval = BIT_1;
+       }
+
+       dma_pool_free(ha->s_dma_pool, stat_buf, stat_buf_dma);
 
-uint8_t
+       return rval;
+}
+
+int
 qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords,
     uint16_t *status)
 {
@@ -2080,7 +2181,6 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords,
 
        return rval;
 }
-#endif
 
 int
 qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp)
index 5866a7c706a82d627e71f597fe89970eb493d10f..9f91f1a20542cde30379643072d127cc873a9c6a 100644 (file)
@@ -366,6 +366,12 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
                goto qc_fail_command;
        }
 
+       /* Close window on fcport/rport state-transitioning. */
+       if (!*(fc_port_t **)rport->dd_data) {
+               cmd->result = DID_IMM_RETRY << 16;
+               goto qc_fail_command;
+       }
+
        if (atomic_read(&fcport->state) != FCS_ONLINE) {
                if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
                    atomic_read(&ha->loop_state) == LOOP_DEAD) {
@@ -421,6 +427,12 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
                goto qc24_fail_command;
        }
 
+       /* Close window on fcport/rport state-transitioning. */
+       if (!*(fc_port_t **)rport->dd_data) {
+               cmd->result = DID_IMM_RETRY << 16;
+               goto qc24_fail_command;
+       }
+
        if (atomic_read(&fcport->state) != FCS_ONLINE) {
                if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
                    atomic_read(&ha->loop_state) == LOOP_DEAD) {
@@ -513,7 +525,7 @@ qla2x00_eh_wait_on_command(scsi_qla_host_t *ha, struct scsi_cmnd *cmd)
  *    Success (Adapter is online) : 0
  *    Failed  (Adapter is offline/disabled) : 1
  */
-static int
+int
 qla2x00_wait_for_hba_online(scsi_qla_host_t *ha)
 {
        int             return_status;
@@ -1312,6 +1324,8 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
        ha->ports = MAX_BUSES;
        ha->init_cb_size = sizeof(init_cb_t);
        ha->mgmt_svr_loop_id = MANAGEMENT_SERVER;
+       ha->link_data_rate = LDR_UNKNOWN;
+       ha->optrom_size = OPTROM_SIZE_2300;
 
        /* Assign ISP specific operations. */
        ha->isp_ops.pci_config          = qla2100_pci_config;
@@ -1339,6 +1353,8 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
        ha->isp_ops.write_nvram         = qla2x00_write_nvram_data;
        ha->isp_ops.fw_dump             = qla2100_fw_dump;
        ha->isp_ops.ascii_fw_dump       = qla2100_ascii_fw_dump;
+       ha->isp_ops.read_optrom         = qla2x00_read_optrom_data;
+       ha->isp_ops.write_optrom        = qla2x00_write_optrom_data;
        if (IS_QLA2100(ha)) {
                host->max_id = MAX_TARGETS_2100;
                ha->mbx_count = MAILBOX_REGISTER_COUNT_2100;
@@ -1364,7 +1380,12 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
                ha->isp_ops.intr_handler = qla2300_intr_handler;
                ha->isp_ops.fw_dump = qla2300_fw_dump;
                ha->isp_ops.ascii_fw_dump = qla2300_ascii_fw_dump;
+               ha->isp_ops.beacon_on = qla2x00_beacon_on;
+               ha->isp_ops.beacon_off = qla2x00_beacon_off;
+               ha->isp_ops.beacon_blink = qla2x00_beacon_blink;
                ha->gid_list_info_size = 6;
+               if (IS_QLA2322(ha) || IS_QLA6322(ha))
+                       ha->optrom_size = OPTROM_SIZE_2322;
        } else if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
                host->max_id = MAX_TARGETS_2200;
                ha->mbx_count = MAILBOX_REGISTER_COUNT;
@@ -1400,7 +1421,13 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
                ha->isp_ops.write_nvram = qla24xx_write_nvram_data;
                ha->isp_ops.fw_dump = qla24xx_fw_dump;
                ha->isp_ops.ascii_fw_dump = qla24xx_ascii_fw_dump;
+               ha->isp_ops.read_optrom = qla24xx_read_optrom_data;
+               ha->isp_ops.write_optrom = qla24xx_write_optrom_data;
+               ha->isp_ops.beacon_on = qla24xx_beacon_on;
+               ha->isp_ops.beacon_off = qla24xx_beacon_off;
+               ha->isp_ops.beacon_blink = qla24xx_beacon_blink;
                ha->gid_list_info_size = 8;
+               ha->optrom_size = OPTROM_SIZE_24XX;
        }
        host->can_queue = ha->request_q_length + 128;
 
@@ -1657,11 +1684,13 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport,
                spin_lock_irqsave(&fcport->rport_lock, flags);
                fcport->drport = rport;
                fcport->rport = NULL;
+               *(fc_port_t **)rport->dd_data = NULL;
                spin_unlock_irqrestore(&fcport->rport_lock, flags);
                set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags);
        } else {
                spin_lock_irqsave(&fcport->rport_lock, flags);
                fcport->rport = NULL;
+               *(fc_port_t **)rport->dd_data = NULL;
                spin_unlock_irqrestore(&fcport->rport_lock, flags);
                fc_remote_port_delete(rport);
        }
@@ -2066,6 +2095,8 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
        ha->fw_dumped = 0;
        ha->fw_dump_reading = 0;
        ha->fw_dump_buffer = NULL;
+
+       vfree(ha->optrom_buffer);
 }
 
 /*
@@ -2314,6 +2345,9 @@ qla2x00_do_dpc(void *data)
                if (!ha->interrupts_on)
                        ha->isp_ops.enable_intrs(ha);
 
+               if (test_and_clear_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags))
+                       ha->isp_ops.beacon_blink(ha);
+
                ha->dpc_active = 0;
        } /* End of while(1) */
 
@@ -2491,6 +2525,12 @@ qla2x00_timer(scsi_qla_host_t *ha)
                    atomic_read(&ha->loop_down_timer)));
        }
 
+       /* Check if beacon LED needs to be blinked */
+       if (ha->beacon_blink_led == 1) {
+               set_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags);
+               start_dpc++;
+       }
+
        /* Schedule the DPC routine if needed */
        if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
            test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
@@ -2499,6 +2539,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
            start_dpc ||
            test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
            test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
+           test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) ||
            test_bit(RELOGIN_NEEDED, &ha->dpc_flags)) &&
            ha->dpc_wait && !ha->dpc_active) {
 
index 2c3342108dd82219f311adc9644cd50acbc9a3eb..b70bebe18c0123458150e0e0031fa537edf0b05e 100644 (file)
@@ -6,8 +6,6 @@
  */
 #include "qla_def.h"
 
-#include <scsi/scsi_transport_fc.h>
-
 /**
  * IO descriptor handle definitions.
  *
index f4d755a643e44d985d0378b06e6c134930da531f..3866a5760f15b45966a2a3de8ebf40aaa88f9596 100644 (file)
@@ -695,3 +695,966 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
 
        return ret;
 }
+
+
+static inline void
+qla2x00_flip_colors(scsi_qla_host_t *ha, uint16_t *pflags)
+{
+       if (IS_QLA2322(ha)) {
+               /* Flip all colors. */
+               if (ha->beacon_color_state == QLA_LED_ALL_ON) {
+                       /* Turn off. */
+                       ha->beacon_color_state = 0;
+                       *pflags = GPIO_LED_ALL_OFF;
+               } else {
+                       /* Turn on. */
+                       ha->beacon_color_state = QLA_LED_ALL_ON;
+                       *pflags = GPIO_LED_RGA_ON;
+               }
+       } else {
+               /* Flip green led only. */
+               if (ha->beacon_color_state == QLA_LED_GRN_ON) {
+                       /* Turn off. */
+                       ha->beacon_color_state = 0;
+                       *pflags = GPIO_LED_GREEN_OFF_AMBER_OFF;
+               } else {
+                       /* Turn on. */
+                       ha->beacon_color_state = QLA_LED_GRN_ON;
+                       *pflags = GPIO_LED_GREEN_ON_AMBER_OFF;
+               }
+       }
+}
+
+void
+qla2x00_beacon_blink(struct scsi_qla_host *ha)
+{
+       uint16_t gpio_enable;
+       uint16_t gpio_data;
+       uint16_t led_color = 0;
+       unsigned long flags;
+       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+       if (ha->pio_address)
+               reg = (struct device_reg_2xxx __iomem *)ha->pio_address;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+
+       /* Save the Original GPIOE. */
+       if (ha->pio_address) {
+               gpio_enable = RD_REG_WORD_PIO(&reg->gpioe);
+               gpio_data = RD_REG_WORD_PIO(&reg->gpiod);
+       } else {
+               gpio_enable = RD_REG_WORD(&reg->gpioe);
+               gpio_data = RD_REG_WORD(&reg->gpiod);
+       }
+
+       /* Set the modified gpio_enable values */
+       gpio_enable |= GPIO_LED_MASK;
+
+       if (ha->pio_address) {
+               WRT_REG_WORD_PIO(&reg->gpioe, gpio_enable);
+       } else {
+               WRT_REG_WORD(&reg->gpioe, gpio_enable);
+               RD_REG_WORD(&reg->gpioe);
+       }
+
+       qla2x00_flip_colors(ha, &led_color);
+
+       /* Clear out any previously set LED color. */
+       gpio_data &= ~GPIO_LED_MASK;
+
+       /* Set the new input LED color to GPIOD. */
+       gpio_data |= led_color;
+
+       /* Set the modified gpio_data values */
+       if (ha->pio_address) {
+               WRT_REG_WORD_PIO(&reg->gpiod, gpio_data);
+       } else {
+               WRT_REG_WORD(&reg->gpiod, gpio_data);
+               RD_REG_WORD(&reg->gpiod);
+       }
+
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+int
+qla2x00_beacon_on(struct scsi_qla_host *ha)
+{
+       uint16_t gpio_enable;
+       uint16_t gpio_data;
+       unsigned long flags;
+       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+       ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING;
+       ha->fw_options[1] |= FO1_DISABLE_GPIO6_7;
+
+       if (qla2x00_set_fw_options(ha, ha->fw_options) != QLA_SUCCESS) {
+               qla_printk(KERN_WARNING, ha,
+                   "Unable to update fw options (beacon on).\n");
+               return QLA_FUNCTION_FAILED;
+       }
+
+       if (ha->pio_address)
+               reg = (struct device_reg_2xxx __iomem *)ha->pio_address;
+
+       /* Turn off LEDs. */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       if (ha->pio_address) {
+               gpio_enable = RD_REG_WORD_PIO(&reg->gpioe);
+               gpio_data = RD_REG_WORD_PIO(&reg->gpiod);
+       } else {
+               gpio_enable = RD_REG_WORD(&reg->gpioe);
+               gpio_data = RD_REG_WORD(&reg->gpiod);
+       }
+       gpio_enable |= GPIO_LED_MASK;
+
+       /* Set the modified gpio_enable values. */
+       if (ha->pio_address) {
+               WRT_REG_WORD_PIO(&reg->gpioe, gpio_enable);
+       } else {
+               WRT_REG_WORD(&reg->gpioe, gpio_enable);
+               RD_REG_WORD(&reg->gpioe);
+       }
+
+       /* Clear out previously set LED colour. */
+       gpio_data &= ~GPIO_LED_MASK;
+       if (ha->pio_address) {
+               WRT_REG_WORD_PIO(&reg->gpiod, gpio_data);
+       } else {
+               WRT_REG_WORD(&reg->gpiod, gpio_data);
+               RD_REG_WORD(&reg->gpiod);
+       }
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       /*
+        * Let the per HBA timer kick off the blinking process based on
+        * the following flags. No need to do anything else now.
+        */
+       ha->beacon_blink_led = 1;
+       ha->beacon_color_state = 0;
+
+       return QLA_SUCCESS;
+}
+
+int
+qla2x00_beacon_off(struct scsi_qla_host *ha)
+{
+       int rval = QLA_SUCCESS;
+
+       ha->beacon_blink_led = 0;
+
+       /* Set the on flag so when it gets flipped it will be off. */
+       if (IS_QLA2322(ha))
+               ha->beacon_color_state = QLA_LED_ALL_ON;
+       else
+               ha->beacon_color_state = QLA_LED_GRN_ON;
+
+       ha->isp_ops.beacon_blink(ha);   /* This turns green LED off */
+
+       ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING;
+       ha->fw_options[1] &= ~FO1_DISABLE_GPIO6_7;
+
+       rval = qla2x00_set_fw_options(ha, ha->fw_options);
+       if (rval != QLA_SUCCESS)
+               qla_printk(KERN_WARNING, ha,
+                   "Unable to update fw options (beacon off).\n");
+       return rval;
+}
+
+
+static inline void
+qla24xx_flip_colors(scsi_qla_host_t *ha, uint16_t *pflags)
+{
+       /* Flip all colors. */
+       if (ha->beacon_color_state == QLA_LED_ALL_ON) {
+               /* Turn off. */
+               ha->beacon_color_state = 0;
+               *pflags = 0;
+       } else {
+               /* Turn on. */
+               ha->beacon_color_state = QLA_LED_ALL_ON;
+               *pflags = GPDX_LED_YELLOW_ON | GPDX_LED_AMBER_ON;
+       }
+}
+
+void
+qla24xx_beacon_blink(struct scsi_qla_host *ha)
+{
+       uint16_t led_color = 0;
+       uint32_t gpio_data;
+       unsigned long flags;
+       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+       /* Save the Original GPIOD. */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       gpio_data = RD_REG_DWORD(&reg->gpiod);
+
+       /* Enable the gpio_data reg for update. */
+       gpio_data |= GPDX_LED_UPDATE_MASK;
+
+       WRT_REG_DWORD(&reg->gpiod, gpio_data);
+       gpio_data = RD_REG_DWORD(&reg->gpiod);
+
+       /* Set the color bits. */
+       qla24xx_flip_colors(ha, &led_color);
+
+       /* Clear out any previously set LED color. */
+       gpio_data &= ~GPDX_LED_COLOR_MASK;
+
+       /* Set the new input LED color to GPIOD. */
+       gpio_data |= led_color;
+
+       /* Set the modified gpio_data values. */
+       WRT_REG_DWORD(&reg->gpiod, gpio_data);
+       gpio_data = RD_REG_DWORD(&reg->gpiod);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+int
+qla24xx_beacon_on(struct scsi_qla_host *ha)
+{
+       uint32_t gpio_data;
+       unsigned long flags;
+       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+       if (ha->beacon_blink_led == 0) {
+               /* Enable firmware for update */
+               ha->fw_options[1] |= ADD_FO1_DISABLE_GPIO_LED_CTRL;
+
+               if (qla2x00_set_fw_options(ha, ha->fw_options) != QLA_SUCCESS)
+                       return QLA_FUNCTION_FAILED;
+
+               if (qla2x00_get_fw_options(ha, ha->fw_options) !=
+                   QLA_SUCCESS) {
+                       qla_printk(KERN_WARNING, ha,
+                           "Unable to update fw options (beacon on).\n");
+                       return QLA_FUNCTION_FAILED;
+               }
+
+               spin_lock_irqsave(&ha->hardware_lock, flags);
+               gpio_data = RD_REG_DWORD(&reg->gpiod);
+
+               /* Enable the gpio_data reg for update. */
+               gpio_data |= GPDX_LED_UPDATE_MASK;
+               WRT_REG_DWORD(&reg->gpiod, gpio_data);
+               RD_REG_DWORD(&reg->gpiod);
+
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       }
+
+       /* So all colors blink together. */
+       ha->beacon_color_state = 0;
+
+       /* Let the per HBA timer kick off the blinking process. */
+       ha->beacon_blink_led = 1;
+
+       return QLA_SUCCESS;
+}
+
+int
+qla24xx_beacon_off(struct scsi_qla_host *ha)
+{
+       uint32_t gpio_data;
+       unsigned long flags;
+       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+       ha->beacon_blink_led = 0;
+       ha->beacon_color_state = QLA_LED_ALL_ON;
+
+       ha->isp_ops.beacon_blink(ha);   /* Will flip to all off. */
+
+       /* Give control back to firmware. */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       gpio_data = RD_REG_DWORD(&reg->gpiod);
+
+       /* Disable the gpio_data reg for update. */
+       gpio_data &= ~GPDX_LED_UPDATE_MASK;
+       WRT_REG_DWORD(&reg->gpiod, gpio_data);
+       RD_REG_DWORD(&reg->gpiod);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       ha->fw_options[1] &= ~ADD_FO1_DISABLE_GPIO_LED_CTRL;
+
+       if (qla2x00_set_fw_options(ha, ha->fw_options) != QLA_SUCCESS) {
+               qla_printk(KERN_WARNING, ha,
+                   "Unable to update fw options (beacon off).\n");
+               return QLA_FUNCTION_FAILED;
+       }
+
+       if (qla2x00_get_fw_options(ha, ha->fw_options) != QLA_SUCCESS) {
+               qla_printk(KERN_WARNING, ha,
+                   "Unable to get fw options (beacon off).\n");
+               return QLA_FUNCTION_FAILED;
+       }
+
+       return QLA_SUCCESS;
+}
+
+
+/*
+ * Flash support routines
+ */
+
+/**
+ * qla2x00_flash_enable() - Setup flash for reading and writing.
+ * @ha: HA context
+ */
+static void
+qla2x00_flash_enable(scsi_qla_host_t *ha)
+{
+       uint16_t data;
+       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+       data = RD_REG_WORD(&reg->ctrl_status);
+       data |= CSR_FLASH_ENABLE;
+       WRT_REG_WORD(&reg->ctrl_status, data);
+       RD_REG_WORD(&reg->ctrl_status);         /* PCI Posting. */
+}
+
+/**
+ * qla2x00_flash_disable() - Disable flash and allow RISC to run.
+ * @ha: HA context
+ */
+static void
+qla2x00_flash_disable(scsi_qla_host_t *ha)
+{
+       uint16_t data;
+       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+       data = RD_REG_WORD(&reg->ctrl_status);
+       data &= ~(CSR_FLASH_ENABLE);
+       WRT_REG_WORD(&reg->ctrl_status, data);
+       RD_REG_WORD(&reg->ctrl_status);         /* PCI Posting. */
+}
+
+/**
+ * qla2x00_read_flash_byte() - Reads a byte from flash
+ * @ha: HA context
+ * @addr: Address in flash to read
+ *
+ * A word is read from the chip, but, only the lower byte is valid.
+ *
+ * Returns the byte read from flash @addr.
+ */
+static uint8_t
+qla2x00_read_flash_byte(scsi_qla_host_t *ha, uint32_t addr)
+{
+       uint16_t data;
+       uint16_t bank_select;
+       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+       bank_select = RD_REG_WORD(&reg->ctrl_status);
+
+       if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
+               /* Specify 64K address range: */
+               /*  clear out Module Select and Flash Address bits [19:16]. */
+               bank_select &= ~0xf8;
+               bank_select |= addr >> 12 & 0xf0;
+               bank_select |= CSR_FLASH_64K_BANK;
+               WRT_REG_WORD(&reg->ctrl_status, bank_select);
+               RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
+
+               WRT_REG_WORD(&reg->flash_address, (uint16_t)addr);
+               data = RD_REG_WORD(&reg->flash_data);
+
+               return (uint8_t)data;
+       }
+
+       /* Setup bit 16 of flash address. */
+       if ((addr & BIT_16) && ((bank_select & CSR_FLASH_64K_BANK) == 0)) {
+               bank_select |= CSR_FLASH_64K_BANK;
+               WRT_REG_WORD(&reg->ctrl_status, bank_select);
+               RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
+       } else if (((addr & BIT_16) == 0) &&
+           (bank_select & CSR_FLASH_64K_BANK)) {
+               bank_select &= ~(CSR_FLASH_64K_BANK);
+               WRT_REG_WORD(&reg->ctrl_status, bank_select);
+               RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
+       }
+
+       /* Always perform IO mapped accesses to the FLASH registers. */
+       if (ha->pio_address) {
+               uint16_t data2;
+
+               reg = (struct device_reg_2xxx __iomem *)ha->pio_address;
+               WRT_REG_WORD_PIO(&reg->flash_address, (uint16_t)addr);
+               do {
+                       data = RD_REG_WORD_PIO(&reg->flash_data);
+                       barrier();
+                       cpu_relax();
+                       data2 = RD_REG_WORD_PIO(&reg->flash_data);
+               } while (data != data2);
+       } else {
+               WRT_REG_WORD(&reg->flash_address, (uint16_t)addr);
+               data = qla2x00_debounce_register(&reg->flash_data);
+       }
+
+       return (uint8_t)data;
+}
+
+/**
+ * qla2x00_write_flash_byte() - Write a byte to flash
+ * @ha: HA context
+ * @addr: Address in flash to write
+ * @data: Data to write
+ */
+static void
+qla2x00_write_flash_byte(scsi_qla_host_t *ha, uint32_t addr, uint8_t data)
+{
+       uint16_t bank_select;
+       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+       bank_select = RD_REG_WORD(&reg->ctrl_status);
+       if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
+               /* Specify 64K address range: */
+               /*  clear out Module Select and Flash Address bits [19:16]. */
+               bank_select &= ~0xf8;
+               bank_select |= addr >> 12 & 0xf0;
+               bank_select |= CSR_FLASH_64K_BANK;
+               WRT_REG_WORD(&reg->ctrl_status, bank_select);
+               RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
+
+               WRT_REG_WORD(&reg->flash_address, (uint16_t)addr);
+               RD_REG_WORD(&reg->ctrl_status);         /* PCI Posting. */
+               WRT_REG_WORD(&reg->flash_data, (uint16_t)data);
+               RD_REG_WORD(&reg->ctrl_status);         /* PCI Posting. */
+
+               return;
+       }
+
+       /* Setup bit 16 of flash address. */
+       if ((addr & BIT_16) && ((bank_select & CSR_FLASH_64K_BANK) == 0)) {
+               bank_select |= CSR_FLASH_64K_BANK;
+               WRT_REG_WORD(&reg->ctrl_status, bank_select);
+               RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
+       } else if (((addr & BIT_16) == 0) &&
+           (bank_select & CSR_FLASH_64K_BANK)) {
+               bank_select &= ~(CSR_FLASH_64K_BANK);
+               WRT_REG_WORD(&reg->ctrl_status, bank_select);
+               RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
+       }
+
+       /* Always perform IO mapped accesses to the FLASH registers. */
+       if (ha->pio_address) {
+               reg = (struct device_reg_2xxx __iomem *)ha->pio_address;
+               WRT_REG_WORD_PIO(&reg->flash_address, (uint16_t)addr);
+               WRT_REG_WORD_PIO(&reg->flash_data, (uint16_t)data);
+       } else {
+               WRT_REG_WORD(&reg->flash_address, (uint16_t)addr);
+               RD_REG_WORD(&reg->ctrl_status);         /* PCI Posting. */
+               WRT_REG_WORD(&reg->flash_data, (uint16_t)data);
+               RD_REG_WORD(&reg->ctrl_status);         /* PCI Posting. */
+       }
+}
+
+/**
+ * qla2x00_poll_flash() - Polls flash for completion.
+ * @ha: HA context
+ * @addr: Address in flash to poll
+ * @poll_data: Data to be polled
+ * @man_id: Flash manufacturer ID
+ * @flash_id: Flash ID
+ *
+ * This function polls the device until bit 7 of what is read matches data
+ * bit 7 or until data bit 5 becomes a 1.  If that hapens, the flash ROM timed
+ * out (a fatal error).  The flash book recommeds reading bit 7 again after
+ * reading bit 5 as a 1.
+ *
+ * Returns 0 on success, else non-zero.
+ */
+static int
+qla2x00_poll_flash(scsi_qla_host_t *ha, uint32_t addr, uint8_t poll_data,
+    uint8_t man_id, uint8_t flash_id)
+{
+       int status;
+       uint8_t flash_data;
+       uint32_t cnt;
+
+       status = 1;
+
+       /* Wait for 30 seconds for command to finish. */
+       poll_data &= BIT_7;
+       for (cnt = 3000000; cnt; cnt--) {
+               flash_data = qla2x00_read_flash_byte(ha, addr);
+               if ((flash_data & BIT_7) == poll_data) {
+                       status = 0;
+                       break;
+               }
+
+               if (man_id != 0x40 && man_id != 0xda) {
+                       if ((flash_data & BIT_5) && cnt > 2)
+                               cnt = 2;
+               }
+               udelay(10);
+               barrier();
+       }
+       return status;
+}
+
+#define IS_OEM_001(ha) \
+       ((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2322 && \
+        (ha)->pdev->subsystem_vendor == 0x1028 && \
+        (ha)->pdev->subsystem_device == 0x0170)
+
+/**
+ * qla2x00_program_flash_address() - Programs a flash address
+ * @ha: HA context
+ * @addr: Address in flash to program
+ * @data: Data to be written in flash
+ * @man_id: Flash manufacturer ID
+ * @flash_id: Flash ID
+ *
+ * Returns 0 on success, else non-zero.
+ */
+static int
+qla2x00_program_flash_address(scsi_qla_host_t *ha, uint32_t addr, uint8_t data,
+    uint8_t man_id, uint8_t flash_id)
+{
+       /* Write Program Command Sequence. */
+       if (IS_OEM_001(ha)) {
+               qla2x00_write_flash_byte(ha, 0xaaa, 0xaa);
+               qla2x00_write_flash_byte(ha, 0x555, 0x55);
+               qla2x00_write_flash_byte(ha, 0xaaa, 0xa0);
+               qla2x00_write_flash_byte(ha, addr, data);
+       } else {
+               if (man_id == 0xda && flash_id == 0xc1) {
+                       qla2x00_write_flash_byte(ha, addr, data);
+                       if (addr & 0x7e)
+                               return 0;
+               } else {
+                       qla2x00_write_flash_byte(ha, 0x5555, 0xaa);
+                       qla2x00_write_flash_byte(ha, 0x2aaa, 0x55);
+                       qla2x00_write_flash_byte(ha, 0x5555, 0xa0);
+                       qla2x00_write_flash_byte(ha, addr, data);
+               }
+       }
+
+       udelay(150);
+
+       /* Wait for write to complete. */
+       return qla2x00_poll_flash(ha, addr, data, man_id, flash_id);
+}
+
+/**
+ * qla2x00_erase_flash() - Erase the flash.
+ * @ha: HA context
+ * @man_id: Flash manufacturer ID
+ * @flash_id: Flash ID
+ *
+ * Returns 0 on success, else non-zero.
+ */
+static int
+qla2x00_erase_flash(scsi_qla_host_t *ha, uint8_t man_id, uint8_t flash_id)
+{
+       /* Individual Sector Erase Command Sequence */
+       if (IS_OEM_001(ha)) {
+               qla2x00_write_flash_byte(ha, 0xaaa, 0xaa);
+               qla2x00_write_flash_byte(ha, 0x555, 0x55);
+               qla2x00_write_flash_byte(ha, 0xaaa, 0x80);
+               qla2x00_write_flash_byte(ha, 0xaaa, 0xaa);
+               qla2x00_write_flash_byte(ha, 0x555, 0x55);
+               qla2x00_write_flash_byte(ha, 0xaaa, 0x10);
+       } else {
+               qla2x00_write_flash_byte(ha, 0x5555, 0xaa);
+               qla2x00_write_flash_byte(ha, 0x2aaa, 0x55);
+               qla2x00_write_flash_byte(ha, 0x5555, 0x80);
+               qla2x00_write_flash_byte(ha, 0x5555, 0xaa);
+               qla2x00_write_flash_byte(ha, 0x2aaa, 0x55);
+               qla2x00_write_flash_byte(ha, 0x5555, 0x10);
+       }
+
+       udelay(150);
+
+       /* Wait for erase to complete. */
+       return qla2x00_poll_flash(ha, 0x00, 0x80, man_id, flash_id);
+}
+
+/**
+ * qla2x00_erase_flash_sector() - Erase a flash sector.
+ * @ha: HA context
+ * @addr: Flash sector to erase
+ * @sec_mask: Sector address mask
+ * @man_id: Flash manufacturer ID
+ * @flash_id: Flash ID
+ *
+ * Returns 0 on success, else non-zero.
+ */
+static int
+qla2x00_erase_flash_sector(scsi_qla_host_t *ha, uint32_t addr,
+    uint32_t sec_mask, uint8_t man_id, uint8_t flash_id)
+{
+       /* Individual Sector Erase Command Sequence */
+       qla2x00_write_flash_byte(ha, 0x5555, 0xaa);
+       qla2x00_write_flash_byte(ha, 0x2aaa, 0x55);
+       qla2x00_write_flash_byte(ha, 0x5555, 0x80);
+       qla2x00_write_flash_byte(ha, 0x5555, 0xaa);
+       qla2x00_write_flash_byte(ha, 0x2aaa, 0x55);
+       if (man_id == 0x1f && flash_id == 0x13)
+               qla2x00_write_flash_byte(ha, addr & sec_mask, 0x10);
+       else
+               qla2x00_write_flash_byte(ha, addr & sec_mask, 0x30);
+
+       udelay(150);
+
+       /* Wait for erase to complete. */
+       return qla2x00_poll_flash(ha, addr, 0x80, man_id, flash_id);
+}
+
+/**
+ * qla2x00_get_flash_manufacturer() - Read manufacturer ID from flash chip.
+ * @man_id: Flash manufacturer ID
+ * @flash_id: Flash ID
+ */
+static void
+qla2x00_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id,
+    uint8_t *flash_id)
+{
+       qla2x00_write_flash_byte(ha, 0x5555, 0xaa);
+       qla2x00_write_flash_byte(ha, 0x2aaa, 0x55);
+       qla2x00_write_flash_byte(ha, 0x5555, 0x90);
+       *man_id = qla2x00_read_flash_byte(ha, 0x0000);
+       *flash_id = qla2x00_read_flash_byte(ha, 0x0001);
+       qla2x00_write_flash_byte(ha, 0x5555, 0xaa);
+       qla2x00_write_flash_byte(ha, 0x2aaa, 0x55);
+       qla2x00_write_flash_byte(ha, 0x5555, 0xf0);
+}
+
+
+static inline void
+qla2x00_suspend_hba(struct scsi_qla_host *ha)
+{
+       int cnt;
+       unsigned long flags;
+       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+       /* Suspend HBA. */
+       scsi_block_requests(ha->host);
+       ha->isp_ops.disable_intrs(ha);
+       set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
+
+       /* Pause RISC. */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
+       RD_REG_WORD(&reg->hccr);
+       if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) {
+               for (cnt = 0; cnt < 30000; cnt++) {
+                       if ((RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) != 0)
+                               break;
+                       udelay(100);
+               }
+       } else {
+               udelay(10);
+       }
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+static inline void
+qla2x00_resume_hba(struct scsi_qla_host *ha)
+{
+       /* Resume HBA. */
+       clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
+       set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+       up(ha->dpc_wait);
+       qla2x00_wait_for_hba_online(ha);
+       scsi_unblock_requests(ha->host);
+}
+
+uint8_t *
+qla2x00_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
+    uint32_t offset, uint32_t length)
+{
+       unsigned long flags;
+       uint32_t addr, midpoint;
+       uint8_t *data;
+       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+       /* Suspend HBA. */
+       qla2x00_suspend_hba(ha);
+
+       /* Go with read. */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       midpoint = ha->optrom_size / 2;
+
+       qla2x00_flash_enable(ha);
+       WRT_REG_WORD(&reg->nvram, 0);
+       RD_REG_WORD(&reg->nvram);               /* PCI Posting. */
+       for (addr = offset, data = buf; addr < length; addr++, data++) {
+               if (addr == midpoint) {
+                       WRT_REG_WORD(&reg->nvram, NVR_SELECT);
+                       RD_REG_WORD(&reg->nvram);       /* PCI Posting. */
+               }
+
+               *data = qla2x00_read_flash_byte(ha, addr);
+       }
+       qla2x00_flash_disable(ha);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       /* Resume HBA. */
+       qla2x00_resume_hba(ha);
+
+       return buf;
+}
+
+int
+qla2x00_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
+    uint32_t offset, uint32_t length)
+{
+
+       int rval;
+       unsigned long flags;
+       uint8_t man_id, flash_id, sec_number, data;
+       uint16_t wd;
+       uint32_t addr, liter, sec_mask, rest_addr;
+       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+       /* Suspend HBA. */
+       qla2x00_suspend_hba(ha);
+
+       rval = QLA_SUCCESS;
+       sec_number = 0;
+
+       /* Reset ISP chip. */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
+       pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
+
+       /* Go with write. */
+       qla2x00_flash_enable(ha);
+       do {    /* Loop once to provide quick error exit */
+               /* Structure of flash memory based on manufacturer */
+               if (IS_OEM_001(ha)) {
+                       /* OEM variant with special flash part. */
+                       man_id = flash_id = 0;
+                       rest_addr = 0xffff;
+                       sec_mask   = 0x10000;
+                       goto update_flash;
+               }
+               qla2x00_get_flash_manufacturer(ha, &man_id, &flash_id);
+               switch (man_id) {
+               case 0x20: /* ST flash. */
+                       if (flash_id == 0xd2 || flash_id == 0xe3) {
+                               /*
+                                * ST m29w008at part - 64kb sector size with
+                                * 32kb,8kb,8kb,16kb sectors at memory address
+                                * 0xf0000.
+                                */
+                               rest_addr = 0xffff;
+                               sec_mask = 0x10000;
+                               break;   
+                       }
+                       /*
+                        * ST m29w010b part - 16kb sector size
+                        * Default to 16kb sectors
+                        */
+                       rest_addr = 0x3fff;
+                       sec_mask = 0x1c000;
+                       break;
+               case 0x40: /* Mostel flash. */
+                       /* Mostel v29c51001 part - 512 byte sector size. */
+                       rest_addr = 0x1ff;
+                       sec_mask = 0x1fe00;
+                       break;
+               case 0xbf: /* SST flash. */
+                       /* SST39sf10 part - 4kb sector size. */
+                       rest_addr = 0xfff;
+                       sec_mask = 0x1f000;
+                       break;
+               case 0xda: /* Winbond flash. */
+                       /* Winbond W29EE011 part - 256 byte sector size. */
+                       rest_addr = 0x7f;
+                       sec_mask = 0x1ff80;
+                       break;
+               case 0xc2: /* Macronix flash. */
+                       /* 64k sector size. */
+                       if (flash_id == 0x38 || flash_id == 0x4f) {
+                               rest_addr = 0xffff;
+                               sec_mask = 0x10000;
+                               break;
+                       }
+                       /* Fall through... */
+
+               case 0x1f: /* Atmel flash. */
+                       /* 512k sector size. */
+                       if (flash_id == 0x13) {
+                               rest_addr = 0x7fffffff;
+                               sec_mask =   0x80000000;
+                               break;
+                       }
+                       /* Fall through... */
+
+               case 0x01: /* AMD flash. */
+                       if (flash_id == 0x38 || flash_id == 0x40 ||
+                           flash_id == 0x4f) {
+                               /* Am29LV081 part - 64kb sector size. */
+                               /* Am29LV002BT part - 64kb sector size. */
+                               rest_addr = 0xffff;
+                               sec_mask = 0x10000;
+                               break;
+                       } else if (flash_id == 0x3e) {
+                               /*
+                                * Am29LV008b part - 64kb sector size with
+                                * 32kb,8kb,8kb,16kb sector at memory address
+                                * h0xf0000.
+                                */
+                               rest_addr = 0xffff;
+                               sec_mask = 0x10000;
+                               break;
+                       } else if (flash_id == 0x20 || flash_id == 0x6e) {
+                               /*
+                                * Am29LV010 part or AM29f010 - 16kb sector
+                                * size.
+                                */
+                               rest_addr = 0x3fff;
+                               sec_mask = 0x1c000;
+                               break;
+                       } else if (flash_id == 0x6d) {
+                               /* Am29LV001 part - 8kb sector size. */
+                               rest_addr = 0x1fff;
+                               sec_mask = 0x1e000;
+                               break;
+                       }
+               default:
+                       /* Default to 16 kb sector size. */
+                       rest_addr = 0x3fff;
+                       sec_mask = 0x1c000;
+                       break;
+               }
+
+update_flash:
+               if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
+                       if (qla2x00_erase_flash(ha, man_id, flash_id)) {
+                               rval = QLA_FUNCTION_FAILED;
+                               break;
+                       }
+               }
+
+               for (addr = offset, liter = 0; liter < length; liter++,
+                   addr++) {
+                       data = buf[liter];
+                       /* Are we at the beginning of a sector? */
+                       if ((addr & rest_addr) == 0) {
+                               if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
+                                       if (addr >= 0x10000UL) {
+                                               if (((addr >> 12) & 0xf0) &&
+                                                   ((man_id == 0x01 &&
+                                                       flash_id == 0x3e) ||
+                                                    (man_id == 0x20 &&
+                                                        flash_id == 0xd2))) {
+                                                       sec_number++;
+                                                       if (sec_number == 1) {
+                                                               rest_addr =
+                                                                   0x7fff;
+                                                               sec_mask =
+                                                                   0x18000;
+                                                       } else if (
+                                                           sec_number == 2 ||
+                                                           sec_number == 3) {
+                                                               rest_addr =
+                                                                   0x1fff;
+                                                               sec_mask =
+                                                                   0x1e000;
+                                                       } else if (
+                                                           sec_number == 4) {
+                                                               rest_addr =
+                                                                   0x3fff;
+                                                               sec_mask =
+                                                                   0x1c000;
+                                                       }
+                                               }
+                                       }
+                               } else if (addr == ha->optrom_size / 2) {
+                                       WRT_REG_WORD(&reg->nvram, NVR_SELECT);
+                                       RD_REG_WORD(&reg->nvram);
+                               }
+
+                               if (flash_id == 0xda && man_id == 0xc1) {
+                                       qla2x00_write_flash_byte(ha, 0x5555,
+                                           0xaa);
+                               &nbs