Misc. changes for hardware support, from various sources. --- arch/i386/config.in | 57 arch/i386/kernel/setup.c | 71 drivers/ide/Config.in | 1 drivers/ide/pci/Makefile | 1 drivers/ide/pci/cs5535.c | 452 ++++++ drivers/ide/pci/cs5535.h | 75 + drivers/isdn/hisax/config.c | 8 drivers/isdn/hisax/gazel.c | 6 drivers/isdn/isdn_common.c | 4 drivers/isdn/isdn_net.c | 11 drivers/isdn/isdn_ppp.c | 3 drivers/scsi/aacraid/CHANGELOG | 1606 +++++++++++++++++++++ drivers/scsi/aacraid/Makefile | 136 + drivers/scsi/aacraid/README | 39 drivers/scsi/aacraid/TODO | 5 drivers/scsi/aacraid/aachba.c | 2989 +++++++++++++++++++++++++++++++--------- drivers/scsi/aacraid/aacraid.h | 1199 +++++++++++----- drivers/scsi/aacraid/commctrl.c | 602 ++++++-- drivers/scsi/aacraid/comminit.c | 233 ++- drivers/scsi/aacraid/commsup.c | 1611 +++++++++++++++++---- drivers/scsi/aacraid/compat.h | 256 +++ drivers/scsi/aacraid/csmi.c | 1686 ++++++++++++++++++++++ drivers/scsi/aacraid/csmi.h | 402 +++++ drivers/scsi/aacraid/dpcsup.c | 199 ++ drivers/scsi/aacraid/fwdebug.c | 343 ++++ drivers/scsi/aacraid/fwdebug.h | 51 drivers/scsi/aacraid/linit.c | 2402 +++++++++++++++++++++++++------- drivers/scsi/aacraid/rkt.c | 538 +++++++ drivers/scsi/aacraid/rx.c | 401 +++-- drivers/scsi/aacraid/sa.c | 243 +-- include/asm-i386/msr.h | 8 include/linux/pci_ids.h | 2 32 files changed, 13385 insertions(+), 2255 deletions(-) diff --git a/arch/i386/config.in b/arch/i386/config.in index 6838057..8bc0034 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -42,6 +42,8 @@ choice 'Processor family' \ Winchip-C6 CONFIG_MWINCHIPC6 \ Winchip-2 CONFIG_MWINCHIP2 \ Winchip-2A/Winchip-3 CONFIG_MWINCHIP3D \ + Geode-GX1/SC1200 CONFIG_GEODE_SC1200 \ + Geode-GX2/GX3 CONFIG_GEODE_GX2 \ CyrixIII/VIA-C3 CONFIG_MCYRIXIII \ VIA-C3-2 CONFIG_MVIAC3_2" Pentium-Pro # @@ -139,9 +141,31 @@ if [ "$CONFIG_MK7" = "y" ]; then define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_USE_3DNOW y define_bool CONFIG_X86_PGE y + define_bool CONFIG_X86_USE_PPRO_CHECKSUM y + define_bool CONFIG_X86_F00F_WORKS_OK y +fi + +if [ "$CONFIG_GEODE_SC1200" = "y" ]; then + define_int CONFIG_X86_L1_CACHE_SHIFT 5 + define_bool CONFIG_X86_USE_STRING_486 y + define_bool CONFIG_X86_ALIGNMENT_16 y + define_bool CONFIG_X86_HAS_TSC y + define_bool CONFIG_X86_PPRO_FENCE y + define_bool CONFIG_X86_F00F_WORKS_OK y +fi + +if [ "$CONFIG_GEODE_GX2" = "y" ]; then + define_int CONFIG_X86_L1_CACHE_SHIFT 5 + define_bool CONFIG_X86_HAS_TSC y + define_bool CONFIG_MTRR n + define_bool CONFIG_X86_LOCAL_APIC n + define_bool CONFIG_X86_GOOD_APIC n + define_bool CONFIG_X86_PGE y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y define_bool CONFIG_X86_F00F_WORKS_OK y + define_bool CONFIG_X86_MCE n fi + if [ "$CONFIG_MELAN" = "y" ]; then define_int CONFIG_X86_L1_CACHE_SHIFT 4 define_bool CONFIG_X86_USE_STRING_486 y @@ -192,7 +216,9 @@ if [ "$CONFIG_MWINCHIP3D" = "y" ]; then define_bool CONFIG_X86_F00F_WORKS_OK y fi +if [ "$CONFIG_GEODE_GX2" != "y" ]; then bool 'Machine Check Exception' CONFIG_X86_MCE +fi tristate 'Toshiba Laptop support' CONFIG_TOSHIBA tristate 'Dell laptop support' CONFIG_I8K @@ -205,10 +231,19 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'BIOS Enhanced Disk Drive calls determine boot disk (EXPERIMENTAL)' CONFIG_EDD fi -choice 'High Memory Support' \ +# GX2/3 does not have PAE support, so don't give em the option of 64G support + +if [ "$CONFIG_GEODE_GX2" != "y" ]; then + choice 'High Memory Support' \ "off CONFIG_NOHIGHMEM \ 4GB CONFIG_HIGHMEM4G \ 64GB CONFIG_HIGHMEM64G" off +else + choice 'High Memory Support' \ + "off CONFIG_NOHIGHMEM \ + 4GB CONFIG_HIGHMEM4G" off +fi + if [ "$CONFIG_HIGHMEM4G" = "y" -o "$CONFIG_HIGHMEM64G" = "y" ]; then define_bool CONFIG_HIGHMEM y else @@ -223,16 +258,22 @@ if [ "$CONFIG_HIGHMEM" = "y" ]; then fi bool 'Math emulation' CONFIG_MATH_EMULATION + +if [ "$CONFIG_GEODE_GX2" != "y" ]; then bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR +fi + bool 'Symmetric multi-processing support' CONFIG_SMP if [ "$CONFIG_SMP" != "y" ]; then - bool 'Local APIC support on uniprocessors' CONFIG_X86_UP_APIC - dep_bool 'IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC $CONFIG_X86_UP_APIC - if [ "$CONFIG_X86_UP_APIC" = "y" ]; then - define_bool CONFIG_X86_LOCAL_APIC y - fi - if [ "$CONFIG_X86_UP_IOAPIC" = "y" ]; then - define_bool CONFIG_X86_IO_APIC y + if [ "$CONFIG_GEODE_GX2" != "y" ]; then + bool 'Local APIC support on uniprocessors' CONFIG_X86_UP_APIC + dep_bool 'IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC $CONFIG_X86_UP_APIC + if [ "$CONFIG_X86_UP_APIC" = "y" ]; then + define_bool CONFIG_X86_LOCAL_APIC y + fi + if [ "$CONFIG_X86_UP_IOAPIC" = "y" ]; then + define_bool CONFIG_X86_IO_APIC y + fi fi else int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 diff --git a/include/asm-i386/msr.h b/include/asm-i386/msr.h index ea2d626..2e87084 100644 --- a/include/asm-i386/msr.h +++ b/include/asm-i386/msr.h @@ -1,6 +1,8 @@ #ifndef __ASM_MSR_H #define __ASM_MSR_H +#include + /* * Access to machine-specific registers (available on 586 and better only) * Note: the rd* operations modify the parameters directly (without using @@ -17,8 +19,14 @@ : /* no outputs */ \ : "c" (msr), "a" (val1), "d" (val2)) +#ifdef CONFIG_GEODE_SC1200 +#define rdtsc(low,high) \ + __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)); \ + if ((unsigned long) low > 0xFFFFFFFC) high-- +#else #define rdtsc(low,high) \ __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) +#endif #define rdtscl(low) \ __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx") diff --git a/drivers/scsi/aacraid/CHANGELOG b/drivers/scsi/aacraid/CHANGELOG new file mode 100644 index 0000000..18d2d25 --- /dev/null +++ b/drivers/scsi/aacraid/CHANGELOG @@ -0,0 +1,1606 @@ +Version: 0.9.10 + +Version: 1.1.2 + +2003-05-15 Mark_Salyzyn@adaptec.com + +Differences between 2.4.21-rc2-ac2 kernel and our 1.1.2 versioned driver, +changes as performed by Deanna Bonds, Bob Pasteur and Mark Salyzyn. + +aachba.c: + - If the state of a logical unit is hidden, then do not report. This + state is typically entered when a device is being cleared. + - Added support for the Tallahassee project, where one channel is + dedicated to SCSI, and the other channel is dedicated to RAID. + - Resolved some issues surrounding PAE support and IA64. + - If the driver is a not a boot disk driver, then set the Removable + bit on the inquiry strings returned by the logical units to ensure + that any changes in the arrays will be acquired when the device is + re-attached. + - mask the SRB status with 0x3F to deal with misbehaving devices. + - Do not report DISKs to inquiry requests on the SCSI bus except if + the channel is designated as a SCSI only bus. + - Propagate check conditions to the SCSI command result. + - Add support for programmable timeouts to propagate down toe the + requests. + - If we have pae mode enabled, right after we get the adapter + information and determine the pae mode capability, we enable the + system to issue 64 bit requests. +aacraid.h: + - Had to drop from 512 commands to 100 commands because some versions + of the firmware would starve commands causing a timeout reaction + which lead to lost commands. + - Added a global control variable for nondasd and paemode support. + - Dealt with some 64 bit / 32 bit issues in list_head structures and + helper Macros, replacing them with our own more sensitive variants. + - Differentiated virtual and physical references to the shared fib + allocations. + - information structure not synchronized to firmware, needed to add + a clusterchannelmask. + - Added definitions in support of the new configuration information + page bits in support of Tallahassee. + - Changed to an allocated fib pool, rather than an array in the hba + structure as this affected the SCSI memory pool. + - Added some AIF definitions to permit us to sniff for container + changes to permit a rescan to pick up new information or targets. +commctrl.c: + - The fib reference was changed to a physical and a virtual address, + absorb the name changes. + - The list_head structure handlers have been replaced with our own, + absorb the name changes. + - The fib address reported in an AIF is a physical (32 bit) reference, + and not a virtual (possibly 64 bit) reference. + - added the ioctl handling for sending a raw srb (FSACTL_SEND_RAW_SRB). +comminit.c: + - Deal with IA64 issues. + - Change to using the physical address (32 bit) for the AIF references. + - The list_head structure handlers have been replaced with our own, + absorb the name changes. + - Observed a memory leak, free up the queue resources should we fail + to initialize the adapter. +commsup.c: + - The fib reference was changed to a physical and a virtual address, + absorb the name changes. + - Instead of panicking the kernel when a fib allocation was available, + sleep until it is available. + - Submitted fib pointers are physical (32 bit) rather than virtual + (possibly 64 bit) values. + - producer and consumer indexes should be converted over to local + cpu endian before comparison. + - aac_handle_aif now sniffs AIF events and takes plug and play action + for container changes. + - The aif thread is set up to be a kernel thread, and not a user + thread. This permits us the ability to make plug and play calls + without prejudice. + - Added instrumentation to the aif thread to confirm the plug and + play activity and as an aid to several other debug sessions. + - Do not age an aif context based on the last received aif, but rather + the last poll. +dpcsup.c: + - The fib reference was changed to a physical and a virtual address, + absorb the name changes. + - Submitted fib pointers are physical (32 bit) rather than virtual + (possibly 64 bit) values. +linit.c: + - Added paemode control. + - Added various upcoming board products, and documented better the + existing board product ids. This includes SATA RAID products. + - needed to take the io_request_lock during portions of initialization. + - allocate the fib resource separately, rather than part of adapter + structure to aid in the precious SCSI resources. + - cleanup of none dasd support options. + - Added more details about the build date of the driver to the proc + information. + - dropped a change that permitted 64 bit DMA resources to be generated + instead of through a 32 bit bounce buffer. (it was moved to aachba.c + where it can be turned on after we determine the adapter's + capabilities). + - max_id, max_lun and max_channel parameters are set after the + adapter information has been picked up (the number of channels is + based on the product id table now). +sa.c: + - Context of timeout handling was incorrect, only noticed in IA64 + bit machines (due to lack of BIOS initialization). + +Differences that need further investigation and could be viewed as regressions +and added after submission: + +rx.c: + - Dropped detection of failure to generate kernel command thread. +sa.c: + - Dropped detection of failure to generate kernel command thread. + +Version: 1.1.3 + +2003-07-01 Mark_Salyzyn@adaptec.com + +aachba.c: + - Added aac_get_container_name to permit override of array inquiry + string with the set name. + +2003-07-08 Mark_Salyzyn@adaptec.com + +aachba.c: + - Return 0 (success) for unsupported commands, the check condition + should perform the necessary action of error handling. + +2003-07-10 Mark_Salyzyn@adaptec.com + +aachba.c: + - The pass-through SCSI SCB command in PAE mode was getting the fib + size count wrong, by using the 32 bit command, then doing an (n-1) + times the size of the 64 bit scatter gather. Resolution was to + subtract the 32 bit scatter gather, then do an n times the 64 scatter + gather size. + - Only go into PAE mode if more than 4MB of memory in the system. + +2003-07-10 Mark_Salyzyn@adaptec.com + +linit.c: + - Added `Family' product codes and reordered the product discovery code + to produce devices in PCI order rather than in product order. + Dell, Legend and Adaptec Families were produced with the assumption + of 2 available busses. + +2003-07-24 Mark_Salyzyn@adaptec.com + +linit.c: + - Added Bearcat (6 ch SATA) and a commented entry for Lancer where + future workarounds may be necessary due to hardware constraints. + - Set highmem_io (for kernels of 2.4.18 and above). + +aachba.c: + - Set highmem_io (for kernels of 2.4.18 and above; and when the + adapter is guaranteed to handle the possible address ranges it + will be provided). + +Version: 1.1.4: + +2003-07-28 Mark_Salyzyn@adaptec.com + +aacraid.h+common/include/fsaioctl.h+aachba.c + - Added the FSACTL_REGISTER_FIB_SEND function to the ioctl. This ioctl + is *not* a user accessible ioctl, meant only for driver use to permit + stacking a filter driver just ahead of the hardware layer. The call + to register is: + + typedef void (*fib_callback)(void *ctxt, struct fib *fibctx); + typedef struct { + int (*fib_send)(u16 command, + struct fib * context, + unsigned long fib_size, + int priority, + int wait, + int reply + fib_callback callback, + void * ctxt); + } fib_send_t; + . . . + fib_send_t original; + int dummy_fib_send (u16 command, + struct fib * context, + unsigned long fib_size, + int priority, + int wait, + int reply + fib_callback callback, + void * ctxt) + { + return (*original->fib_send)(command, context, fib_size, priority, wait, reply, callback, ctxt); + } + . . . + Scsi_Host_Template * host; + Scsi_Device * adapter; + original->fib_send = dummy_fib_send; + host->ioctl(adapter, FSACTL_REGISTER_FIB_SEND, &original); + + Return value from the ioctl include ENOTTY (not supported), EINVAL + (invalid argument pointer) and EBUSY (another function already + registered) and the original fib_send function is returned in the + ioctl argument structure. A NULL value for the fib_send member of the + structure deregisters the filter driver. The fib_callback function is + issued at interrupt priority and should follow all the constraints of + interrupt operation. It is the responsibility of the registered + fib_send function to ensure that the original fib_callback function + is called with the ctxt value when completing the command (this + subtlety is lost in the above dummy function). + +2003-07-28 Mark_Salyzyn@adaptec.com + +linit.c: + - Added Kernel, Firmware and BIOS revision and build number to proc + information. + - Added board serial number to proc information. + +aachba.c: + - Do not set removable bit in the inquiry command, the aif delivery + of array status change will handle the reasons for the removable + bit (capacity change and differences in the partition table). Some + customers take issue with the fact our arrays appear as removable. + +commctrl.c: + - Reported driver version and build number instead of Firmware version + and build number for the Miniport Version Check ioctl. ADPmp57715 + +2003-08-06 Mark_Salyzyn@adaptec.com and a cast of thousands + +all files: + - Added appropriate ifdefs, or merged in additions, in support of the + 2.6.0-test2 kernels as follows: + +Makefile: + - Added ifdefs for 2.4 and 2.6 kernels so we can use a common Makefile + for both kernel build environments. + +aachba.c: + - use linux/blkdev.h in 2.5+ kernels. + - define aac_spin_* macros to differentiate between lock requirements + in 2.5+ and 2.4 kernels. + - Use the SCSI layers definitions of the SCSI commands, rather than + our own internal SS_* manifests. + - Define SCSICMD_TO_* macros to acquire the SCSI target host, channel, + id and lun. + - Use the 2.6 SAM_* status codes for return, the 2.4 system will + redefine the SAM_* codes to 2.4 variants. + - Change to devname instead of devno when referencing devices to + simplify conversions. + - MAXIMUM_NUM_CONTAINERS references were +/- 1 in comparisons, made + this value a `number' rather than a mix of `number' and `limit'. + - Resolved `Cast of pointer from integer of different size' by + (void *)(ulong)dma_addr_t. + - Change to `id' rather than `target' to match SCSI subsystem + references name for consistency. + +aacraid.h: + - MAXIMUM_NUM_CONTAINERS references were +/- 1 in comparisons, made + this value a `number' rather than a mix of `number' and `limit'. + - Removed AAC_MAX_TARGET, as it is no longer used. + - Added CONTAINER_TO_* macros to simplify references. + - Change to `id' rather than `target' to match SCSI subsystem + references name for consistency. + - Change to devname instead of devno when referencing devices. + - Use cap_to_cyls inline to handle 64 bit calculation correctly. + +commctrl.c: + - use linux/blkdev.h in 2.5+ kernels. + - Change to `id' rather than `target' to match SCSI subsystem + references name for consistency. + +comminit.c: + - use linux/blkdev.h in 2.5+ kernels. + +commsup.c: + - use linux/blkdev.h in 2.5+ kernels. + - Moved CONTAINER_TO_* macros to aacraid.h to simplify references. + - Device Discovery loops are different for 2.4 and 2.5+ kernels, + use list_for_each_entry siblings instead of host_queue loop. + - daemonize adds the process name as a parameter, and requires + SIGKILL to be enabled to permit kernel shutdown in 2.5+ kernels. + +dpcsup.c: + - use linux/blkdev.h in 2.5+ kernels. + +linit.c: + - use linux/blkdev.h in 2.5+ kernels. + - added aacids to provide a table hint for installers. + - changed over to utilize ANSI structure initialization. + - aac_biosparm and aac_procinfo change parameters in 2.5+ kernels. + - aac_slave_configure replaces aac_queuedepth in 2.5+ kernels. + - detect no longer needs to unlock io_request_lock to do it's duty + in 2.5+ kernels. + - use SCSI_set_device in 2.5+ kernels rather than scsi_set_pci_device. + - Change to devname instead of devno when referencing devices to + simplify conversions. + - Use MAXIMUM_NUM_CONTAINERS rather than AAC_MAX_TARGET + - Use cap_to_cyls inline to handle 64 bit calculation correctly in + aac_biosparm. + - Use minor in 2.5+ kernels instead of MINOR macro. + +rx.c: + - use linux/blkdev.h in 2.5+ kernels. + - interrupts now return irqreturn_t. + +sa.c: + - use linux/blkdev.h in 2.5+ kernels. + - interrupts now return irqreturn_t. + +2003-08-15 Mark_Salyzyn@adaptec.com + +install.sh: + - increased range of kernel version reports in the magic file to 30. + +2003-08-19 Mark_Salyzyn@adaptec.com & ijohns@elipsan.com + +aachba.c: + - status_byte in the result is shifted down by one. + - set_sense spoof was not immediately followed by a copy of the check + condition results into the SCSI command. + +2003-08-20 Mark_Salyzyn@adaptec.com, Scott_Long@adaptec.com & Alan Cox + +commctrl.c: + - The raw SCSI SCB ioctl command in PAE mode was getting the fib + size count wrong, by using the 32 bit command, then doing an (n-1) + times the size of the 64 bit scatter gather. Resolution was to + subtract the 32 bit scatter gather, then do an n times the 64 scatter + gather size. + +aacraid.h: + - Added definition of CT_FLUSH_CACHE command and structures. + - Added AAC_QUIRK_31BIT for ROMB based adapters. + +linit.c: + - Added AAC_QUIRK_31BIT for ROMB based adapters. + - Check return from scsi_register. + +aachba.c: + - Added support for issuing CT_FLUSH_CACHE command when the SCSI + SYNCHRONIZE command is issued to a container. + - Restored mask after adding AAC_QUIRK_31BIT for ROMB based adapters. + +2003-08-21 Mark_Salyzyn@adaptec.com + +aachba.c: + - Changed aac_get_container_name to be a none-blocking function, + completing the incoming scsicmd with the adapter response. + +2003-08-26 Mark_Salyzyn@adaptec.com + +commsup.c + aacraid.h: + - Altered handling of AIF messages from Firmware to differentiate + events in a finer grained manner. + +2003-08-29 Mark_Salyzyn@adaptec.com + +aachba.c + aacraid.h + - Driver too noisy, undefined AAC_DETAILD_STATUS_INFO and incorporated + check condition report into the AAC_DETAILED_STATUS_INFO ifdef. + +2003-09-03 Mark_Salyzyn@adaptec.com + +aachba.c: + - Check if the device is in use and report that as a locked device + to both the FSACTL_QUERY_DISK and FSACTL_DELETE_ARRAY ioctls. + - unlock/lock around probe_container as this is a blocking function. + This change addresses a deadlock issue that surfaced in SMP only + environments. + +Version: 1.1.4-2172 + +2003-09-04 Mark_Salyzyn@adaptec.com + +commsup.c: + - References to the Status Job update structure were at incorrect + offsets causing incorrect operation during an Array Clear with + regards to plug and play actions. + +Version: 1.1.4-2177 + +2003-09-05 Mark_Salyzyn@adaptec.com + +aachba.c: + - Cleanup request from the SCSI list maintainers. + - Dropped use of SCSICMD_TO_CHANNEL & friends since + scsicmd->device->channel is available in all versions of the + operating system. + - Removed deprecated code and/or comments related to deprecation. + - include works in all versions of the operating + system. + +2003-09-09 Mark_Salyzyn@adaptec.com + +aacraid.h: + - NUM_FIBs should be 64 larger (AIFS) larger than the NUM_IO_FIBS. + +commsup.c: + - efficiency improved if we hold on to the aac_queue variable, aims + towards better code compliance and consistency. + +2003-09-15 Mark_Salyzyn@adaptec.com + +rkt.c: + - Copy if rx.c with rx = rkt + +aacraid.h: + - Added definition for rkt interface structures, copy of rx, but a + larger reserved region. + +linit.c: + - Added product code for ROC (Lancer/Rocket) U320 two channel, use rkt + interface. + +2003-09-16 Mark_Salyzyn@adaptec.com + +linit.c: + - Show Adapter vendor and model in proc information. + +Version: 1.1.4-2185 + +2003-09-16 Mark_Salyzyn@adaptec.com + +aacraid.h: + - Added definition of nblank() to assist us in determining if + dprintk(x) is defined as a blank definition to enable us to ifdef + debug code that ends up calling only dprintk functions. + +commsup.c: + - Ignore events that refer to containers > MAXIMUM_NUM_CONTAINERS + - include works in all versions of the operating + system. + +linit.c: + - print more details about outstanding commands when a SCSI hang + occurs (first use of nblank() macro just defined in aacraid.h) + +2003-09-19 Mark_Salyzyn@adaptec.com & Mark Haverkamp + +commsup.c & aachba.c: + - valid flag has added support for a value of 2, which means target + is still valid, but needs a probe_container. + +commsup.c: + - fib_alloc should not go to sleep, but return NULL if there are no + available entries in the pool. + +dpcsup.c: + - print a message if the fib kmalloc fails when forwarding AIFs + +comminit.c: + - check fib_alloc return, and report -ENOMEM should the pool be + empty. + +aachba.c: + - Check value of scsicmd->scsi_done in aac_io_done as we can get + errant firmware which returns commands twice (no released firmware + does this, this is a driver hardening issue only). + - When a fib_alloc fails, return -1 to SCSI layer. Formerly, we would + send the command with DID_ERROR. + +Version: 1.1.4-2192 + +2003-09-25 Mark_Salyzyn@adaptec.com + +linit.c: + - Moved debug variables into block to reduce impact on none-debug + environments. + +dpcsup.c + commsup.c: + - Use the fib pool instead of a kmalloc to allocate a fib for the + processing of an AIF. + +install.sh: + - Install driver into any forgotten /lib/modules directories. + +2003-09-26 Mark_Salyzyn@adaptec.com + +commctrl.c + aacraid.h: + - AMD-64 and IA-64 management applications will fail, need to change + fibctx to a 32 bit unique value. + +Version: 1.1.4-2194 + +2003-09-29 Mark_Salyzyn@adaptec.com & Mark Haverkamp + +aachba.c: + - use linux/blkdev.h for all variants on Linux. + - hold on to the host pointer in aac_io_done, because it's reference + in the device and scsicmd can go away after scsi_done is called. + - check return value of pci_set_dma_mask. + +commctrl.c: + - use linux/blkdev.h for all variants on Linux. + +comminit.c: + - use linux/blkdev.h for all variants on Linux. + +commsup.c: + - use linux/blkdev.h for all variants on Linux. + - drop linux/smp_lock.h include as it was added in a debug test from + some time ago. + - Added current 2.6 kernel support routines for rescanning. + +dpcsup.c: + - use linux/blkdev.h for all variants on Linux. + +linit.c: + - use linux/blkdev.h for all variants on Linux. + - check return value of pci_set_dma_mask. + - template->present is no longer relevant in 2.6 based kernels. + +rx.c: + - use linux/blkdev.h for all variants on Linux. + +sa.c: + - use linux/blkdev.h for all variants on Linux. + +rkt.c: + - use linux/blkdev.h for all variants on Linux. + +2003-10-01 Mark_Salyzyn@adaptec.com + +commsup.c: + - needed a fib_dealloc call ahead of the fib_free call added when + we moved over to the fib pool to handle the AIFs. + +dpcsup.c: + - need to use the `local' fibctx so that the AIF command can be + acknowledged. + +commctrl.c: + - return error status from the send_fib function in ioctl_send_fib. + +2003-10-07 Mark_Salyzyn@adaptec.com + +aachba.c + linit.c: + - serial number contains the cookie (fafa0001) that is at index 1 + of the serial number element. Only show the serial number which + is at index 0. + +linit.c: + - Added registration to receive 32 bit ioctls. + +commsup.c + dpcsup.c + aacraid.h: + - Dropped code to acquire AIF's from the general FIB pool, it was a + fool's errand. However, we kept the code that limits the AIF's + received and allocated to the AdapterFibsSize / sizeof(hw_fib). + The `last' AIF hw_fib is used to quickly acknowledge the entries, + and drop the results on the floor. + +rx.c + rkt.c: + - Cache the OIMR data in dev->OIMR, it looks remarkably like irq_mask, + which is really unused, but we can clean that up later. + +2003-10-08 Matthew Wilcox + +aachba.c: + - Use SCp.dma_handle instead of SCp.ptr for holding on to the physical + address of the allocated pci_map_single as part of the request. + +compat.h: + - define dma_handle to be ptr (in support of SCp.dma_handle change + above) for kernels that do not define this member. + +2003-10-08 Christoph Hellwig + +aachba.c: + - drop use of scsi_to_pci_dma_dir() as it is a pass-through in all + versions of the kernel. + +2003-10-09 Mark_Salyzyn@adaptec.com + +linit.c: + - When an Adapter Reset is requested, wait up to 60 seconds for all + outstanding commands to complete and report SUCCESS. + +Version: 1.1.4-2221 + +2003-10-09 Mark_Salyzyn@adaptec.com + +linit.c: + - Waited for *all* commands to complete for *all* devices on the + controller when an Adapter Reset is requested. + +Version: 1.1.4-2222 + +2003-10-10 Mark_Salyzyn@adaptec.com + +aacraid.h + rx.c + rkt.c + sa.c + linit.c: + - Added a aac_adapter_check_health, make sure the adapter is healthy + when performing and Adapter Reset request, report error codes. + +aachba.c: + - revert to use of scsi_to_pci_dma_dir() as it is not a pass-through in + all versions of the kernel. + +linit.c: + - SCSI_HAS_HOST_LOCK means that we should be working with releasing + host->lock or host->host_lock instead of io_request_lock surrounding + scsi_sleep. + +aacraid.h: + - Added definition for AAC_MAX_HOSTPHYSMEMPAGES + +comminit.c: + - Utilized AAC_MAX_HOSTPHYSMEMPAGES to limit the number of open DMA + 4096 byte PAGES of memory requested by the operating system. + +2003-10-16 Mark_Salyzyn@adaptec.com + +install.sh: + - Added support for x86_64 installs + +aachba.c: + - used SENSE KEYS from scsi.h rather than our own definitions. + +2003-10-20 Xose Vazquez Perez + +linit.c: + - Added pci_ids for 0x10110046/0x90050365 + +Version: 1.1.4-2265 + +2003-10-23 Mark_Salyzyn@adaptec.com + +linit.c: + - no need to set template->present as this is done by the SCSI layer. + +2003-10-24 Mark_Salyzyn@adaptec.com + +install.sh + - Added support for SuSE kernel determination for finer selection + of modules + - If the kernel is compiled for athlon, use that instead of + /proc/cpuinfo + - if /proc/cpuinfo is not present, don't show any errors during + install + +2003-10-28 Mark_Salyzyn@adaptec.com + +install.sh + - The entire class of SuSE OS releases (sles7, sles8, suse7, suse8, + suse8.1, suse8.2, ul1, ul1-sp2a) place the driver module results into + /lib/modules/[kernel]/kernel/drivers/scsi/aacraid/aacraid.o. The + package places updates in ...//scsi/aacraid.o (note, one directory + up). The module selected for use in the mkinitrd is fed via a `find' + command which reports files in raw directory order which in the + reiser file system would be in the .../scsi directory, but for EXT2 + since the file was added later, would prefer the previously placed + product in ../scsi/aacraid/aacraid.o. The fix is to have the driver + disk post-install remove the older .../scsi/aacraid directory. + +2003-10-30 Mark_Salyzyn@adaptec.com + +install.sh + - For the installations to `extra' /lib/modules directories beyond + the boot set, take the processor clue from the postscript (-athlon, + -x86_64 or -ia64) rather than from /proc/cpuinfo. + +Version: 1.1.4-2282 +Version: 1.1.4-2292 (Debug) + +2003-10-31 Mark_Salyzyn@adaptec.com + +aacraid.h + aachba.c: + - Added a nested count to the fsa_scsi_dev structure since some kernels + before 2.4.19 have troubles overflowing their stack when a device + goes offline. The issue is that the SCSI done call nests into sending + another queued command, which in turn spoofs a response back + indicating failure which in turn calls SCSI done. We limit the + nesting to 64 commands before we respond with a busy instead. + +Version: 1.1.4-2296 (Debug) + +linit.c & .version: + - Versioning is defined by the structure: + struct { + unsigned char dash; // Dash version number + unsigned char type; // Type, 1=Devo, 2=Alpha, 3=Beta, 4=Release + unsigned char minor;// Minor version minor + unsigned char major;// Major version number + } + Adjusted version data to match this definition for generation and + support. + +Version: 1.1.4-2299 +Version: 1.1.4-2301 +Version: 1.1.4-2302 +Version: 1.1.4-2303 + +linit.c & aacraid.h: + - Allow 64 bit apps to call GET_NEXT_ADAPTER_FIB ioctl directly, + promoting 32 bit apps when they call. + +aachba.c & aacraid.h: + - Set MAX_NESTED to 1, and improve code to reflect this simplicity. + +install.sh: + - Handle name change of products from *-athlon-athlon to *-athlon. + - Warn the user if the initrd shrinks too much + +Version: 1.1.4-2308 + +install.sh: + - Add support for identifying 2.4.19-340 kernels. + +2003-12-12 Mark Haverkamp + +linit.c: + - updated aac_eh_reset to use __shost_for_each_device now that the + device element is now private and we're supposed to use the helper + function for access. + +Version: 1.1.4-2309 +Version: 1.1.4-2310 (debug) + +2003-12-18 Mark Salyzyn + +linit.c: + - suppress unused variable warning in debug code. + - cast sys_ioctl when registering as it does not match prototype + argument for ioctl32 registration. + +Version: 1.1.4-2311 + +2003-12-22 Mark Haverkamp + +aachba.c: + - change from pae to dac as this is the more public understanding of + the 64 bit support concepts. +aacraid.h: + - Remove padding and SavedIrql +commsup.c + aachba.c: + - use atomic_read when accessing access_count member of device + structure. +linit.c & aacraid.h + - iminor takes the inode, not the inode->i_rdev member. + +Version: 1.1.4-2313 + +aachba.c + commsup.c: + - use device_busy, shost_status, in_recovery instead of just + access_count. Adjust for each OS release variant. + +Version: 1.1.4-2314 + +2003-12-22: Ken Beaty + +aachba.c + commsup.c: + - Adjusted ifdefs for kernel version to make more sense. + +2004-01-24: Mark Salyzyn + +install.sh: + - Altered script to discover prebuilt binaries from the classic + Adaptec rpm package, the Red Hat install disk format, or the + SuSE install disk format. + +2004-02-09: Christoph Hellwig + +aachba.c: + - Remove fsa_dev structure since fsa_dev is always available. + +Version: 1.1.4-2324 + +2004-02-10: Submit to scsi list for inclusion + +2004-02-17: Herve MORILLON + Mark_Salyzyn@adaptec.com + +rx.c + rkt.c: + - hit doorbell before processing host_command_normal + +aachba.c: + - Permit requests larger than 64KB + +aacraid.h: + - Permit 512 outstanding requests + +Version: 1.1.5-2326 + +linit.c + build: + - Added support for vary_io, unfortunately the build system also needed + to be adjusted to generate the SCSI_HAS_VARY_IO if the member is + seen in the drivers/scsi/hosts.h file. + +build + install.sh: + - Added support for 2.4.19-189, 2.4.19-191 and 2.4.19-201 SuSE Kernels + +Version: 1.1.5-2327 + +rkt.c + rx.c: + - Added support to issue the Temperature sync command. Since the + cost of the sync command should not increase, the decision was + made to support a `varargs' approach to dealing with the additional + temperature elements *only* for this command. + +linit.c: + - Added a proc write that accepts the string "Temperature=[0-9.],..." + to send the off-board temperature value to the Firmware so that it + may be integrated into the Enclosure Data. + - Added SkyHawk SATA cards to device list. 2020S changes now to + 2020ZCR, and we add 2020SA. + +aachba.c: + - PERCRAID RAID-5 is superfluous, changed to to PERC RAID-5. + +Version: 1.1.5-2328 + +linit.c + aacraid.h: + - Migrate towards using CONFIG_COMPAT instead of __x86_64__ + +rx.c + rkt.c: + - Added support to pick up an Adapter Blink code. ADPmp64499. + +linit.c: + - Report the Adapter Blink code to the console log. ADPmp64499. + +build: + - Correctly built the x86_64 SLES8 and ul1 driver disk. Side effects + discovered also fix problems with ia32 SLES8 install. ADPmp64499. + +Version: 1.1.5-2329 + +linit.c + aacraid.h: + - Report an AifExeFirmwarePanic AIF message to applications when the + adapter is in a blinkled state. + +aachba.c + commsup.c: Brad House + - use shost_for_each_device instead of list_for_each_entry. + +linit.c + aachba.c: + - xscale (arm) systems can not have highmem_io set as virtual/phys + handling does not recognize the page/offset addressing. + +rkt.c + rx.c: + - The Mailbox[7] in none BBS systems is not active until shortly + before the Firmware kernel is booted. The Outbound Message register + is always active and contains the same bringup conditions. We must + look at the OMR during the *_init wait. + +Version: 1.1.5-2330 + +rkt.c + rx.c + sa.c: + - Set the time by using get_seconds (epoch January 1 1970) instead + of jiffies/HZ (epoch machine startup). get_seconds is provided + for kernels < 2.6. + +Version: 1.1.5-2331 + +rkt.c: + - Mailbox[7] becomes momentarily inaccessible right after PATUWAIT + on the Callisto, lets loop on OMR only. Do not know if this + problem exists on other systems. + +Version: 1.1.5-2332 + +aachba.c + linit.c: + - Issue CT_COMMIT_CONFIG before issuign the VM_NameServe. This is + for systems that do not have a BIOS to perform this step. + +Version: 1.1.5-2333 + +aacraid.h: + - SAS requires the ability to handle as many as 32 Adapters in a + system, increased the manifest that limits the number of Adapters. + - Testing has shown that allowing 33MB I/O can starve a machine, so + we are limiting the maximum I/O size to 4MB (to match other drivers + that permit large I/O). + +linit.c: + - Make sure that the driver does not register more than + AAC_MAXIMUM_ADAPTERS instances. + - Set the queue depth to each device as divided up from AAC_MAX_IO_FIB + +commctrl.c: Chris Wright + - aac_send_raw_srb added check for bounding of fibsize value. + +all: Mark Haverkamp & Mark Salyzyn + - merge 2.6 driver changes into tree to synchronize. + +Version: 1.1.5-2334 + +aacraid.h+linit.c+commctrl.c+comminit.c: + - Added sg_tablesize and max_fib_size to adapter structure and + negotiate these plus Scsi_Host sg_tablesize, can_queue and + max_sectors based on the adapter capabilities. + +aachba.c: + - Added aac_raw_io command + - Recognize that read_callback is identical to write_callback, which + is in turn identical to raw_io's need for a callback. Renamed to + one callback function io_callback. + +rx.c+rkt.c+sa.c: + - Moved initialization around to permit New Command Interface probes + - dropped irq_mask and associated functions. + - moved acknowledgement of F/W commands *before* processing so that + we get re-interrupted if a new command is added to the produced + index while we are processing. + +linit.c+aachba.c: + - Do not print `bad0' for the serial number + +linit.c: + - this_id = 32, because it gets in the way of Container 16 being + processed. + +aachba.c: + - scsi_add_timer call issued just before completion routine called + since error recovery handler is there *just* to detect card + failure and not to affect command processing. + +build: + - Added 2.4.19.SuSE-343 kernel in support of ul1-sles8-ia32 install, + which adds yet another installation floppy to the list. + +Version: 1.1.5-2335 + +linit.c+all: + - Revert temporarily to 1.1.4-2177, Changed ASR-2020S to ASR-2020ZCR, + and ASR-2020S Terminator to ASR-2025ZCR. + +Version: 1.1.4-2336 + +linit.c+all: + - Revert temporarily to 1.1.4-2322, Changed ASR-2020S to ASR-2020ZCR, + and ASR-2020S Terminator to ASR-2025ZCR. + +Version: 1.1.4-2337 + +all: + - Revert back to 1.1.5 code base. + +commsup.c: + - Fix Irq Moderation code. A Misnomer, since this is really a PCI + utilization moderation, interrupts are not recurring on F/W. + +comminit.c: + - Turn on Irq Moderation feature (Tentatively 30% reduction in Host + CPU utilization) + +Version: 1.1.5-2337 + +aacraid.h+commsup.c+dpcsup.c+comminit.c+rx.c: + - Added support for the new comm interface. + +linit.c: + - Added debug information to proc output + +Version: 1.1.5-2338 + +commsup.c: Mark Haverkamp + - Added scsi/scsi_device.h, scsi/scsi_driver.h to include file set + - set removable to a value of 1, not to TRUE. + +aachba.c: Mark_Salyzyn@adaptec.com + - Switch to using max_fib_size rather than FIB_DATA_SIZE_IN_BYTES, + this permits SAS management applications to send ioctl FIBs larger + than 512 bytes in size to adapters that accept larger FIBs. + - Added support for SAI_READ_CAPACITY_16, READ_12, WRITE_12, READ_16 + and WRITE_16 commands. + - Played `tricks' with device_blocked and queue_depth fields in the + scsi_device structure to meter the outstanding commands down when + large sequential activity is detected. + +aacraid.h: Mark_Salyzyn@adaptec.com + - Remove unused definition of FIB_DATA_SIZE_IN_BYTES. + +linit.c: + - Setting the maximum number of I/O requests/device to a maximum of + 256 would act in the SCSI layer as only allocating to permit 1 I/O + for each device. + +Version: 1.1.5-2339 + +build: Mark_Salyzyn@adaptec.com + - Added support for 2.6.4-52 SuSE 9.1 Pro install + - Added support for multiple architectures for 2.4.21-15.EL RHEL3 QU2 + install. + +aacraid.h+aachba.c+linit.c: Mark Haverkamp + - Define 2131 as FSACTL_GET_CONTAINERS + +commctrl.c: Adam Manthei , Mark_Salyzyn@adaptec.com + - change all printk() to dprintk(()) as this is a user initiated + call for aac_send_rw_srb & aac_get_pci_info. + +rx.c+rkt.c: Adam Manthei , Mark_Salyzyn@adaptec.com + - use pci_alloc_consistent/pci_free_consistent instead of an + unchecked combination of kmalloc(,_GFP_DMA)/pci_map_single/ + pci_unmap_single/kfree. + +Version: 1.1.5-2340 + +linit.c+commctrl.c: Mark Haverkamp + - adjust to reflect linux-scsi submission results + +aachba.c: Mark_Salyzyn@adaptec.com + - remove print for unhandled commands into a debug print. The + unhandled commands are reported to the caller as unhandled, let + the caller deal with this. + +rx.c+rkt.c+sa.c: maximilian attems + - upon failure of the init routine, make sure that the registered + interupt handler is deregistered. + +commsup.c: + - fib_adapter_complete is supposed to free the hw_fib and that is it, + it tried to talk to hardware and caused a lockup. + +Version: 1.1.5-2341 + +build: + - use aacraid.ko for 2.6 releases + +Version: 1.1.5-2342 + +aachba.c: Mark_Salyzyn@adaptec.com + - added support for a module parameter 'commit=1' to enable COMMIT + CONFIG to be issued to the adapter. + - added support for a module parameter 'coalescethreshold=16' which + sets the maximum block size to consider for pushing back to the + scsi_merge layer. + - added support for a module parameter 'acbsize=8192' which sets the + suggested fib size to override the suggestion from Firmare. + - dropped call to scsi_add_timer, as it causes a panic. It was placed + in the source to resolve a command completion race condition. + +Version: 1.1.5-2343 + +install.sh: Mark_Salyzyn@adaptec.com + - globbing issue caused more whiny complaints about a missing + installation into the initrd. + - fixed some issued surrounding using the script for SuSE module + update. + +linit.c: Mark_Salyzyn@adaptec.com + - if the driver does not discover any targets, report failure. + - drop kernel_version hack to support build + +build: Mark_Salyzyn@adaptec.com + - Use vermagic instead of kernel_version to pick up matching kernel. + - when innoculating 2.6 tree builds, one needs a *full* compile in + order to generate the struct_module member. + - use module.ko for 2.6 kernels. + +Version: 1.1.5-2344 + +build: Mark_Salyzyn@adaptec.com + - floppy linux/suse/${ARCH}-${VERS}/modules/${PRODUCT}.o needs to be + a ${PRODUCT}.ko in the 2.6 based installations. + - Placed module in both scsi and scsi/${PRODUCT} directories as it + appears that the post-install is not functioning properly. + +aachba.c: Mark_Salyzyn@adaptec.com + - Checked if the lba exceeds 32 bit block address for systems that + can not support it. raw_io_64 enables 64 bit block addresses. + - Redid math for u64 >> 32 as it appears the xscale 64 bit library + is flawed. + +Version: 1.1.5-2345 + +aachba.c: Mark_Salyzyn@adaptec.com + - Overrides to force 8KB fibs needs to be reverted to defaults. + +Version: 1.1.5-2346 + +build: Mark_Salyzyn@adaptec.com + - Added 2.4.21-15.0.2.EL kernel + - Added 2.6.5-7.97 kernel to the build + +rx.c+rkt.c: Mark_Salyzyn@adaptec.com + - Mailbox7 continues to be a consternation regarding reliable + adapter recovery scenarios; switched to using OMRx[0]. + +Version: 1.1.5-2347 + +aachba.c: Mark_Salyzyn@adaptec.com + - (u64)=((u8)<<24) does not give expected results, sign extension + occurs. Replace with (u64)=((u64)(u8)<<24) + +Version: 1.1.5-2348 + +install.sh: Mark_Salyzyn@adaptec.com + - initrd is blocked from incorporating our product if there is + something in /lib/modules/${OS}-${CONFIG}/update/${PRODUCT}.o, + so remove the file. + +Version: 1.1.5-2349 + +aachba.c+aacraid.h: + - define commit_config FIB command + - define get_container_count FIB command. + +aachba.c+aacraid.h+commsup.c+linit.c + - fsa_dev becomes a dynamic structure to accommodate a variable + maximum_num_containers. + +build: + - Added 2.4.21-231 kernel to build system. + +linit.c: + - Turned on debug printing of scsi timeouts for xscale only. + +Version: 1.1.5-2350 + +rkt.c: + - Limit can_queue to 246 for rocket + +build: + - Added 2.4.19-306 kernel to build system. + +aachba.c: + - Removed an innocuous (obnoxious?) DEBUG printk + +2004-07-15: Mark Salyzyn + +Version: 1.1.5-2351 + +build: + - Added 2.4.9-31 to the build system + +modules.conf: + - Added 2.4.9-e.41, 2.4.9-e.43, 2.4.21-17.EL & 2.4.21-15.0.3.EL kernels + +build: + - Dropped 2.4.21-231 from build + +2004-07-16: Mark Salyzyn + +Version: 1.1.5-2352 + +build: + - Added 2.6.3-7mdk to the build system + +2004-07-20: Mark Salyzyn + +Version: 1.1.5-2353 (Lantana Build w/o SLES9, SuSE9.1 & SuSE9 errata 231) +Version: 1.1.5-2354 (Lantana Build w/o SLES9 & SuSE9 errata 231) +Version: 1.1.5-2355 (BigQual refresh) + +install.sh: + - If missing, add a reference to the module to the kernel's module.dep + file (affects drivers that are *not* shipped with the OS; HostRAID + and some dpt_i2o) + +aachba.c: + - for __arm__ build, the default FIB size is selected by F/W and not + overridden to 8192 bytes. + +Version: 1.1.5-2356 (Jupiter) + +aacraid.h+comminit.c+rkt.c+commsup.c+linit.c: Ken Sandars + Mark Salyzyn + - Added AAC_NUM_MGT_FIB, and ensured can_queue represents the + maximum number of io commands allowed and not be confused as the + maximum number of FIB commands permitted into the Adapter. Thus + host->can_queue is the maximum number of I/O commands, AAC_NUM_MGT_FIB + is the maximum number of ioctl commands (set to 8 rather than legacy + of 64) and init->MaxIoCommands sent back to the adapter is the total + number of FIBs. + +Version: 1.1.5-2357 (Jupiter+BigQual) + +commctrl.c: Mark Salyzyn + - Added support for issuing FIBs that are larger than the negotiated + size for the management interface. + +linit.c: Mark Salyzyn + - Added ASR-2240S, ASR-4005SAS, ASR-4000SAS, ASR-4800SAS, ASR-4805SAS + and AAR-2610SA to the product list. + +install.sh: Mark Salyzyn + - Fixed problems with using the RH & SuSE modules disk as an update + media, most of which was the selection of the extraction name from + the modules.cgz file or acquiring the appropriate update.tar.gz file. + +build: Mark Salyzyn + - set 700 for update.sh in the modules disks to recognize at least + that the RH modules disk works as an update media. + +aachba.c: Mark Salyzyn + - Dropped to 8K for the coalesce threshold for xscale builds. + +Version: 1.1.5-2358 (BigQual+Lantana) + +aachba.c+commctrl.c+aacraid.h+comminit.c+commsup.c+dpcsup.c+linit.c: + - Merged 2.6.8-rc2-bk9 differences into the driver (COSMETIC) + +compat.h + - Added definition for __user for kernels less than 2.5 (COSMETIC) + +linit.c: + - The aac_get_next_adapter_fib_ioctl for 64 bit implementations under + 2.6 maladdressed the transfer. + +Version: 1.1.5-2359 (BigQual+SPOCK+Lantana) + +commctrl.c: + - Added support for CODE_STREAM_IDENTIFIER, accessed via a new + ioctl FSACTL_GET_VERSION_MATCHING + - Added support for FSACTL_SEND_LARGE_FIB + +aacraid.h: + - Added definition for struct VersionMatch + - Added definition for FSACTL_GET_VERSION_MATCHING + - Added definition for FSACTL_SEND_LARGE_FIB + +install.sh: + - if the modules.dep file does not exist, then ensure no complaints + are made about mv not being able to access the file. + - If an entry is missing in modules.dep, construct it correctly. + +aachba.c: + - Remove any leading spaces from the Container Name. Ensure that + if there is no container name remaining, to leave the existing + one alone. + +build: + - Added support for 2.4.18-e.43 + - Added support for 2.4.18-e.47 + - Added support for 2.4.9-e.48 + - Added support for 2.4.9-e.49 (RHAS 2.1 QU5) + - Added support for 2.4.21-15.0.4.EL + +rx.c+rkt.c: + - When responding to AIFs, use DoorBellAdapterNormRespReady instead of + DoorBellAdapterNormCmdReady. The code appeared to work without + undue side effects because Firmware would clear off the queues + when new AIFs are delivered. + +commsup.c: + - If busy, defer scan action to next AIF. Half hearted attempt to + improve the reliability of this unsupported feature. + +aacraid.h+linit.c+comminit.c+rx.c+rkt.c+sa.c: + - Remove references to Mailbox7 accesses for synchronous commands. + +aacraid.h+aachba.c: + - Turned on support for Compatibility ID testing. Only enabled if + the build environment defines CODE_STREAM_IDENTIFIER. + - Fortify the adapter information to include supplemental information + as well as the GetBusInfo in support of SAS programatic limits. + +linit.c+aachba.c: + - Use the newly acquired supplement information vendor and product + fields to override the cardtype selection. + +Version: 1.1.5-2360 +Version: 1.1.5-2361 (Branch off 1.1.5-2340 in RHEL3 QU3 with aac_info fix in 1.1.5-2364) + +linit.c: + - register a reboot notifier to flush adapter + - faked AIF needs to call fib_init() later (ADPmp70525) + +commctrl.c: + - Since kfree has the possibility of switching in some esoteric + variants of the kernel, and since the BKL is held during ioctl + calls, we are unlocking the fib lock around these system calls. + +Version: 1.1.5-2362 + +build: + - Added support for 2.4.21-17.EL (RHEL3 QU3 beta) + - Added support for 2.4.21-20.EL (RHEL3 QU3) + - Added support for 2.6.7-1.451.2.3 (RHEL4 alpha 4) + +linit.c: + - ASR4000 series entries were flawed in the indexes. Added an + additional AvonPark entry. + +Version: 1.1.5-2363 + +linit.c: + - aac_info is flawed and causes periodic panics in certain systems. + +build: + - Allow background builds + - em32t binaries did not show in the rpm + +Version: 1.1.5-2364 [BigQual, Pratt, Jupiter Dual & Lantana] + +linit.c: + - AAR-2610SA has had a subproduct change from 0x103C/0x0295 to + 0x103C/0x3227. + - Some adapters have internal limits of 34 SG elements as a result + of a bug of not splitting requests up when cache is disabled when + sending them to the CHIM. Created a quirk for the adapters that + have this limit. + +Version: 1.1.5-2365 + +aachba.c: + - Neglected to add maximum_num_physical check to the srb handler. + - leading space on inquiry code was flawed as a result ot a typographic + error (replace ! with *) + +linit.c: + - ASR-4005SAS for IBM is designated as an 8i (ADPmp71521) + - Added check for late completion of command during timeout + - called aac_get_fw_debug_buffer() after init + +fwdebug.c+fwdebug.h + - Added firmware debug print handlers + +build: + - RH floppy disk was limited to 864KB, let it open up to 1.4MB. The + risk is that 864KB was about all the ramdisk could handle when + extracting, so we will no longer get a report of disk overrun as + a warning to existing OS releases. We do not know what will overload + the ramdisk during install. (ADPmp72476) + - Product ID list for aacraid is broken in the build due to changes + resulting from incorporating the 2.6 tree. + - em32t binaries did not show in the rpm fix broke SuSE releases that + utilize the 2.4.19 kernel (ADPmp73104) + +commsup.c: + - Added support for sending the time every 30 minutes. + +Version: 1.1.5-2366 + +commctrl.c: + - Fixed 64 bit version of the SCB ioctl call as it was not translating + the 32 bit scatter-gather correctly for scatter gather elements + beyond the first one. Do not believe this issue presented a problem + for any Adaptec management products due to their needs as they + limited their SG to only one entry. + +build: + - Added 2.4.19-238 + - Added 2.4.19-241 + - Added 2.4.19-248 + - Added 2.4.19-251 + +Version: 1.1.5-2367 + +linit.c: + - Added Themisto discovery to driver + - Added AAC_QUIRK_MASTER and AAC_QUIRK_SLAVE to deal with controller + pairs. + - Changed Prowler "ESD SO-DIMM PCI-X SATA ZCR" to "ASR-2026ZCR". + - Return FAILED when hba_reset completed, the ten second bus settling + delay is counter productive. + +aacraid.h+linit.c: Christoph Hellwig + - drop casting surrounding iomap and ioremap and use the __iomem + type enhancement. + +csmi.c+csmi.h: + - Added CSMI ioctl support. + +install.sh: + - log both successful and failed installations and limit complaints + about installation to a minimum by not repeating similar failure + messages. + +aachba.c: + - vtune reports that 2% of the time dealing with read calls was + devoted to get_sd_devname(). Optimized codepath. + +Version: 1.1.5-2368 + +build: + - Added 2.4.27 debian smp kernel to build + - Added 2.6.7-1.451.2.3 RHEL4 alpha 4 to the build + - Added 2.6.8-1.602 RHEL4 beta 1 to the build + - Added 2.6.5-7.109.5 SuSE 9.1 errata to the build + +csmi.h: + - Changed from CSMI_8_BYTE_ALLIGNED to CSMI_8_BYTE_ALIGNED + +csmi.c: + - failure on return from copy_to_user is ignored, but (void) is + not the way to ignore it based on compiler warnings. + - scb size is set to 16 always. + - scb flags is set to 0 always. + +linit.c+compat.h: + - scsi_sleep() renamed to ssleep() in 2.6.9 kernel + +commctrl.c: + - 32 bit application issuing a raw srb in a 64 bit address space + is not handled correctly for the fibsize calculation. + - Limit the number of scatter gather entries to 32, and zero + out the references to those sg entries. + +Version: 1.1.5-2369 + +compat.h: + - 2.6.8-1.602 RHEL4 beta 1 kernel looks more like 2.6.9, so needed to + define scsi_sleep for kernels 2.6.8 and up rather than 2.6.9 and up. + +linit.c: Chris Trown + - Added an include for linux/delay.h to pick up the definition of + ssleep(). + - Added `other' Themisto ID to list. + +csmi.h: + - bumped to 0.83 version + +csmi.c: + - Acquired slot number from Supplementary Adapter Info SlotNumber + field + - Added support to determine the actual bus type (SAS, SATA, Other). + +build: + - Added support for 2.4.21-22.EL (RHEL3 errata) + - Added support for 2.6.5-7.111 (SLES9 NLD) + - Added support for 2.4.21-243 (SuSE 9.x errata) + +aachba.c: + - valid must clear if VM_Nameserve fails on scan + - setinqstr has the possibility of overflowing the inquiry structure, + the results are a damaged stack. + +commsup.c: + - do a probe_container before issuing scan as the adapter can take + some time to write DDF data (not SCSI). + +aacraid.h: + - added definition of probe_container. + +Version: 1.1.5-2370 + +aacraid.h+commsup.c+aachba.c+commctrl.c+comminit.c+linit.c+sa.c: Adrian Bunk + - Make some needlessly global code static + +linit.c: + - Added Intruder (AAR-2420SA, AAR-2620SA & AAR-2820SA) + +aachba.c+commsup.c: + - Enable a 50 second timeout on the first asynchronous command to + permit the driver to error out and report the hardware failure. + +linit.c: + - Fixed a comment completion problem for Intruder additions. + +build: + - Added support for 2.6.8-24 (SuSE 9.2) + +Version: 1.1.5-2371 + +aachba.c: Jens Axboe + - Use a busy status return with scsi_done rather than -1 to + signal OS to try again later for aac_read and aac_write to + meet with acceptable coding standards. + +aachba.c+linit.c: Mark Salyzyn & Christoph Hellwig + - Moved AAC_EXTENDED_TIMEOUT to set sdev->timeout instead of + inline for every command in the 2.6 variant. + +linit.c: + - There is a subsystem device id clash between SATAHAWK and INTRUDER + and is giving the BIOS group some grief. Therefore the subsystem + device ID for intruder is changed to 029B, 029C and 029D for 8, 6, + and 4 port versions respectively. + - Added FSACTL_GET_VERSION_MATCHING and FSACTL_SEND_LARGE_FIB ioctls to + list of supported 32 bit ioctl calls. + +build: + - enhanced README.txt to also provide a brief description of the + binary file. + - Added support for a RHEL3 i686 ISO image as well. + - Added support for 2.6.5-7.109.12 (SLES9/SuSE9.1 SP1 B2 i386) + - Added support for 2.6.5-7.109.13 (SLES9/SuSE9.1 SP1 B2 x86_64) + - Added support for 2.6.5-7.115 (SLES9/SuSE9.1 SP1 B3) + - Added support for 2.6.5-1.358 (RH FC2) + - Added support for 2.6.9-1.667 (RH FC3) + - Added support for 2.4.21-260 (SuSE 9 errata) + - Added support for 2.4.21-261 (SuSE 8 errata) + +csmi.c: + - return code for CSMIGetSATASignature is under the control of the + firmware and should not be blindly set to SUCCESS if the command + succeeded. + + +Version: 1.1.5-2372 + +build: + - Added support for 2.6.9-1.648_EL (RHEL4 beta 2) + +linit.c: + - trim space from Model + +install.sh: + - Add /etc/modprobe.conf as another modules configuration file. + - If the module in the initrd does not match, but has the same + `size' values, then report a `possibly stripped' warning message. + +Version: 1.1.5-2373 + +build: + - Use "Avon Park SIT" for this build for the version identifier + +commsup.c: + - enable scsi-scan-single (ADPmp75534 & ADPmp69336) + +Version: 1.1.5-2374 + +build: + - Added support for 2.6.5-7.111.5 (SLES9 NLD errata) + - Added support for 2.6.5-7.128 (SLES9 SP1 B4) + - Added support for 2.6.5-7.134 (SLES9 SP1 RC) + - Added support for 2.6.9-1.906_EL (RHEL4 RC) + +commsup.c: + - disable scsi-scan-single for 2.6 kernels, proc_scsi no longer + exported + +install.sh + - Missed a double quote in the scripting to reduce size sensitivity. + +Version: 1.1.5-2375 (Avon Park SIT) + +csmi.c: + - Paramters.uFlags is a bit field, not a state. + - cdbLength needs to be hard coded to 14 from 16 (beware, 2TB warning). + - Set the srbFlags based on data direction or if there is any data to + send at all (HOST_FLAGS_DATA_IN/DATA_OUT/NO_DATA_TRANSFER). + +csmi.h: + - Added definition for HOST_FLAGS_DATA_IN/DATA_OUT/NO_DATA_TRANSFER. + +Version: 1.1.5-2376 (This is a code stream identifier) + +linit.c: + - Added ICP Lancer products ICP9024R0 and ICP9014R0. + - Added include of asm/ioctl32.h + - Report ServeRAID for driver name if IBM 8i. + +aacraid.h + - Added definition for IOP_RESET synchronous command + +rkt.c+rx.c+linit.c+aacraid.h+commsup.c+aachba.c+csmi.c+comminit.c+commctrl.c+compat.h + - Merged code and style changes in 2.6.10-rc3-bk14 into codebase. + +aachba.c: + - set the scsi device as removeable during the Read Capacity call. + (ADPmp76369) + +pci.ids: + - Submitted patch to pci-ids@ucw.cz to update the vital product list + to match the products in the linit.c file (ADPmp77082) + +build: + - Added support for 2.4.21-20.0.1.EL (RHEL3 errata) + - Added support for 2.4.21-27.EL (RHEL3 QU4) + - Added support for 2.4.21-27.0.1.EL (RHEL3 errata) + +Version: 1.1.5-2377 (Avon Park SIT) + +linit.c: + - Dropped the maximum number of commands down to 16 per target if on + an x86_64 machine with more than 4GB of memory when built in the + 2.4.* environment. + +Version: 1.1.5-2378 (CERC Test) + +linit.c: + - Dropped the maximum number of commands down to 10 per target for + this test. + +Version: 1.1.5-2379 (CERC Test) + +build: + - Added support for 2.6.9-5.EL (RHEL4 RC) + - Added support for 2.6.5-7.139 (SLES9 SP1) + - Added support for 2.4.9-e.57 (RHAS QU6) + - Added support for 2.4.9-e.59 (RHAS QU6 errata 59) + +commsup.c: + - Added kernel ifdef's to handle scsi_add_target and + scsi_remove_target calls. + +aachba.c+aacraid.h: + - Added AAC_DEBUG_INSTRUMENT_DAC_CERC to disable 64 bit scatter gather + for only the CERC SR2 product. + +Version: 1.1.5-2380 (This is a code stream identifier) + +aachba.c+comminit.c: + - Added numacb insmod parameter. + +aachba.c+aacraid.h + - Remove AAC_DEBUG_INSTRUMENT_DAC_CERC code. + +build: + - Error in incorporating the RHAS2.1 QU6 kernel (2.4.9-e.57) on to the + driver disk (ADPmp78010) + - Same problem with RHEL4 RC (2.6.9-5.EL) (ADPmp69861) + +Version: 1.1.5-2381 (This is a code stream identifier) + +build: + - Added support for 2.4.21-273 (SLES 8 errata 273) + - Added support for 2.6.5-7.111.30 (SLES 9 errata 30) + - Added support for 2.6.8-24.11 (SuSE 9.2 errata 11) + - Added support for 2.4.19.SuSE-256 (SLES8 x86_64 errata 256) + - Added support for 2.4.21-9.EL (RHEL3 QU1) + - Added support for 2.6.8.1-12mdk (Mandrake 10.1) + - Added support for 2.6.9-1.11_FC2 (FC2) + - Added support for 2.6.10-1.9_FC2 (FC2) + +commsup.c+aacraid.h + - Changed Plug-n-Play state machine to be per-array rather than + per-adapter (ADPmp77096) + +Version: 1.1.5-2382 (This is a code stream identifier) diff --git a/drivers/scsi/aacraid/Makefile b/drivers/scsi/aacraid/Makefile index 1bea28d..a945219 100644 --- a/drivers/scsi/aacraid/Makefile +++ b/drivers/scsi/aacraid/Makefile @@ -1,10 +1,142 @@ +# Adaptec aacraid +AAC_FLAGS := $(shell if [ ! -d ${TOPDIR}/drivers/scsi/aacraid ] ; then \ + echo --error_Please_build_this_driver_in_the_Linux_Kernel_tree ; \ +fi) +AAC_FLAGS += $(shell if [ -s ${TOPDIR}/include/linux/pci.h ] ; then \ + if grep shutdown ${TOPDIR}/include/linux/pci.h >/dev/null 2>/dev/null ; then \ + echo -DPCI_HAS_SHUTDOWN ; \ + fi ; \ +fi) +AAC_FLAGS += $(shell if [ -s ${TOPDIR}/drivers/scsi/hosts.h ] ; then \ + if grep vary_io ${TOPDIR}/drivers/scsi/hosts.h >/dev/null 2>/dev/null ; then \ + echo -DSCSI_HAS_VARY_IO ; \ + fi ; \ +fi) +AAC_FLAGS += $(shell if [ -s ${TOPDIR}/drivers/scsi/hosts.c ] ; then \ + if grep scsi_in_detection ${TOPDIR}/drivers/scsi/hosts.c >/dev/null 2>/dev/null ; then \ + echo -DSCSI_HAS_SCSI_IN_DETECTION ; \ + fi ; \ +fi) +AAC_FLAGS += $(shell if [ -s ${TOPDIR}/drivers/scsi/scsi_syms.c ] ; then \ + if grep scsi_in_detection ${TOPDIR}/drivers/scsi/scsi_syms.c >/dev/null 2>/dev/null ; then \ + echo -DSCSI_HAS_SCSI_SCAN_HOST ; \ + fi ; \ +fi) +AAC_FLAGS += $(shell if [ -s ${TOPDIR}/include/linux/delay.h ] ; then \ + if grep ssleep ${TOPDIR}/include/linux/delay.h >/dev/null 2>/dev/null ; then \ + echo -DSCSI_HAS_SSLEEP ; \ + fi ; \ +fi) +AAC_FLAGS += $(shell if [ -s ${TOPDIR}/include/scsi/scsi_device.h ] ; then \ + if grep scsi_device_online ${TOPDIR}/include/scsi/scsi_device.h >/dev/null 2>/dev/null ; then \ + echo -DSCSI_HAS_SCSI_DEVICE_ONLINE ; \ + fi ; \ +fi) +AAC_FLAGS += $(shell if [ -s ${TOPDIR}/include/scsi/scsi_host.h ] ; then \ + if grep dump_poll ${TOPDIR}/include/scsi/scsi_host.h >/dev/null 2>/dev/null ; then \ + echo -DSCSI_HAS_DUMP ; \ + fi ; \ +fi) +AAC_FLAGS += $(shell if [ -s ${TOPDIR}/include/scsi/scsi_host.h ] ; then \ + if grep dump_sanity_check ${TOPDIR}/include/scsi/scsi_host.h >/dev/null 2>/dev/null ; then \ + echo -DSCSI_HAS_DUMP_SANITY_CHECK ; \ + fi ; \ +fi) +AAC_FLAGS += $(shell if [ -s ${TOPDIR}/drivers/scsi/scsi_dump.h ] ; then \ + echo -DSCSI_HAS_DUMP -DSCSI_HAS_DUMP_SANITY_CHECK ; \ +fi) +AAC_FLAGS += $(shell if [ -s ${TOPDIR}/include/linux/types.h ] ; then \ + if grep __bitwise ${TOPDIR}/include/linux/types.h >/dev/null 2>/dev/null ; then \ + echo -DHAS_BITWISE_TYPE ; \ + fi ; \ +fi) +AAC_FLAGS += $(shell if [ -s ${TOPDIR}/include/linux/delay.h.h ] ; then \ + if grep msleep ${TOPDIR}/include/linux/delay.h >/dev/null 2>/dev/null ; then \ + echo -DHAS_MSLEEP ; \ + fi ; \ +fi) +ifeq (${VERSION},2) # 2.x.x +ifeq (${PATCHLEVEL},2) # 2.2.x -EXTRA_CFLAGS += -I$(TOPDIR)/drivers/scsi +ifeq ($(shell grep AAC_DRIVER_BRANCH.*dkms ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build/aacraid.h >/dev/null 2>/dev/null ; echo $?),0) +CONFIG_SCSI_AACRAID := m +endif + +CFILES_DRIVER=linit.c aachba.c commctrl.c comminit.c commsup.c \ + dpcsup.c rx.c sa.c rkt.c fwdebug.c csmi.c + +IFILES_DRIVER=aacraid.h compat.h + +ALL_SOURCE=${CFILES_DRIVER} ${IFILES_DRIVER} + +TARGET_OFILES=${CFILES_DRIVER:.c=.o} + +ifndef GCCVERSION +GCCVERSION=2.96 +endif + +GCCMACHINE:=$(shell ls -d /usr/lib/gcc-lib/*/${GCCVERSION} | sed -n 1s@/${GCCVERSION}@@p) + +INCS=-I. -I.. -I../../../include -I/usr/src/linux/include -I/usr/src/linux/drivers/scsi +INCS=-nostdinc -I${GCCMACHINE}/${GCCVERSION}/include -I. -I.. + +WARNINGS= -w -Wall -Wno-unused -Wno-switch -Wno-missing-prototypes -Wno-implicit + +COMMON_FLAGS=\ + -D__KERNEL__=1 -DUNIX -DCVLOCK_USE_SPINLOCK -DLINUX \ + -Wall -Wstrict-prototypes \ + ${INCS} \ + ${WARNINGS} \ + -O2 -fomit-frame-pointer + +AACFLAGS=${COMMON_FLAGS} ${CFLAGS} ${EXTRA_FLAGS} ${AAC_FLAGS} +COMPILE.c=${CC} ${AACFLAGS} ${TARGET_ARCH} -c + +.SUFFIXES: +.SUFFIXES: .c .o .h .a + +all: source ${TARGET_OFILES} aacraid.o + +modules: all + +source: ${ALL_SOURCE} + +clean: + rm *.o + +aacraid.o: source ${TARGET_OFILES} + ld -r -o $@ $(TARGET_OFILES) + cp -r aacraid.o ../ + +endif # 2.2.x +ifeq (${PATCHLEVEL},4) # 2.4.x + +EXTRA_CFLAGS += -I$(TOPDIR)/drivers/scsi ${EXTRA_FLAGS} ${AAC_FLAGS} O_TARGET := aacraid.o obj-m := $(O_TARGET) obj-y := linit.o aachba.o commctrl.o comminit.o commsup.o \ - dpcsup.o rx.o sa.o + dpcsup.o rx.o sa.o rkt.o fwdebug.o csmi.o + +ifeq ($(shell grep AAC_DRIVER_BRANCH.*dkms ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build/aacraid.h >/dev/null 2>/dev/null ; echo $?),0) +CONFIG_SCSI_AACRAID := m +endif include $(TOPDIR)/Rules.make + +endif # 2.4.x +ifeq (${PATCHLEVEL},6) # 2.6.x + +ifeq ($(shell grep AAC_DRIVER_BRANCH.*dkms ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build/aacraid.h >/dev/null 2>/dev/null ; echo $?),0) +obj-m := aacraid.o +else +obj-$(CONFIG_SCSI_AACRAID) := aacraid.o +endif + +aacraid-objs := linit.o aachba.o commctrl.o comminit.o commsup.o \ + dpcsup.o rx.o sa.o rkt.o fwdebug.o csmi.o + +EXTRA_CFLAGS := -Idrivers/scsi ${EXTRA_FLAGS} ${AAC_FLAGS} +endif # 2.6.x +endif # 2.x.x diff --git a/drivers/scsi/aacraid/README b/drivers/scsi/aacraid/README index eba70ef..fdb0f45 100644 --- a/drivers/scsi/aacraid/README +++ b/drivers/scsi/aacraid/README @@ -10,25 +10,37 @@ the original). Supported Cards/Chipsets ------------------------- - Dell Computer Corporation PERC 2 Quad Channel - Dell Computer Corporation PERC 2/Si - Dell Computer Corporation PERC 3/Si - Dell Computer Corporation PERC 3/Di + Adaptec 2020S + Adaptec 2025S + Adaptec 2120S + Adaptec 2200S + Adaptec 2230S + Adaptec 2240S + Adaptec 2410SA + Adaptec 2610SA + Adaptec 2810SA + Adaptec 21610SA + Adaptec 3230S + Adaptec 3240S + Adaptec 4000SAS + Adaptec 4005SAS + Adaptec 4800SAS + Adaptec 4805SAS + Adaptec 5400S + Dell PERC 2 Quad Channel + Dell PERC 2/Si + Dell PERC 3/Si + Dell PERC 3/Di + Dell CERC 2 HP NetRAID-4M - ADAPTEC 2120S - ADAPTEC 2200S - ADAPTEC 5400S Legend S220 Legend S230 - Adaptec 3230S - Adaptec 3240S - ASR-2020S PCI-X - AAR-2410SA SATA People ------------------------- Alan Cox -Christoph Hellwig (small cleanups/fixes) +Christoph Hellwig (updates for new-style PCI probing and SCSI host registration, + small cleanups/fixes) Matt Domsch (revision ioctl, adapter messages) Deanna Bonds (non-DASD support, PAE fibs and 64 bit, added new adaptec controllers added new ioctls, changed scsi interface to use new error handler, @@ -45,8 +57,7 @@ Adaptec Unix OEM Product Group Mailing List ------------------------- -linux-aacraid-devel@dell.com (Interested parties troll here) -http://mbserver.adaptec.com/ (Currently more Community Support than Devel Support) +linux-scsi@vger.kernel.org (Interested parties troll here) Also note this is very different to Brian's original driver so don't expect him to support it. Adaptec does support this driver. Contact either tech support or Mark Salyzyn. diff --git a/drivers/scsi/aacraid/TODO b/drivers/scsi/aacraid/TODO index f9ac6ac..1ebef3c 100644 --- a/drivers/scsi/aacraid/TODO +++ b/drivers/scsi/aacraid/TODO @@ -1,5 +1,4 @@ o Testing o More testing -o Feature request: display the firmware/bios/etc revisions in the - /proc info -o 2.5.0 and beyond. +o I/O size increase +o add sysfs interface diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 4d21996..2e14356 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -4,6 +4,7 @@ * * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. + * * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * This program is free software; you can redistribute it and/or modify @@ -22,8 +23,6 @@ * */ -#include -#include #include #include #include @@ -32,74 +31,46 @@ #include #include #include +#include +#include /* For the following test */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +#include +#endif #include #include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include #define MAJOR_NR SCSI_DISK0_MAJOR /* For DEVICE_NR() */ -#include +#include /* for DEVICE_NR & io_request_lock definition */ #include "scsi.h" #include "hosts.h" #include "sd.h" +#else +#include +#include +#include +#include +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)) && !defined(BLIST_NO_ULD_ATTACH)) +#include /* Pick up BLIST_NO_ULD_ATTACH? */ +#endif +#include +#include +#include +#endif #include "aacraid.h" -/* SCSI Commands */ -/* TODO: dmb - use the ones defined in include/scsi/scsi.h */ - -#define SS_TEST 0x00 /* Test unit ready */ -#define SS_REZERO 0x01 /* Rezero unit */ -#define SS_REQSEN 0x03 /* Request Sense */ -#define SS_REASGN 0x07 /* Reassign blocks */ -#define SS_READ 0x08 /* Read 6 */ -#define SS_WRITE 0x0A /* Write 6 */ -#define SS_INQUIR 0x12 /* inquiry */ -#define SS_ST_SP 0x1B /* Start/Stop unit */ -#define SS_LOCK 0x1E /* prevent/allow medium removal */ -#define SS_RESERV 0x16 /* Reserve */ -#define SS_RELES 0x17 /* Release */ -#define SS_MODESEN 0x1A /* Mode Sense 6 */ -#define SS_RDCAP 0x25 /* Read Capacity */ -#define SM_READ 0x28 /* Read 10 */ -#define SM_WRITE 0x2A /* Write 10 */ -#define SS_SEEK 0x2B /* Seek */ - /* values for inqd_pdt: Peripheral device type in plain English */ -#define INQD_PDT_DA 0x00 /* Direct-access (DISK) device */ -#define INQD_PDT_PROC 0x03 /* Processor device */ -#define INQD_PDT_CHNGR 0x08 /* Changer (jukebox, scsi2) */ -#define INQD_PDT_COMM 0x09 /* Communication device (scsi2) */ -#define INQD_PDT_NOLUN2 0x1f /* Unknown Device (scsi2) */ -#define INQD_PDT_NOLUN 0x7f /* Logical Unit Not Present */ +#define INQD_PDT_DA 0x00 /* Direct-access (DISK) device */ +#define INQD_PDT_PROC 0x03 /* Processor device */ +#define INQD_PDT_CHNGR 0x08 /* Changer (jukebox, scsi2) */ +#define INQD_PDT_COMM 0x09 /* Communication device (scsi2) */ +#define INQD_PDT_NOLUN2 0x1f /* Unknown Device (scsi2) */ +#define INQD_PDT_NOLUN 0x7f /* Logical Unit Not Present */ -#define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */ -#define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */ - -#define TARGET_LUN_TO_CONTAINER(target, lun) (target) -#define CONTAINER_TO_TARGET(cont) ((cont)) -#define CONTAINER_TO_LUN(cont) (0) - -#define MAX_FIB_DATA (sizeof(struct hw_fib) - sizeof(FIB_HEADER)) - -#define MAX_DRIVER_SG_SEGMENT_COUNT 17 - -/* - * Sense keys - */ -#define SENKEY_NO_SENSE 0x00 -#define SENKEY_UNDEFINED 0x01 -#define SENKEY_NOT_READY 0x02 -#define SENKEY_MEDIUM_ERR 0x03 -#define SENKEY_HW_ERR 0x04 -#define SENKEY_ILLEGAL 0x05 -#define SENKEY_ATTENTION 0x06 -#define SENKEY_PROTECTED 0x07 -#define SENKEY_BLANK 0x08 -#define SENKEY_V_UNIQUE 0x09 -#define SENKEY_CPY_ABORT 0x0A -#define SENKEY_ABORT 0x0B -#define SENKEY_EQUAL 0x0C -#define SENKEY_VOL_OVERFLOW 0x0D -#define SENKEY_MISCOMP 0x0E -#define SENKEY_RESERVED 0x0F +#define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */ +#define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */ /* * Sense codes @@ -109,6 +80,7 @@ #define SENCODE_END_OF_DATA 0x00 #define SENCODE_BECOMING_READY 0x04 #define SENCODE_INIT_CMD_REQUIRED 0x04 +#define SENCODE_DATA_PROTECT 0x0E #define SENCODE_PARAM_LIST_LENGTH_ERROR 0x1A #define SENCODE_INVALID_COMMAND 0x20 #define SENCODE_LBA_OUT_OF_RANGE 0x21 @@ -158,82 +130,274 @@ #define BYTE2(x) (unsigned char)((x) >> 16) #define BYTE3(x) (unsigned char)((x) >> 24) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +/* compatibility */ +#ifndef SAM_STAT_CHECK_CONDITION +# define SAM_STAT_CHECK_CONDITION (CHECK_CONDITION << 1) +#endif +#ifndef SAM_STAT_GOOD +# define SAM_STAT_GOOD (GOOD << 1) +#endif +#ifndef SAM_STAT_TASK_SET_FULL +# define SAM_STAT_TASK_SET_FULL (QUEUE_FULL << 1) +#endif + +#endif /*------------------------------------------------------------------------------ * S T R U C T S / T Y P E D E F S *----------------------------------------------------------------------------*/ /* SCSI inquiry data */ struct inquiry_data { - u8 inqd_pdt; /* Peripheral qualifier | Peripheral Device Type */ - u8 inqd_dtq; /* RMB | Device Type Qualifier */ - u8 inqd_ver; /* ISO version | ECMA version | ANSI-approved version */ - u8 inqd_rdf; /* AENC | TrmIOP | Response data format */ - u8 inqd_len; /* Additional length (n-4) */ - u8 inqd_pad1[2]; /* Reserved - must be zero */ - u8 inqd_pad2; /* RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */ - u8 inqd_vid[8]; /* Vendor ID */ - u8 inqd_pid[16]; /* Product ID */ - u8 inqd_prl[4]; /* Product Revision Level */ -}; - -struct sense_data { - u8 error_code; /* 70h (current errors), 71h(deferred errors) */ - u8 valid:1; /* A valid bit of one indicates that the information */ - /* field contains valid information as defined in the - * SCSI-2 Standard. - */ - u8 segment_number; /* Only used for COPY, COMPARE, or COPY AND VERIFY Commands */ - u8 sense_key:4; /* Sense Key */ - u8 reserved:1; - u8 ILI:1; /* Incorrect Length Indicator */ - u8 EOM:1; /* End Of Medium - reserved for random access devices */ - u8 filemark:1; /* Filemark - reserved for random access devices */ - - u8 information[4]; /* for direct-access devices, contains the unsigned - * logical block address or residue associated with - * the sense key - */ - u8 add_sense_len; /* number of additional sense bytes to follow this field */ - u8 cmnd_info[4]; /* not used */ - u8 ASC; /* Additional Sense Code */ - u8 ASCQ; /* Additional Sense Code Qualifier */ - u8 FRUC; /* Field Replaceable Unit Code - not used */ - u8 bit_ptr:3; /* indicates which byte of the CDB or parameter data - * was in error - */ - u8 BPV:1; /* bit pointer valid (BPV): 1- indicates that - * the bit_ptr field has valid value - */ - u8 reserved2:2; - u8 CD:1; /* command data bit: 1- illegal parameter in CDB. - * 0- illegal parameter in data. - */ - u8 SKSV:1; - u8 field_ptr[2]; /* byte of the CDB or parameter data in error */ + u8 inqd_pdt; /* Peripheral qualifier | Peripheral Device Type */ + u8 inqd_dtq; /* RMB | Device Type Qualifier */ + u8 inqd_ver; /* ISO version | ECMA version | ANSI-approved version */ + u8 inqd_rdf; /* AENC | TrmIOP | Response data format */ + u8 inqd_len; /* Additional length (n-4) */ + u8 inqd_pad1[2];/* Reserved - must be zero */ + u8 inqd_pad2; /* RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */ + u8 inqd_vid[8]; /* Vendor ID */ + u8 inqd_pid[16];/* Product ID */ + u8 inqd_prl[4]; /* Product Revision Level */ }; /* * M O D U L E G L O B A L S */ -static struct fsa_scsi_hba *fsa_dev[MAXIMUM_NUM_ADAPTERS]; /* SCSI Device Instance Pointers */ -static struct sense_data sense_data[MAXIMUM_NUM_CONTAINERS]; -static void get_sd_devname(int disknum, char *buffer); -static unsigned long aac_build_sg(Scsi_Cmnd* scsicmd, struct sgmap* sgmap); -static unsigned long aac_build_sg64(Scsi_Cmnd* scsicmd, struct sgmap64* psg); -static int aac_send_srb_fib(Scsi_Cmnd* scsicmd); +static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap); +static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg); +static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg); +static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); +#ifdef AAC_DETAILED_STATUS_INFO static char *aac_get_status_string(u32 status); +#endif /* * Non dasd selection is handled entirely in aachba now */ +static int nondasd = -1; +static int dacmode = -1; + +#if (defined(__arm__) || defined(CONFIG_EXTERNAL)) +static int commit = 1; +#else +static int commit = -1; +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) +module_param(nondasd, int, S_IRUGO|S_IWUSR); +#else MODULE_PARM(nondasd, "i"); +#endif MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on"); -MODULE_PARM(paemode, "i"); -MODULE_PARM_DESC(paemode, "Control whether dma addressing is using PAE. 0=off, 1=on"); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) +module_param(dacmode, int, S_IRUGO|S_IWUSR); +#else +MODULE_PARM(dacmode, "i"); +#endif +MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on"); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) +module_param(commit, int, S_IRUGO|S_IWUSR); +#else +MODULE_PARM(commit, "i"); +#endif +MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on"); + +#if (defined(__arm__) || defined(CONFIG_EXTERNAL) || (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) || defined(__VMKERNEL_MODULE__)) +static int coalescethreshold = 0; +#else +static int coalescethreshold = 16; /* 8KB coalesce knee */ +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) +module_param(coalescethreshold, int, S_IRUGO|S_IWUSR); +#else +MODULE_PARM(coalescethreshold, "i"); +#endif +MODULE_PARM_DESC(coalescethreshold, "Control the maximum block size of sequential requests that are fed back to the scsi_merge layer for coalescing. 0=off, 16 block (8KB) default."); + +int numacb = -1; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) +module_param(numacb, int, S_IRUGO|S_IWUSR); +#else +MODULE_PARM(numacb, "i"); +#endif +MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control blocks (FIB) allocated. Valid values are 512 and down. Default is to use suggestion from Firmware."); + +int acbsize = -1; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) +module_param(acbsize, int, S_IRUGO|S_IWUSR); +#else +MODULE_PARM(acbsize, "i"); +#endif +MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512, 2048, 4096 and 8192. Default is to use suggestion from Firmware."); + +int update_interval = 30 * 60; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) +module_param(update_interval, int, S_IRUGO|S_IWUSR); +#else +MODULE_PARM(update_interval, "i"); +#endif +MODULE_PARM_DESC(update_interval, "Interval in seconds between time sync updates issued to adapter."); + +int check_interval = 24 * 60 * 60; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) +module_param(check_interval, int, S_IRUGO|S_IWUSR); +#else +MODULE_PARM(check_interval, "i"); +#endif +MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health checks."); + +int check_reset = 1; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) +module_param(check_reset, int, S_IRUGO|S_IWUSR); +#else +MODULE_PARM(check_reset, "i"); +#endif +MODULE_PARM_DESC(check_reset, "If adapter fails health check, reset the adapter."); +#if (defined(AAC_EXTENDED_TIMEOUT)) + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) +int extendedtimeout = -1; +module_param(extendedtimeout, int, S_IRUGO|S_IWUSR); +#else +static int extendedtimeout = -1; +MODULE_PARM(extendedtimeout, "i"); +#endif +MODULE_PARM_DESC(extendedtimeout, "Request a specific timeout to override I/O requests issed to the adapter."); +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) +static char aacraid[256]; +module_param_string(aacraid, aacraid, sizeof(aacraid), 0); +#else +static char * aacraid = NULL; +MODULE_PARM(aacraid, "s"); +#endif +MODULE_PARM_DESC(aacraid, "set the various published parameters of the aacraid driver with a syntax of aacraid=parm:value[,parm:value]..."); + +static int aacraid_setup(char *str) +{ + int i; + char *key; + char *value; + struct { + char * option_name; + int * option_flag; + int option_value; + } options[] = { + { "nondasd", &nondasd, 1 }, + { "dacmode", &dacmode, 1 }, + { "commit", &commit, 1 }, + { "coalescethreshold", &coalescethreshold, 16 }, + { "acbsize", &acbsize, 8192 }, + { "update_interval", &update_interval, 30 * 60 }, + { "check_interval", &check_interval, -1 }, + { "check_reset", &check_reset, 1 }, +#if (defined(AAC_EXTENDED_TIMEOUT)) + { "extendedtimeout", &extendedtimeout, AAC_EXTENDED_TIMEOUT }, +#endif + }; + +#if (defined(AAC_DEBUG_INSTRUMENT_SETUP)) +printk (KERN_INFO "aacraid_setup(\"%s\")\n", (str) ? str : ""); +#endif + if (str) while ((key = strsep(&str, ",."))) { + if (!*key) + continue; + value = strchr(key, ':'); + if (value) + *value++ = '\0'; + for (i = 0; i < (sizeof (options) / sizeof (options[0])); i++) { + if (strnicmp (key, options[i].option_name, + strlen(options[i].option_name)) == 0) { + *options[i].option_flag + = (value) + ? simple_strtoul(value, NULL, 0) + : options[i].option_value; + break; + } + } + } -static int nondasd = -1; -static int paemode = -1; + return (1); +} + +__setup("aacraid=", aacraid_setup); + +/** + * aac_get_config_status - check the adapter configuration + * @common: adapter to query + * + * Query config status, and commit the configuration if needed. + */ +int aac_get_config_status(struct aac_dev *dev) +{ + int status = 0; + struct fib * fibptr; + + if (!(fibptr = fib_alloc(dev))) + return -ENOMEM; + + fib_init(fibptr); + { + struct aac_get_config_status *dinfo; + dinfo = (struct aac_get_config_status *) fib_data(fibptr); + + dinfo->command = cpu_to_le32(VM_ContainerConfig); + dinfo->type = cpu_to_le32(CT_GET_CONFIG_STATUS); + dinfo->count = cpu_to_le32(sizeof(((struct aac_get_config_status_resp *)NULL)->data)); + } + + status = fib_send(ContainerCommand, + fibptr, + sizeof (struct aac_get_config_status), + FsaNormal, + 1, 1, + NULL, NULL); + if (status < 0 ) { + printk(KERN_WARNING "aac_get_config_status: SendFIB failed.\n"); + } else { + struct aac_get_config_status_resp *reply + = (struct aac_get_config_status_resp *) fib_data(fibptr); + dprintk((KERN_WARNING + "aac_get_config_status: response=%d status=%d action=%d\n", + le32_to_cpu(reply->response), + le32_to_cpu(reply->status), + le32_to_cpu(reply->data.action))); + if ((le32_to_cpu(reply->response) != ST_OK) || + (le32_to_cpu(reply->status) != CT_OK) || + (le32_to_cpu(reply->data.action) > CFACT_PAUSE)) { + printk(KERN_WARNING "aac_get_config_status: Will not issue the Commit Configuration\n"); + status = -EINVAL; + } + } + 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); + 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, + fibptr, + sizeof (struct aac_commit_config), + FsaNormal, + 1, 1, + NULL, NULL); + fib_complete(fibptr); + } else if (commit == 0) { + printk(KERN_WARNING + "aac_get_config_status: Foreign device configurations are being ignored\n"); + } + } + fib_free(fibptr); + return status; +} /** * aac_get_containers - list containers @@ -243,21 +407,56 @@ static int paemode = -1; */ int aac_get_containers(struct aac_dev *dev) { - struct fsa_scsi_hba *fsa_dev_ptr; - u32 index; + struct fsa_dev_info *fsa_dev_ptr; + u32 index; int status = 0; - struct aac_query_mount *dinfo; - struct aac_mount *dresp; struct fib * fibptr; unsigned instance; + struct aac_get_container_count *dinfo; + struct aac_get_container_count_resp *dresp; + int maximum_num_containers = MAXIMUM_NUM_CONTAINERS; - fsa_dev_ptr = &(dev->fsa_dev); instance = dev->scsi_host_ptr->unique_id; if (!(fibptr = fib_alloc(dev))) return -ENOMEM; - for (index = 0; index < MAXIMUM_NUM_CONTAINERS; index++) { + 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, + fibptr, + sizeof (struct aac_get_container_count), + FsaNormal, + 1, 1, + NULL, NULL); + if (status >= 0) { + dresp = (struct aac_get_container_count_resp *)fib_data(fibptr); + maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries); + fib_complete(fibptr); + } + + if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) + maximum_num_containers = MAXIMUM_NUM_CONTAINERS; + fsa_dev_ptr = (struct fsa_dev_info *) kmalloc( + sizeof(*fsa_dev_ptr) * maximum_num_containers, GFP_KERNEL); + if (!fsa_dev_ptr) { + fib_free(fibptr); + return -ENOMEM; + } + memset(fsa_dev_ptr, 0, sizeof(*fsa_dev_ptr) * maximum_num_containers); + + dev->fsa_dev = fsa_dev_ptr; + dev->maximum_num_containers = maximum_num_containers; + + for (index = 0; index < dev->maximum_num_containers; index++) { + struct aac_query_mount *dinfo; + struct aac_mount *dresp; + + fsa_dev_ptr[index].devname[0] = '\0'; + fib_init(fibptr); dinfo = (struct aac_query_mount *) fib_data(fibptr); @@ -277,83 +476,276 @@ int aac_get_containers(struct aac_dev *dev) } dresp = (struct aac_mount *)fib_data(fibptr); +#if (defined(AAC_DEBUG_INSTRUMENT_2TB)) + printk(KERN_INFO "dresp->mnt[0].vol=%d " + "dresp->mnt[0].capacity=%u" + "={%02x %02x %02x %02x}\n", + le32_to_cpu(dresp->mnt[0].vol), + le32_to_cpu(dresp->mnt[0].capacity), + ((u8 *)&dresp->mnt[0].capacity)[0], + ((u8 *)&dresp->mnt[0].capacity)[1], + ((u8 *)&dresp->mnt[0].capacity)[2], + ((u8 *)&dresp->mnt[0].capacity)[3]); +#endif + if ((le32_to_cpu(dresp->status) == ST_OK) && + (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) { + dinfo->command = cpu_to_le32(VM_NameServe64); + dinfo->count = cpu_to_le32(index); + dinfo->type = cpu_to_le32(FT_FILESYS); + + if (fib_send(ContainerCommand, + fibptr, + sizeof(struct aac_query_mount), + FsaNormal, + 1, 1, + NULL, NULL) < 0) + continue; +#if (defined(AAC_DEBUG_INSTRUMENT_2TB)) + printk(KERN_INFO "dresp->mnt[0].capacity64=%llu" + "={%02x %02x %02x %02x %02x %02x %02x %02x}\n", + ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + + (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32), + ((u8 *)&dresp->mnt[0].capacity)[0], + ((u8 *)&dresp->mnt[0].capacity)[1], + ((u8 *)&dresp->mnt[0].capacity)[2], + ((u8 *)&dresp->mnt[0].capacity)[3], + ((u8 *)&dresp->mnt[0].capacityhigh)[0], + ((u8 *)&dresp->mnt[0].capacityhigh)[1], + ((u8 *)&dresp->mnt[0].capacityhigh)[2], + ((u8 *)&dresp->mnt[0].capacityhigh)[3]); +#endif + } else + dresp->mnt[0].capacityhigh = 0; + + dprintk ((KERN_DEBUG + "VM_NameServe cid=%d status=%d vol=%d state=%d cap=%llu\n", + (int)index, (int)le32_to_cpu(dresp->status), + (int)le32_to_cpu(dresp->mnt[0].vol), + (int)le32_to_cpu(dresp->mnt[0].state), + ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + + (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32))); if ((le32_to_cpu(dresp->status) == ST_OK) && (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { - fsa_dev_ptr->valid[index] = 1; - fsa_dev_ptr->type[index] = le32_to_cpu(dresp->mnt[0].vol); - fsa_dev_ptr->size[index] = le32_to_cpu(dresp->mnt[0].capacity); + fsa_dev_ptr[index].valid = 1; + fsa_dev_ptr[index].type = le32_to_cpu(dresp->mnt[0].vol); + fsa_dev_ptr[index].size + = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + + (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32); if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) - fsa_dev_ptr->ro[index] = 1; + fsa_dev_ptr[index].ro = 1; +#if (defined(AAC_DEBUG_INSTRUMENT_2TB)) + printk(KERN_INFO "Valid type=%u size=%llu ro=%d\n", + fsa_dev_ptr[index].type, fsa_dev_ptr[index].size, + fsa_dev_ptr[index].ro); +#endif } fib_complete(fibptr); /* * If there are no more containers, then stop asking. */ - if ((index + 1) >= le32_to_cpu(dresp->count)) + if ((index + 1) >= le32_to_cpu(dresp->count)){ break; + } } fib_free(fibptr); - fsa_dev[instance] = fsa_dev_ptr; return status; } +static void aac_io_done(struct scsi_cmnd * scsicmd) +{ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) /* suppress unused variable warning */ + unsigned long cpu_flags; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) /* suppress unused variable warning */ + struct Scsi_Host *host = scsicmd->device->host; +#endif +#endif + + if (scsicmd->scsi_done == (void (*)(struct scsi_cmnd*))NULL) { + printk(KERN_WARNING "aac_io_done: scsi_done NULL\n"); + return; + } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) + spin_lock_irqsave(&io_request_lock, cpu_flags); +#endif + scsicmd->scsi_done(scsicmd); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) + spin_unlock_irqrestore(&io_request_lock, cpu_flags); +#endif +#if (defined(AAC_DEBUG_INSTRUMENT_TIMING)) + { + u64 lba; + u32 count = 0; + struct timeval now; + do_gettimeofday(&now); + if ((scsicmd->cmnd[0] == WRITE_6) || /* 6 byte command */ + (scsicmd->cmnd[0] == READ_6)) { + lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | + (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; + count = scsicmd->cmnd[4]; + if (count == 0) + count = 256; +#if (defined(WRITE_16)) + } else if ((scsicmd->cmnd[0] == WRITE_16) || /* 16 byte command */ + (scsicmd->cmnd[0] == READ_16)) { + lba = ((u64)scsicmd->cmnd[2] << 56) + | ((u64)scsicmd->cmnd[3] << 48) + | ((u64)scsicmd->cmnd[4] << 40) + | ((u64)scsicmd->cmnd[9] << 32) + | ((u64)scsicmd->cmnd[6] << 24) + | (scsicmd->cmnd[7] << 16) + | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; + count = (scsicmd->cmnd[10] << 24) + | (scsicmd->cmnd[11] << 16) + | (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13]; +#endif + } else if ((scsicmd->cmnd[0] == WRITE_12) /* 12 byte command */ + || (scsicmd->cmnd[0] == READ_12)) { + lba = ((u64)scsicmd->cmnd[2] << 24) + | (scsicmd->cmnd[3] << 16) + | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; + count = (scsicmd->cmnd[6] << 24) + | (scsicmd->cmnd[7] << 16) + | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; + } else if ((scsicmd->cmnd[0] == WRITE_10) /* 10 byte command */ + || (scsicmd->cmnd[0] == READ_10)) { + lba = ((u64)scsicmd->cmnd[2] << 24) + | (scsicmd->cmnd[3] << 16) + | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; + count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; + } else + lba = (u64)(long)scsicmd; + printk(((count) + ? KERN_DEBUG "%lu.%06lu d%lu %llu[%u]\n" + : KERN_DEBUG "%lu.%06lu d%lu 0x%llx\n"), + now.tv_sec % 100, now.tv_usec, + ((struct aac_dev *)scsicmd->device->host->hostdata)->queues->queue[AdapNormCmdQueue].numpending, + lba, count); + } +#endif +} +#if (defined(AAC_DEBUG_INSTRUMENT_TIMING)) + +static inline void __aac_io_done(struct scsi_cmnd * scsicmd) +{ + struct timeval now; + scsicmd->scsi_done(scsicmd); + do_gettimeofday(&now); + printk(KERN_DEBUG "%lu.%06lu d%lu %p\n", + now.tv_sec % 100, now.tv_usec, + ((struct aac_dev *)scsicmd->device->host->hostdata)->queues->queue[AdapNormCmdQueue].numpending, + scsicmd); +} +#endif + +static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len) +{ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + void *buf; + unsigned int transfer_len; + struct scatterlist *sg = scsicmd->request_buffer; + + if (scsicmd->use_sg) { + buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; + transfer_len = min(sg->length, len + offset); + } else { + buf = scsicmd->request_buffer; + transfer_len = min(scsicmd->request_bufflen, len + offset); + } + + memcpy(buf + offset, data, transfer_len - offset); + + if (scsicmd->use_sg) + kunmap_atomic(buf - sg->offset, KM_IRQ0); + +#else + memcpy(scsicmd->request_buffer + offset, data, + min(scsicmd->request_bufflen, len + offset) - offset); +#endif +} + +static void get_container_name_callback(void *context, struct fib * fibptr) +{ + struct aac_get_name_resp * get_name_reply; + struct scsi_cmnd * scsicmd; + + scsicmd = (struct scsi_cmnd *) context; + scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; + + dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); + if (fibptr == NULL) + BUG(); + + get_name_reply = (struct aac_get_name_resp *) fib_data(fibptr); + /* Failure is irrelevant, using default value instead */ + if ((le32_to_cpu(get_name_reply->status) == CT_OK) + && (get_name_reply->data[0] != '\0')) { + char *sp = get_name_reply->data; + sp[sizeof(((struct aac_get_name_resp *)NULL)->data)-1] = '\0'; + while (*sp == ' ') + ++sp; + if (*sp) { + char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)]; + int count = sizeof(d); + char *dp = d; + do { + *dp++ = (*sp) ? *sp++ : ' '; + } while (--count > 0); + aac_internal_transfer(scsicmd, d, + offsetof(struct inquiry_data, inqd_pid), sizeof(d)); + } + } + + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; + + fib_complete(fibptr); + fib_free(fibptr); + aac_io_done(scsicmd); +} + /** - * aac_get_container_name - get container name + * aac_get_container_name - get container name, none blocking. */ -static int aac_get_container_name(struct aac_dev *dev, int cid, char * pid) +static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) { - struct fsa_scsi_hba *fsa_dev_ptr; - int status = 0; + int status; struct aac_get_name *dinfo; - struct aac_get_name_resp *dresp; - struct fib * fibptr; - unsigned instance; + struct fib * cmd_fibcontext; + struct aac_dev * dev; - fsa_dev_ptr = &(dev->fsa_dev); - instance = dev->scsi_host_ptr->unique_id; + dev = (struct aac_dev *)scsicmd->device->host->hostdata; - if (!(fibptr = fib_alloc(dev))) + if (!(cmd_fibcontext = fib_alloc(dev))) return -ENOMEM; - fib_init(fibptr); - dinfo = (struct aac_get_name *) fib_data(fibptr); + fib_init(cmd_fibcontext); + dinfo = (struct aac_get_name *) fib_data(cmd_fibcontext); dinfo->command = cpu_to_le32(VM_ContainerConfig); dinfo->type = cpu_to_le32(CT_READ_NAME); dinfo->cid = cpu_to_le32(cid); dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data)); - status = fib_send(ContainerCommand, - fibptr, - sizeof (struct aac_get_name), - FsaNormal, - 1, 1, - NULL, NULL); - if (status < 0 ) { - printk(KERN_WARNING "aac_get_container_name: SendFIB failed.\n"); - } else { - dresp = (struct aac_get_name_resp *)fib_data(fibptr); - - status = (le32_to_cpu(dresp->status) != CT_OK) - || (dresp->data[0] == '\0'); - if (status == 0) { - char * sp = dresp->data; - char * dp = pid; - do { - if ((*sp == '\0') - || ((dp - pid) >= sizeof(((struct aac_get_name_resp *)NULL)->data))) { - *dp = ' '; - } else { - *dp = *sp++; - } - } while (++dp < &pid[sizeof(((struct inquiry_data *)NULL)->inqd_pid)]); - } + status = fib_send(ContainerCommand, + cmd_fibcontext, + sizeof (struct aac_get_name), + FsaNormal, + 0, 1, + (fib_callback) get_container_name_callback, + (void *) scsicmd); + + /* + * Check that the command queued to the controller + */ + if (status == -EINPROGRESS) { + scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; + return 0; } - fib_complete(fibptr); - fib_free(fibptr); - fsa_dev[instance] = fsa_dev_ptr; - return status; + + printk(KERN_WARNING "aac_get_container_name: fib_send failed with status: %d.\n", status); + fib_complete(cmd_fibcontext); + fib_free(cmd_fibcontext); + return -1; } /** @@ -362,19 +754,24 @@ static int aac_get_container_name(struct aac_dev *dev, int cid, char * pid) * @cid: container identifier * * Queries the controller about the given volume. The volume information - * is updated in the struct fsa_scsi_hba structure rather than returned. + * is updated in the struct fsa_dev_info structure rather than returned. */ -static int probe_container(struct aac_dev *dev, int cid) +int probe_container(struct aac_dev *dev, int cid) { - struct fsa_scsi_hba *fsa_dev_ptr; + struct fsa_dev_info *fsa_dev_ptr; int status; struct aac_query_mount *dinfo; struct aac_mount *dresp; struct fib * fibptr; unsigned instance; +#if (defined(AAC_DEBUG_INSTRUMENT_VM_NAMESERVE)) + unsigned long tag; +#endif - fsa_dev_ptr = &(dev->fsa_dev); + fsa_dev_ptr = dev->fsa_dev; + if (!fsa_dev_ptr) + return -ENOMEM; instance = dev->scsi_host_ptr->unique_id; if (!(fibptr = fib_alloc(dev))) @@ -388,27 +785,61 @@ static int probe_container(struct aac_dev *dev, int cid) dinfo->count = cpu_to_le32(cid); dinfo->type = cpu_to_le32(FT_FILESYS); +#if (defined(AAC_DEBUG_INSTRUMENT_VM_NAMESERVE)) + tag = jiffies; +#endif status = fib_send(ContainerCommand, fibptr, sizeof(struct aac_query_mount), FsaNormal, 1, 1, NULL, NULL); +#if (defined(AAC_DEBUG_INSTRUMENT_VM_NAMESERVE)) + tag = jiffies - tag; + printk(KERN_INFO "VM_Nameserve: %lu.%03lus\n", + tag / HZ, ((tag % HZ) * 1000) / HZ); +#endif if (status < 0) { - printk(KERN_WARNING "aacraid: probe_containers query failed.\n"); + printk(KERN_WARNING "aacraid: probe_container query failed.\n"); goto error; } dresp = (struct aac_mount *) fib_data(fibptr); if ((le32_to_cpu(dresp->status) == ST_OK) && + (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) { + dinfo->command = cpu_to_le32(VM_NameServe64); + dinfo->count = cpu_to_le32(cid); + dinfo->type = cpu_to_le32(FT_FILESYS); + +#if (defined(AAC_DEBUG_INSTRUMENT_VM_NAMESERVE)) + tag = jiffies; +#endif + if (fib_send(ContainerCommand, + fibptr, + sizeof(struct aac_query_mount), + FsaNormal, + 1, 1, + NULL, NULL) < 0) + goto error; +#if (defined(AAC_DEBUG_INSTRUMENT_VM_NAMESERVE)) + tag = jiffies - tag; + printk(KERN_INFO "VM_Nameserve64: %lu.%03lus\n", + tag / HZ, ((tag % HZ) * 1000) / HZ); +#endif + } else + dresp->mnt[0].capacityhigh = 0; + + if ((le32_to_cpu(dresp->status) == ST_OK) && (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { - fsa_dev_ptr->valid[cid] = 1; - fsa_dev_ptr->type[cid] = le32_to_cpu(dresp->mnt[0].vol); - fsa_dev_ptr->size[cid] = le32_to_cpu(dresp->mnt[0].capacity); + fsa_dev_ptr[cid].valid = 1; + fsa_dev_ptr[cid].type = le32_to_cpu(dresp->mnt[0].vol); + fsa_dev_ptr[cid].size + = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + + (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32); if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) - fsa_dev_ptr->ro[cid] = 1; + fsa_dev_ptr[cid].ro = 1; } error: @@ -457,6 +888,11 @@ static char *container_types[] = { "V-MIRRORS", "PSEUDO R4", "RAID50", + "RAID5D", + "RAID5D0", + "RAID1E", + "RAID6", + "RAID60", "Unknown" }; @@ -471,40 +907,68 @@ static char *container_types[] = { * files instead of in OS dependant driver source. */ -static void setinqstr(int devtype, void *data, int tindex) +static void setinqstr(struct aac_dev *dev, void *data, int tindex) { struct scsi_inq *str; - char *findit; - struct aac_driver_ident *mp; - mp = aac_get_driver_ident(devtype); - str = (struct scsi_inq *)(data); /* cast data to scsi inq block */ + memset(str, ' ', sizeof(*str)); + + if (dev->supplement_adapter_info.AdapterTypeText[0]) { + char * cp = dev->supplement_adapter_info.AdapterTypeText; + int c = sizeof(str->vid); + while (*cp && *cp != ' ' && --c) + ++cp; + c = *cp; + *cp = '\0'; + inqstrcpy (dev->supplement_adapter_info.AdapterTypeText, + str->vid); + *cp = c; + while (*cp && *cp != ' ') + ++cp; + while (*cp == ' ') + ++cp; + /* last six chars reserved for vol type */ + c = 0; + if (strlen(cp) > sizeof(str->pid)) { + c = cp[sizeof(str->pid)]; + cp[sizeof(str->pid)] = '\0'; + } + inqstrcpy (cp, str->pid); + if (c) + cp[sizeof(str->pid)] = c; + } else { + struct aac_driver_ident *mp = aac_get_driver_ident(dev->cardtype); + + inqstrcpy (mp->vname, str->vid); + /* last six chars reserved for vol type */ + inqstrcpy (mp->model, str->pid); + } - inqstrcpy (mp->vname, str->vid); - inqstrcpy (mp->model, str->pid); /* last six chars reserved for vol type */ - - findit = str->pid; - - for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */ - findit++; - if (tindex < (sizeof(container_types)/sizeof(char *))){ - inqstrcpy (container_types[tindex], findit); + char *findit = str->pid; + + for ( ; *findit != ' '; findit++); /* walk till we find a space */ + /* RAID is superfluous in the context of a RAID device */ + if (memcmp(findit-4, "RAID", 4) == 0) + *(findit -= 4) = ' '; + if (((findit - str->pid) + strlen(container_types[tindex])) + < (sizeof(str->pid) + sizeof(str->prl))) + inqstrcpy (container_types[tindex], findit + 1); } inqstrcpy ("V1.0", str->prl); } -void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code, - u8 a_sense_code, u8 incorrect_length, - u8 bit_pointer, u16 field_pointer, - u32 residue) +static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code, + u8 a_sense_code, u8 incorrect_length, + u8 bit_pointer, u16 field_pointer, + u32 residue) { sense_buf[0] = 0xF0; /* Sense data valid, err code 70h (current error) */ sense_buf[1] = 0; /* Segment number, always zero */ if (incorrect_length) { - sense_buf[2] = sense_key | 0x20; /* Set ILI bit | sense key */ + sense_buf[2] = sense_key | 0x20;/* Set ILI bit | sense key */ sense_buf[3] = BYTE3(residue); sense_buf[4] = BYTE2(residue); sense_buf[5] = BYTE1(residue); @@ -512,22 +976,22 @@ void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code, } else sense_buf[2] = sense_key; /* Sense key */ - if (sense_key == SENKEY_ILLEGAL) + if (sense_key == ILLEGAL_REQUEST) sense_buf[7] = 10; /* Additional sense length */ else sense_buf[7] = 6; /* Additional sense length */ sense_buf[12] = sense_code; /* Additional sense code */ sense_buf[13] = a_sense_code; /* Additional sense code qualifier */ - if (sense_key == SENKEY_ILLEGAL) { + if (sense_key == ILLEGAL_REQUEST) { sense_buf[15] = 0; if (sense_code == SENCODE_INVALID_PARAM_FIELD) - sense_buf[15] = 0x80; /* Std sense key specific field */ + sense_buf[15] = 0x80;/* Std sense key specific field */ /* Illegal parameter is in the parameter block */ if (sense_code == SENCODE_INVALID_CDB_FIELD) - sense_buf[15] = 0xc0; /* Std sense key specific field */ + sense_buf[15] = 0xc0;/* Std sense key specific field */ /* Illegal parameter is in the CDB block */ sense_buf[15] |= bit_pointer; sense_buf[16] = field_pointer >> 8; /* MSB */ @@ -535,62 +999,178 @@ void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code, } } -static void aac_io_done(Scsi_Cmnd * scsicmd) -{ - unsigned long cpu_flags; - spin_lock_irqsave(&io_request_lock, cpu_flags); - scsicmd->scsi_done(scsicmd); - spin_unlock_irqrestore(&io_request_lock, cpu_flags); -} - -static void __aac_io_done(Scsi_Cmnd * scsicmd) -{ - scsicmd->scsi_done(scsicmd); -} - int aac_get_adapter_info(struct aac_dev* dev) { struct fib* fibptr; - struct aac_adapter_info* info; int rcode; u32 tmp; + struct aac_adapter_info *info; + struct aac_bus_info *command; + struct aac_bus_info_response *bus_info; + if (!(fibptr = fib_alloc(dev))) return -ENOMEM; fib_init(fibptr); - info = (struct aac_adapter_info*) fib_data(fibptr); - - memset(info,0,sizeof(struct aac_adapter_info)); + info = (struct aac_adapter_info *) fib_data(fibptr); + memset(info,0,sizeof(*info)); rcode = fib_send(RequestAdapterInfo, - fibptr, - sizeof(struct aac_adapter_info), - FsaNormal, - 1, 1, - NULL, + fibptr, + sizeof(*info), + FsaNormal, + -1, 1, /* First `interrupt' command uses special wait */ + NULL, + NULL); + + if (rcode < 0) { + fib_complete(fibptr); + fib_free(fibptr); + return rcode; + } + memcpy(&dev->adapter_info, info, sizeof(*info)); + + if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) { + struct aac_supplement_adapter_info * info; + + fib_init(fibptr); + + info = (struct aac_supplement_adapter_info *) fib_data(fibptr); + + memset(info,0,sizeof(*info)); + + rcode = fib_send(RequestSupplementAdapterInfo, + fibptr, + sizeof(*info), + FsaNormal, + 1, 1, + NULL, + NULL); + + if (rcode >= 0) + memcpy(&dev->supplement_adapter_info, info, sizeof(*info)); + if ((dev->supplement_adapter_info.Version + < AAC_SIS_VERSION_V3) || + (dev->supplement_adapter_info.SlotNumber + == AAC_SIS_SLOT_UNKNOWN)) + (void)aac_adapter_sync_cmd(dev, SEND_SLOT_NUMBER, + dev->supplement_adapter_info.SlotNumber + = PCI_SLOT(dev->pdev->devfn), + 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); + } + +#if (defined(CODE_STREAM_IDENTIFIER)) + if (dev->supplement_adapter_info.FeatureBits & le32_to_cpu(AAC_FEATURE_FALCON)) { + char * info; + + fib_init(fibptr); + + info = (char *) fib_data(fibptr); + + memset(info,0,MAX_CODE_STREAM_IDENTIFIER_LENGTH); + + rcode = fib_send(RequestCompatibilityId, + fibptr, + MAX_CODE_STREAM_IDENTIFIER_LENGTH, + FsaNormal, + 1, 1, + NULL, NULL); - memcpy(&dev->adapter_info, info, sizeof(struct aac_adapter_info)); + if (rcode >= 0) + memcpy(dev->code_stream_identifier, info, + MAX_CODE_STREAM_IDENTIFIER_LENGTH); + + if (dev->code_stream_identifier[0] + && strncmp(CODE_STREAM_IDENTIFIER, + dev->code_stream_identifier, + MAX_CODE_STREAM_IDENTIFIER_LENGTH)) { + extern char aac_driver_version[]; + printk(KERN_INFO + "%s%d: Warning ! ! ! Compatibility Mismatch\n", + dev->name, dev->id); + tmp = le32_to_cpu(dev->adapter_info.kernelrev); + printk(KERN_INFO + "%s%d: Firmware=%d.%d-%d[%d], Device Driver=%s\n", + dev->name, dev->id, + tmp>>24,(tmp>>16)&0xff,tmp&0xff, + le32_to_cpu(dev->adapter_info.kernelbuild), + aac_driver_version); + printk(KERN_INFO + "%s%d: These should be a tested set to avoid possible compatibility problems.\n", + dev->name, dev->id); + } + } +#endif - tmp = dev->adapter_info.kernelrev; - printk(KERN_INFO "%s%d: kernel %d.%d.%d build %d\n", - dev->name, dev->id, - tmp>>24,(tmp>>16)&0xff,(tmp>>8)&0xff, - dev->adapter_info.kernelbuild); - tmp = dev->adapter_info.monitorrev; - printk(KERN_INFO "%s%d: monitor %d.%d.%d build %d\n", - dev->name, dev->id, - tmp>>24,(tmp>>16)&0xff,(tmp>>8)&0xff, - dev->adapter_info.monitorbuild); - tmp = dev->adapter_info.biosrev; - printk(KERN_INFO "%s%d: bios %d.%d.%d build %d\n", + /* + * GetBusInfo + */ + + fib_init(fibptr); + + bus_info = (struct aac_bus_info_response *) fib_data(fibptr); + + memset(bus_info, 0, sizeof(*bus_info)); + + command = (struct aac_bus_info *)bus_info; + + command->Command = cpu_to_le32(VM_Ioctl); + command->ObjType = cpu_to_le32(FT_DRIVE); + command->MethodId = cpu_to_le32(1); + command->CtlCmd = cpu_to_le32(GetBusInfo); + + rcode = fib_send(ContainerCommand, + fibptr, + sizeof (*bus_info), + FsaNormal, + 1, 1, + NULL, NULL); + + if (rcode >= 0 && le32_to_cpu(bus_info->Status) == ST_OK) { + dev->maximum_num_physicals = le32_to_cpu(bus_info->TargetsPerBus); + dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount); + } + + if (!dev->in_reset) { + tmp = le32_to_cpu(dev->adapter_info.kernelrev); + printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n", + dev->name, + dev->id, + tmp>>24, + (tmp>>16)&0xff, + tmp&0xff, + le32_to_cpu(dev->adapter_info.kernelbuild), + (int)sizeof(dev->supplement_adapter_info.BuildDate), + dev->supplement_adapter_info.BuildDate); + tmp = le32_to_cpu(dev->adapter_info.monitorrev); + printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n", dev->name, dev->id, - tmp>>24,(tmp>>16)&0xff,(tmp>>8)&0xff, - dev->adapter_info.biosbuild); - printk(KERN_INFO "%s%d: serial %x%x\n", + tmp>>24,(tmp>>16)&0xff,tmp&0xff, + le32_to_cpu(dev->adapter_info.monitorbuild)); + tmp = le32_to_cpu(dev->adapter_info.biosrev); + printk(KERN_INFO "%s%d: bios %d.%d-%d[%d]\n", dev->name, dev->id, - dev->adapter_info.serial[0], - dev->adapter_info.serial[1]); + tmp>>24,(tmp>>16)&0xff,tmp&0xff, + le32_to_cpu(dev->adapter_info.biosbuild)); + if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0) + printk(KERN_INFO "%s%d: serial %x\n", + dev->name, dev->id, + le32_to_cpu(dev->adapter_info.serial[0])); + } + aacraid_setup(aacraid); +#if (defined(AAC_DEBUG_INSTRUMENT_SETUP)) +#if (defined(AAC_EXTENDED_TIMEOUT)) + printk(KERN_INFO "nondasd=%d dacmode=%d commit=%d " + "coalescethreshold=%d acbsize=%d extendedtimeout=%d\n", + nondasd, dacmode, commit, coalescethreshold, acbsize, + extendedtimeout); +#else + printk(KERN_INFO "nondasd=%d dacmode=%d commit=%d " + "coalescethreshold=%d acbsize=%d\n", + nondasd, dacmode, commit, coalescethreshold, acbsize); +#endif +#endif dev->nondasd_support = 0; dev->raid_scsi_mode = 0; @@ -609,33 +1189,92 @@ int aac_get_adapter_info(struct aac_dev* dev) * function aac_detect will have to be modified where it sets up the * max number of channels based on the aac->nondasd_support flag only. */ - if ((dev->adapter_info.options & AAC_OPT_SCSI_MANAGED) - && (dev->adapter_info.options & AAC_OPT_RAID_SCSI_MODE)) - { + if ((dev->adapter_info.options & AAC_OPT_SCSI_MANAGED) && + (dev->adapter_info.options & AAC_OPT_RAID_SCSI_MODE)) { dev->nondasd_support = 1; dev->raid_scsi_mode = 1; } if (dev->raid_scsi_mode != 0) - printk(KERN_INFO "%s%d: ROMB RAID/SCSI mode enabled\n",dev->name, dev->id); + printk(KERN_INFO "%s%d: ROMB RAID/SCSI mode enabled\n", + dev->name, dev->id); - if (nondasd != -1) + if(nondasd != -1) { dev->nondasd_support = (nondasd!=0); - - if(dev->nondasd_support != 0) - printk(KERN_INFO "%s%d: Non-DASD support enabled\n",dev->name, dev->id); - - dev->pae_support = 0; - if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){ - dev->pae_support = 1; + } + if(dev->nondasd_support != 0){ + printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id); } - if(paemode != -1) - dev->pae_support = (paemode != 0); + dev->dac_support = 0; + /* + * Only enable DAC mode if the dma_addr_t is larger than 32 + * bit addressing, and we have more than 32 bit addressing worth of + * memory and if the controller supports 64 bit scatter gather elements. + */ + if( (sizeof(dma_addr_t) > 4) && (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){ + dev->dac_support = 1; + } - if(dev->pae_support != 0) - { - printk(KERN_INFO "%s%d: 64 Bit PAE enabled\n", dev->name, dev->id); - pci_set_dma_mask(dev->pdev, (dma_addr_t)0xFFFFFFFFFFFFFFFFULL); + if(dacmode != -1) { + dev->dac_support = (dacmode!=0); + } + if(dev->dac_support != 0) { + if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) && + !pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) { + printk(KERN_INFO"%s%d: 64 Bit DAC enabled\n", + dev->name, dev->id); + } else if (!pci_set_dma_mask(dev->pdev, DMA_32BIT_MASK) && + !pci_set_consistent_dma_mask(dev->pdev, DMA_32BIT_MASK)) { + printk(KERN_INFO"%s%d: DMA mask set failed, 64 Bit DAC disabled\n", + dev->name, dev->id); + dev->dac_support = 0; + } else { + printk(KERN_WARNING"%s%d: No suitable DMA available.\n", + dev->name, dev->id); + rcode = -ENOMEM; + } + } + /* + * 57 scatter gather elements + */ + if (!(dev->raw_io_interface)) { + dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - + sizeof(struct aac_fibhdr) - + sizeof(struct aac_write) + sizeof(struct sgentry)) / + sizeof(struct sgentry); + if( (sizeof(dma_addr_t) > 4) && (num_physpages >= (0xFFFFFFFFULL >> PAGE_SHIFT)) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) && (dev->dac_support) ){ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,18)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && (!defined(__arm__)) && defined(CONFIG_HIGHMEM) && ((LINUX_VERSION_CODE != KERNEL_VERSION(2,4,19)) || defined(CONFIG_HIGHIO)) + dev->scsi_host_ptr->highmem_io = 1; +#endif + /* + * 38 scatter gather elements + */ + dev->scsi_host_ptr->sg_tablesize = + (dev->max_fib_size - + sizeof(struct aac_fibhdr) - + sizeof(struct aac_write64) + + sizeof(struct sgentry64)) / + sizeof(struct sgentry64); + } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,18)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && (!defined(__arm__)) && defined(CONFIG_HIGHMEM) && ((LINUX_VERSION_CODE != KERNEL_VERSION(2,4,19)) || defined(CONFIG_HIGHIO)) + else { + dev->scsi_host_ptr->highmem_io = 0; + } +#endif + dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; + if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { + /* + * Worst case size that could cause sg overflow when + * we break up SG elements that are larger than 64KB. + * Would be nice if we could tell the SCSI layer what + * the maximum SG element size can be. Worst case is + * (sg_tablesize-1) 4KB elements with one 64KB + * element. + * 32bit -> 468 or 238KB 64bit -> 424 or 212KB + */ + dev->scsi_host_ptr->max_sectors = + (dev->scsi_host_ptr->sg_tablesize * 8) + 112; + } } fib_complete(fibptr); @@ -645,21 +1284,49 @@ int aac_get_adapter_info(struct aac_dev* dev) } -static void read_callback(void *context, struct fib * fibptr) +static void io_callback(void *context, struct fib * fibptr) { struct aac_dev *dev; struct aac_read_reply *readreply; - Scsi_Cmnd *scsicmd; - u32 lba; + struct scsi_cmnd *scsicmd; u32 cid; - scsicmd = (Scsi_Cmnd *) context; - - dev = (struct aac_dev *)scsicmd->host->hostdata; - cid =TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun); - - lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; - dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); + scsicmd = (struct scsi_cmnd *) context; + scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; + + dev = (struct aac_dev *)scsicmd->device->host->hostdata; + cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); + + if (nblank(dprintk(x))) { + u64 lba; + if ((scsicmd->cmnd[0] == WRITE_6) || /* 6 byte command */ + (scsicmd->cmnd[0] == READ_6)) + lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | + (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; +#if (defined(WRITE_16)) + else if ((scsicmd->cmnd[0] == WRITE_16) || /* 16 byte command */ + (scsicmd->cmnd[0] == READ_16)) + lba = ((u64)scsicmd->cmnd[2] << 56) | + ((u64)scsicmd->cmnd[3] << 48) | + ((u64)scsicmd->cmnd[4] << 40) | + ((u64)scsicmd->cmnd[9] << 32) | + ((u64)scsicmd->cmnd[6] << 24) | + (scsicmd->cmnd[7] << 16) | + (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; +#endif + else if ((scsicmd->cmnd[0] == WRITE_12) || /* 12 byte command */ + (scsicmd->cmnd[0] == READ_12)) + lba = ((u64)scsicmd->cmnd[2] << 24) | + (scsicmd->cmnd[3] << 16) | + (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; + else + lba = ((u64)scsicmd->cmnd[2] << 24) | + (scsicmd->cmnd[3] << 16) | + (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; + printk(KERN_DEBUG + "io_callback[cpu %d]: lba = %llu, t = %ld.\n", + smp_processor_id(), (unsigned long long)lba, jiffies); + } if (fibptr == NULL) BUG(); @@ -668,77 +1335,108 @@ static void read_callback(void *context, struct fib * fibptr) pci_unmap_sg(dev->pdev, (struct scatterlist *)scsicmd->buffer, scsicmd->use_sg, - scsi_to_pci_dma_dir(scsicmd->sc_data_direction)); + scsicmd->sc_data_direction); else if(scsicmd->request_bufflen) - pci_unmap_single(dev->pdev, (dma_addr_t)(unsigned long)scsicmd->SCp.ptr, + pci_unmap_single(dev->pdev, scsicmd->SCp.dma_handle, scsicmd->request_bufflen, - scsi_to_pci_dma_dir(scsicmd->sc_data_direction)); + scsicmd->sc_data_direction); readreply = (struct aac_read_reply *)fib_data(fibptr); if (le32_to_cpu(readreply->status) == ST_OK) - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD; + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; else { - printk(KERN_WARNING "read_callback: read failed, status = %d\n", readreply->status); - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION; - set_sense((u8 *) &sense_data[cid], - SENKEY_HW_ERR, +#ifdef AAC_DETAILED_STATUS_INFO + printk(KERN_WARNING "io_callback: io failed, status = %d\n", + le32_to_cpu(readreply->status)); +#endif + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; + set_sense((u8 *) &dev->fsa_dev[cid].sense_data, + HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, 0, 0); + memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, + (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer)) + ? sizeof(scsicmd->sense_buffer) + : sizeof(dev->fsa_dev[cid].sense_data)); } fib_complete(fibptr); fib_free(fibptr); aac_io_done(scsicmd); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + if (scsicmd->device->device_blocked) { + struct scsi_cmnd * cmd; + cid = 0; + + for (cmd = scsicmd->device->device_queue; cmd; cmd = cmd->next) + if (cmd->serial_number) + ++cid; + if (cid < scsicmd->device->queue_depth) + scsicmd->device->device_blocked = 0; + } +#endif } -static void write_callback(void *context, struct fib * fibptr) +static inline void aac_select_queue_depth( + struct scsi_cmnd * scsicmd, + int cid, + u64 lba, + u32 count) { + struct scsi_device *device = scsicmd->device; struct aac_dev *dev; - struct aac_write_reply *writereply; - Scsi_Cmnd *scsicmd; - u32 lba; - u32 cid; + unsigned depth; - scsicmd = (Scsi_Cmnd *) context; - dev = (struct aac_dev *)scsicmd->host->hostdata; - cid = TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun); - - lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; - dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); - if (fibptr == NULL) - BUG(); - - if(scsicmd->use_sg) - pci_unmap_sg(dev->pdev, - (struct scatterlist *)scsicmd->buffer, - scsicmd->use_sg, - scsi_to_pci_dma_dir(scsicmd->sc_data_direction)); - else if(scsicmd->request_bufflen) - pci_unmap_single(dev->pdev, (dma_addr_t)(unsigned long)scsicmd->SCp.ptr, - scsicmd->request_bufflen, - scsi_to_pci_dma_dir(scsicmd->sc_data_direction)); - - writereply = (struct aac_write_reply *) fib_data(fibptr); - if (le32_to_cpu(writereply->status) == ST_OK) - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD; - else { - printk(KERN_WARNING "write_callback: write failed, status = %d\n", writereply->status); - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION; - set_sense((u8 *) &sense_data[cid], - SENKEY_HW_ERR, - SENCODE_INTERNAL_TARGET_FAILURE, - ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, - 0, 0); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + if (!device->tagged_supported) + return; +#endif + dev = (struct aac_dev *)device->host->hostdata; + if (dev->fsa_dev[cid].queue_depth <= 2) + dev->fsa_dev[cid].queue_depth = device->queue_depth; + if (lba == dev->fsa_dev[cid].last) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + struct scsi_cmnd * cmd; +#endif + /* + * If larger than coalescethreshold in size, coalescing has + * less effect on overall performance. Also, if we are + * coalescing right now, leave it alone if above the threshold. + */ + if (count > coalescethreshold) + return; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + depth = 0; + + for (cmd = device->device_queue; cmd; cmd = cmd->next) + if ((cmd->serial_number) + && (cmd != scsicmd) + && (++depth > 1)) { + device->device_blocked = 1; + break; + } +#endif + depth = 2; + } else { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + device->device_blocked = 0; +#endif + depth = dev->fsa_dev[cid].queue_depth; } - - fib_complete(fibptr); - fib_free(fibptr); - aac_io_done(scsicmd); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + scsi_adjust_queue_depth(device, MSG_ORDERED_TAG, depth); +#else + device->queue_depth = depth; +#endif + dprintk((KERN_DEBUG "l=%llu %llu[%u] q=%u %lu\n", + dev->fsa_dev[cid].last, lba, count, device->queue_depth, + dev->queues->queue[AdapNormCmdQueue].numpending)); + dev->fsa_dev[cid].last = lba + count; } -int aac_read(Scsi_Cmnd * scsicmd, int cid) +static int aac_read(struct scsi_cmnd * scsicmd, int cid) { - u32 lba; + u64 lba; u32 count; int status; @@ -746,51 +1444,132 @@ int aac_read(Scsi_Cmnd * scsicmd, int cid) struct aac_dev *dev; struct fib * cmd_fibcontext; - dev = (struct aac_dev *)scsicmd->host->hostdata; + dev = (struct aac_dev *)scsicmd->device->host->hostdata; /* * Get block address and transfer length */ - if (scsicmd->cmnd[0] == SS_READ) /* 6 byte command */ +#if (defined(AAC_DEBUG_INSTRUMENT_IO)) + printk(KERN_DEBUG "aac_read: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + scsicmd->cmnd[0], scsicmd->cmnd[1], scsicmd->cmnd[2], + scsicmd->cmnd[3], scsicmd->cmnd[4], scsicmd->cmnd[5], + scsicmd->cmnd[6], scsicmd->cmnd[7], scsicmd->cmnd[8], + scsicmd->cmnd[9], scsicmd->cmnd[10], scsicmd->cmnd[11], + scsicmd->cmnd[12], scsicmd->cmnd[13], scsicmd->cmnd[14], + scsicmd->cmnd[15]); +#endif + if (scsicmd->cmnd[0] == READ_6) /* 6 byte command */ { - dprintk((KERN_DEBUG "aachba: received a read(6) command on target %d.\n", cid)); + dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", cid)); lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; count = scsicmd->cmnd[4]; if (count == 0) count = 256; +#if (defined(READ_16)) + } else if (scsicmd->cmnd[0] == READ_16) { /* 16 byte command */ + dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", cid)); + + lba = ((u64)scsicmd->cmnd[2] << 56) | + ((u64)scsicmd->cmnd[3] << 48) | + ((u64)scsicmd->cmnd[4] << 40) | + ((u64)scsicmd->cmnd[9] << 32) | + ((u64)scsicmd->cmnd[6] << 24) | + (scsicmd->cmnd[7] << 16) | + (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; + count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) | + (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13]; +#endif + } else if (scsicmd->cmnd[0] == READ_12) { /* 12 byte command */ + dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", cid)); + + lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) + | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; + count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16) + | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; } else { - dprintk((KERN_DEBUG "aachba: received a read(10) command on target %d.\n", cid)); + dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", cid)); - lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; + lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; } - dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); + dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n", + smp_processor_id(), (unsigned long long)lba, jiffies)); + if ((!(dev->raw_io_interface) || !(dev->raw_io_64)) && + (lba & 0xffffffff00000000LL)) { + dprintk((KERN_DEBUG "aac_read: Illegal lba\n")); + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | + SAM_STAT_CHECK_CONDITION; + set_sense((u8 *) &dev->fsa_dev[cid].sense_data, + HARDWARE_ERROR, + SENCODE_INTERNAL_TARGET_FAILURE, + ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, + 0, 0); + memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, + (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer)) + ? sizeof(scsicmd->sense_buffer) + : sizeof(dev->fsa_dev[cid].sense_data)); +#if (defined(AAC_DEBUG_INSTRUMENT_TIMING)) + __aac_io_done(scsicmd); +#else + scsicmd->scsi_done(scsicmd); +#endif + return 0; + } + /* + * Are we in a sequential mode? + */ + aac_select_queue_depth(scsicmd, cid, lba, count); /* * Alocate and initialize a Fib */ if (!(cmd_fibcontext = fib_alloc(dev))) { - scsicmd->result = DID_ERROR << 16; - aac_io_done(scsicmd); - return (-1); + return -1; } fib_init(cmd_fibcontext); - if(dev->pae_support == 1){ + if (dev->raw_io_interface) { + struct aac_raw_io *readcmd; + readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); + readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); + readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); + readcmd->count = cpu_to_le32(count<<9); + readcmd->cid = cpu_to_le16(cid); + readcmd->flags = cpu_to_le16(1); + readcmd->bpTotal = 0; + readcmd->bpComplete = 0; + + aac_build_sgraw(scsicmd, &readcmd->sg); + fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw)); + if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) + BUG(); + /* + * Now send the Fib to the adapter + */ + status = fib_send(ContainerRawIo, + cmd_fibcontext, + fibsize, + FsaNormal, + 0, 1, + (fib_callback) io_callback, + (void *) scsicmd); + } else if (dev->dac_support == 1) { struct aac_read64 *readcmd; readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext); readcmd->command = cpu_to_le32(VM_CtHostRead64); readcmd->cid = cpu_to_le16(cid); readcmd->sector_count = cpu_to_le16(count); - readcmd->block = cpu_to_le32(lba); - readcmd->pad = cpu_to_le16(0); - readcmd->flags = cpu_to_le16(0); - + readcmd->block = cpu_to_le32((u32)(lba&0xffffffff)); + readcmd->pad = 0; + readcmd->flags = 0; + aac_build_sg64(scsicmd, &readcmd->sg); - if(readcmd->sg.count > MAX_DRIVER_SG_SEGMENT_COUNT) - BUG(); - fibsize = sizeof(struct aac_read64) + ((readcmd->sg.count - 1) * sizeof (struct sgentry64)); + fibsize = sizeof(struct aac_read64) + + ((le32_to_cpu(readcmd->sg.count) - 1) * + sizeof (struct sgentry64)); + BUG_ON (fibsize > (dev->max_fib_size - + sizeof(struct aac_fibhdr))); /* * Now send the Fib to the adapter */ @@ -799,23 +1578,22 @@ int aac_read(Scsi_Cmnd * scsicmd, int cid) fibsize, FsaNormal, 0, 1, - (fib_callback) read_callback, + (fib_callback) io_callback, (void *) scsicmd); } else { struct aac_read *readcmd; readcmd = (struct aac_read *) fib_data(cmd_fibcontext); readcmd->command = cpu_to_le32(VM_CtBlockRead); readcmd->cid = cpu_to_le32(cid); - readcmd->block = cpu_to_le32(lba); + readcmd->block = cpu_to_le32((u32)(lba&0xffffffff)); readcmd->count = cpu_to_le32(count * 512); - if (count * 512 > (64 * 1024)) - BUG(); - aac_build_sg(scsicmd, &readcmd->sg); - if(readcmd->sg.count > MAX_DRIVER_SG_SEGMENT_COUNT) - BUG(); - fibsize = sizeof(struct aac_read) + ((readcmd->sg.count - 1) * sizeof (struct sgentry)); + fibsize = sizeof(struct aac_read) + + ((le32_to_cpu(readcmd->sg.count) - 1) * + sizeof (struct sgentry)); + BUG_ON (fibsize > (dev->max_fib_size - + sizeof(struct aac_fibhdr))); /* * Now send the Fib to the adapter */ @@ -824,78 +1602,162 @@ int aac_read(Scsi_Cmnd * scsicmd, int cid) fibsize, FsaNormal, 0, 1, - (fib_callback) read_callback, + (fib_callback) io_callback, (void *) scsicmd); } + - + /* * Check that the command queued to the controller */ - if (status == -EINPROGRESS) + if (status == -EINPROGRESS) { + scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; return 0; + } printk(KERN_WARNING "aac_read: 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 | QUEUE_FULL; + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL; aac_io_done(scsicmd); fib_complete(cmd_fibcontext); fib_free(cmd_fibcontext); - return -1; + return 0; } -static int aac_write(Scsi_Cmnd * scsicmd, int cid) +static int aac_write(struct scsi_cmnd * scsicmd, int cid) { - u32 lba; + u64 lba; u32 count; int status; u16 fibsize; struct aac_dev *dev; struct fib * cmd_fibcontext; - dev = (struct aac_dev *)scsicmd->host->hostdata; + dev = (struct aac_dev *)scsicmd->device->host->hostdata; /* * Get block address and transfer length */ - if (scsicmd->cmnd[0] == SS_WRITE) /* 6 byte command */ +#if (defined(AAC_DEBUG_INSTRUMENT_IO)) + printk(KERN_DEBUG "aac_write: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + scsicmd->cmnd[0], scsicmd->cmnd[1], scsicmd->cmnd[2], + scsicmd->cmnd[3], scsicmd->cmnd[4], scsicmd->cmnd[5], + scsicmd->cmnd[6], scsicmd->cmnd[7], scsicmd->cmnd[8], + scsicmd->cmnd[9], scsicmd->cmnd[10], scsicmd->cmnd[11], + scsicmd->cmnd[12], scsicmd->cmnd[13], scsicmd->cmnd[14], + scsicmd->cmnd[15]); +#endif + if (scsicmd->cmnd[0] == WRITE_6) /* 6 byte command */ { lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; count = scsicmd->cmnd[4]; if (count == 0) count = 256; +#if (defined(WRITE_16)) + } else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */ + dprintk((KERN_DEBUG "aachba: received a write(16) command on id