Annotation of Gnu-Mach/i386/i386at/gpl/linux/scsi/BusLogic.c, revision 1.1.1.1

1.1       root        1: /*
                      2: 
                      3:   Linux Driver for BusLogic MultiMaster SCSI Host Adapters
                      4: 
                      5:   Copyright 1995 by Leonard N. Zubkoff <[email protected]>
                      6: 
                      7:   This program is free software; you may redistribute and/or modify it under
                      8:   the terms of the GNU General Public License Version 2 as published by the
                      9:   Free Software Foundation, provided that none of the source code or runtime
                     10:   copyright notices are removed or modified.
                     11: 
                     12:   This program is distributed in the hope that it will be useful, but
                     13:   WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
                     14:   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     15:   for complete details.
                     16: 
                     17:   The author respectfully requests that all modifications to this software be
                     18:   sent directly to him for evaluation and testing.
                     19: 
                     20:   Special thanks to Alex T. Win of BusLogic, whose advice has been invaluable,
                     21:   to David B. Gentzel, for writing the original Linux BusLogic driver, and to
                     22:   Paul Gortmaker, for being such a dedicated test site.
                     23: 
                     24: */
                     25: 
                     26: 
                     27: #define BusLogic_DriverVersion         "1.3.1"
                     28: #define BusLogic_DriverDate            "31 December 1995"
                     29: 
                     30: 
                     31: #include <linux/module.h>
                     32: #include <linux/config.h>
                     33: #include <linux/types.h>
                     34: #include <linux/blkdev.h>
                     35: #include <linux/delay.h>
                     36: #include <linux/ioport.h>
                     37: #include <linux/kernel_stat.h>
                     38: #include <linux/mm.h>
                     39: #include <linux/sched.h>
                     40: #include <linux/stat.h>
                     41: #include <linux/pci.h>
                     42: #include <linux/bios32.h>
                     43: #include <asm/dma.h>
                     44: #include <asm/io.h>
                     45: #include <asm/system.h>
                     46: #include "scsi.h"
                     47: #include "hosts.h"
                     48: #include "sd.h"
                     49: #include "BusLogic.h"
                     50: 
                     51: 
                     52: /*
                     53:   BusLogic_CommandLineEntryCount is a count of the number of "BusLogic="
                     54:   entries provided on the Linux Kernel Command Line.
                     55: */
                     56: 
                     57: static int
                     58:   BusLogic_CommandLineEntryCount =     0;
                     59: 
                     60: 
                     61: /*
                     62:   BusLogic_CommandLineEntries is an array of Command Line Entry structures
                     63:   representing the "BusLogic=" entries provided on the Linux Kernel Command
                     64:   Line.
                     65: */
                     66: 
                     67: static BusLogic_CommandLineEntry_T
                     68:   BusLogic_CommandLineEntries[BusLogic_MaxHostAdapters];
                     69: 
                     70: 
                     71: /*
                     72:   BusLogic_GlobalOptions is a bit mask of Global Options to be applied
                     73:   across all Host Adapters.
                     74: */
                     75: 
                     76: static int
                     77:   BusLogic_GlobalOptions =             0;
                     78: 
                     79: 
                     80: /*
                     81:   BusLogic_RegisteredHostAdapters is a linked list of all the registered
                     82:   BusLogic Host Adapters.
                     83: */
                     84: 
                     85: static BusLogic_HostAdapter_T
                     86:   *BusLogic_RegisteredHostAdapters =   NULL;
                     87: 
                     88: 
                     89: /*
                     90:   BusLogic_Standard_IO_Addresses is the list of standard I/O Addresses at which
                     91:   BusLogic Host Adapters may potentially be found.
                     92: */
                     93: 
                     94: static unsigned short
                     95:   BusLogic_IO_StandardAddresses[] =
                     96:     { 0x330, 0x334, 0x230, 0x234, 0x130, 0x134, 0 };
                     97: 
                     98: 
                     99: /*
                    100:   BusLogic_IO_AddressProbeList is the list of I/O Addresses to be probed for
                    101:   potential BusLogic Host Adapters.  It is initialized by interrogating the
                    102:   PCI Configuration Space on PCI machines as well as from the list of
                    103:   standard BusLogic I/O Addresses.
                    104: */
                    105: 
                    106: static unsigned short
                    107:   BusLogic_IO_AddressProbeList[BusLogic_IO_MaxProbeAddresses+1] =   { 0 };
                    108: 
                    109: 
                    110: /*
                    111:   BusLogic_IRQ_UsageCount stores a count of the number of Host Adapters using
                    112:   a given IRQ Channel, which is necessary to support PCI, EISA, or MCA shared
                    113:   interrupts.  Only IRQ Channels 9, 10, 11, 12, 14, and 15 are supported by
                    114:   BusLogic Host Adapters.
                    115: */
                    116: 
                    117: static short
                    118:   BusLogic_IRQ_UsageCount[7] =         { 0 };
                    119: 
                    120: 
                    121: /*
                    122:   BusLogic_CommandFailureReason holds a string identifying the reason why a
                    123:   call to BusLogic_Command failed.  It is only valid when BusLogic_Command
                    124:   returns a failure code.
                    125: */
                    126: 
                    127: static char
                    128:   *BusLogic_CommandFailureReason;
                    129: 
                    130: 
                    131: /*
                    132:   BusLogic_ProcDirectoryEntry is the BusLogic /proc/scsi directory entry.
                    133: */
                    134: 
                    135: static struct proc_dir_entry
                    136:   BusLogic_ProcDirectoryEntry =
                    137:     { PROC_SCSI_BUSLOGIC, 8, "BusLogic", S_IFDIR | S_IRUGO | S_IXUGO, 2 };
                    138: 
                    139: 
                    140: /*
                    141:   BusLogic_AnnounceDriver announces the Driver Version and Date, Author's
                    142:   Name, Copyright Notice, and Contact Address.
                    143: */
                    144: 
                    145: static void BusLogic_AnnounceDriver(void)
                    146: {
                    147:   static boolean DriverAnnouncementPrinted = false;
                    148:   if (DriverAnnouncementPrinted) return;
                    149:   printk("scsi: ***** BusLogic SCSI Driver Version "
                    150:         BusLogic_DriverVersion " of " BusLogic_DriverDate " *****\n");
                    151:   printk("scsi: Copyright 1995 by Leonard N. Zubkoff <[email protected]>\n");
                    152:   DriverAnnouncementPrinted = true;
                    153: }
                    154: 
                    155: 
                    156: /*
                    157:   BusLogic_DriverInfo returns the Board Name to identify this SCSI Driver
                    158:   and Host Adapter.
                    159: */
                    160: 
                    161: const char *BusLogic_DriverInfo(SCSI_Host_T *Host)
                    162: {
                    163:   BusLogic_HostAdapter_T *HostAdapter =
                    164:     (BusLogic_HostAdapter_T *) Host->hostdata;
                    165:   return HostAdapter->BoardName;
                    166: }
                    167: 
                    168: 
                    169: /*
                    170:   BusLogic_InitializeAddressProbeList initializes the list of I/O Addresses
                    171:   to be probed for potential BusLogic SCSI Host Adapters by interrogating the
                    172:   PCI Configuration Space on PCI machines as well as from the list of standard
                    173:   BusLogic I/O Addresses.
                    174: */
                    175: 
                    176: static void BusLogic_InitializeAddressProbeList(void)
                    177: {
                    178:   int DestinationIndex = 0, SourceIndex = 0;
                    179:   /*
                    180:     If BusLogic_Setup has been called, do not override the Kernel Command
                    181:     Line specifications.
                    182:   */
                    183:   if (BusLogic_IO_AddressProbeList[0] != 0) return;
                    184: #ifdef CONFIG_PCI
                    185:   /*
                    186:     Interrogate PCI Configuration Space for any BusLogic SCSI Host Adapters.
                    187:   */
                    188:   if (pcibios_present())
                    189:     {
                    190:       unsigned short Index = 0, VendorID;
                    191:       unsigned char Bus, DeviceAndFunction;
                    192:       unsigned int BaseAddress0;
                    193:       while (pcibios_find_class(PCI_CLASS_STORAGE_SCSI<<8, Index++,
                    194:                                &Bus, &DeviceAndFunction) == 0)
                    195:        if (pcibios_read_config_word(Bus, DeviceAndFunction,
                    196:                                     PCI_VENDOR_ID, &VendorID) == 0 &&
                    197:            VendorID == PCI_VENDOR_ID_BUSLOGIC &&
                    198:            pcibios_read_config_dword(Bus, DeviceAndFunction,
                    199:                                      PCI_BASE_ADDRESS_0, &BaseAddress0) == 0 &&
                    200:            (BaseAddress0 & PCI_BASE_ADDRESS_SPACE) ==
                    201:              PCI_BASE_ADDRESS_SPACE_IO)
                    202:          {
                    203:            BusLogic_IO_AddressProbeList[DestinationIndex++] =
                    204:              BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
                    205:          }
                    206:     }
                    207: #endif
                    208:   /*
                    209:     Append the list of standard BusLogic I/O Addresses.
                    210:   */
                    211:   while (DestinationIndex < BusLogic_IO_MaxProbeAddresses &&
                    212:         BusLogic_IO_StandardAddresses[SourceIndex] > 0)
                    213:     BusLogic_IO_AddressProbeList[DestinationIndex++] =
                    214:       BusLogic_IO_StandardAddresses[SourceIndex++];
                    215:   BusLogic_IO_AddressProbeList[DestinationIndex] = 0;
                    216: }
                    217: 
                    218: 
                    219: /*
                    220:   BusLogic_RegisterHostAdapter adds Host Adapter to the list of registered
                    221:   BusLogic Host Adapters.
                    222: */
                    223: 
                    224: static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
                    225: {
                    226:   HostAdapter->Next = NULL;
                    227:   if (BusLogic_RegisteredHostAdapters != NULL)
                    228:     {
                    229:       BusLogic_HostAdapter_T *LastHostAdapter = BusLogic_RegisteredHostAdapters;
                    230:       BusLogic_HostAdapter_T *NextHostAdapter;
                    231:       while ((NextHostAdapter = LastHostAdapter->Next) != NULL)
                    232:        LastHostAdapter = NextHostAdapter;
                    233:       LastHostAdapter->Next = HostAdapter;
                    234:     }
                    235:   else BusLogic_RegisteredHostAdapters = HostAdapter;
                    236: }
                    237: 
                    238: 
                    239: /*
                    240:   BusLogic_UnregisterHostAdapter removes Host Adapter from the list of
                    241:   registered BusLogic Host Adapters.
                    242: */
                    243: 
                    244: static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
                    245: {
                    246:   if (BusLogic_RegisteredHostAdapters != HostAdapter)
                    247:     {
                    248:       BusLogic_HostAdapter_T *LastHostAdapter = BusLogic_RegisteredHostAdapters;
                    249:       while (LastHostAdapter != NULL && LastHostAdapter->Next != HostAdapter)
                    250:        LastHostAdapter = LastHostAdapter->Next;
                    251:       if (LastHostAdapter != NULL)
                    252:        LastHostAdapter->Next = HostAdapter->Next;
                    253:     }
                    254:   else BusLogic_RegisteredHostAdapters = HostAdapter->Next;
                    255:   HostAdapter->Next = NULL;
                    256: }
                    257: 
                    258: 
                    259: /*
                    260:   BusLogic_CreateCCBs allocates the initial Command Control Blocks (CCBs)
                    261:   for Host Adapter.
                    262: */
                    263: 
                    264: static boolean BusLogic_CreateCCBs(BusLogic_HostAdapter_T *HostAdapter)
                    265: {
                    266:   int i;
                    267:   for (i = 0; i < BusLogic_InitialCCBs; i++)
                    268:     {
                    269:       BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
                    270:        scsi_init_malloc(sizeof(BusLogic_CCB_T), GFP_ATOMIC | GFP_DMA);
                    271:       if (CCB == NULL)
                    272:        {
                    273:          printk("scsi%d: UNABLE TO ALLOCATE CCB %d - DETACHING\n",
                    274:                 HostAdapter->HostNumber, i);
                    275:          return false;
                    276:        }
                    277:       memset(CCB, 0, sizeof(BusLogic_CCB_T));
                    278:       CCB->HostAdapter = HostAdapter;
                    279:       CCB->Status = BusLogic_CCB_Free;
                    280:       CCB->Next = HostAdapter->Free_CCBs;
                    281:       CCB->NextAll = HostAdapter->All_CCBs;
                    282:       HostAdapter->Free_CCBs = CCB;
                    283:       HostAdapter->All_CCBs = CCB;
                    284:     }
                    285:   return true;
                    286: }
                    287: 
                    288: 
                    289: /*
                    290:   BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
                    291: */
                    292: 
                    293: static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *HostAdapter)
                    294: {
                    295:   BusLogic_CCB_T *NextCCB = HostAdapter->All_CCBs, *CCB;
                    296:   HostAdapter->All_CCBs = NULL;
                    297:   HostAdapter->Free_CCBs = NULL;
                    298:   while ((CCB = NextCCB) != NULL)
                    299:     {
                    300:       NextCCB = CCB->NextAll;
                    301:       scsi_init_free((char *) CCB, sizeof(BusLogic_CCB_T));
                    302:     }
                    303: }
                    304: 
                    305: 
                    306: /*
                    307:   BusLogic_AllocateCCB allocates a CCB from the Host Adapter's free list,
                    308:   allocating more memory from the Kernel if necessary.
                    309: */
                    310: 
                    311: static BusLogic_CCB_T *BusLogic_AllocateCCB(BusLogic_HostAdapter_T *HostAdapter)
                    312: {
                    313:   static unsigned int SerialNumber = 0;
                    314:   BusLogic_CCB_T *CCB;
                    315:   BusLogic_LockHostAdapter(HostAdapter);
                    316:   CCB = HostAdapter->Free_CCBs;
                    317:   if (CCB != NULL)
                    318:     {
                    319:       CCB->SerialNumber = ++SerialNumber;
                    320:       HostAdapter->Free_CCBs = CCB->Next;
                    321:       CCB->Next = NULL;
                    322:       BusLogic_UnlockHostAdapter(HostAdapter);
                    323:       return CCB;
                    324:     }
                    325:   BusLogic_UnlockHostAdapter(HostAdapter);
                    326:   CCB = (BusLogic_CCB_T *) scsi_init_malloc(sizeof(BusLogic_CCB_T),
                    327:                                            GFP_ATOMIC | GFP_DMA);
                    328:   if (CCB == NULL)
                    329:     {
                    330:       printk("scsi%d: Failed to allocate an additional CCB\n",
                    331:             HostAdapter->HostNumber);
                    332:       return NULL;
                    333:     }
                    334:   printk("scsi%d: Allocated an additional CCB\n", HostAdapter->HostNumber);
                    335:   memset(CCB, 0, sizeof(BusLogic_CCB_T));
                    336:   CCB->HostAdapter = HostAdapter;
                    337:   CCB->Status = BusLogic_CCB_Free;
                    338:   BusLogic_LockHostAdapter(HostAdapter);
                    339:   CCB->SerialNumber = ++SerialNumber;
                    340:   CCB->NextAll = HostAdapter->All_CCBs;
                    341:   HostAdapter->All_CCBs = CCB;
                    342:   BusLogic_UnlockHostAdapter(HostAdapter);
                    343:   return CCB;
                    344: }
                    345: 
                    346: 
                    347: /*
                    348:   BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's
                    349:   free list.
                    350: */
                    351: 
                    352: static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB)
                    353: {
                    354:   BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
                    355:   BusLogic_LockHostAdapter(HostAdapter);
                    356:   CCB->Command = NULL;
                    357:   CCB->Status = BusLogic_CCB_Free;
                    358:   CCB->Next = HostAdapter->Free_CCBs;
                    359:   HostAdapter->Free_CCBs = CCB;
                    360:   BusLogic_UnlockHostAdapter(HostAdapter);
                    361: }
                    362: 
                    363: 
                    364: /*
                    365:   BusLogic_Command sends the command OperationCode to HostAdapter, optionally
                    366:   providing ParameterLength bytes of ParameterData and receiving at most
                    367:   ReplyLength bytes of ReplyData; any excess reply data is received but
                    368:   discarded.
                    369: 
                    370:   On success, this function returns the number of reply bytes read from
                    371:   the Host Adapter (including any discarded data); on failure, it returns
                    372:   -1 if the command was invalid, or -2 if a timeout occurred.
                    373: 
                    374:   This function is only called during board detection and initialization, so
                    375:   performance and latency are not critical, and exclusive access to the Host
                    376:   Adapter hardware is assumed.  Once the board and driver are initialized, the
                    377:   only Host Adapter command that is issued is the single byte Start Mailbox
                    378:   Scan command, which does not require waiting for the Host Adapter Ready bit
                    379:   to be set in the Status Register.
                    380: */
                    381: 
                    382: static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
                    383:                            BusLogic_OperationCode_T OperationCode,
                    384:                            void *ParameterData,
                    385:                            int ParameterLength,
                    386:                            void *ReplyData,
                    387:                            int ReplyLength)
                    388: {
                    389:   unsigned char *ParameterPointer = (unsigned char *) ParameterData;
                    390:   unsigned char *ReplyPointer = (unsigned char *) ReplyData;
                    391:   unsigned char StatusRegister = 0, InterruptRegister;
                    392:   long TimeoutCounter;
                    393:   int ReplyBytes = 0;
                    394:   /*
                    395:     Clear out the Reply Data if provided.
                    396:   */
                    397:   if (ReplyLength > 0)
                    398:     memset(ReplyData, 0, ReplyLength);
                    399:   /*
                    400:     Wait for the Host Adapter Ready bit to be set and the Command/Parameter
                    401:     Register Busy bit to be reset in the Status Register.
                    402:   */
                    403:   TimeoutCounter = loops_per_sec >> 3;
                    404:   while (--TimeoutCounter >= 0)
                    405:     {
                    406:       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
                    407:       if ((StatusRegister & BusLogic_HostAdapterReady) &&
                    408:          !(StatusRegister & BusLogic_CommandParameterRegisterBusy))
                    409:        break;
                    410:     }
                    411:   BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
                    412:   if (TimeoutCounter < 0) return -2;
                    413:   /*
                    414:     Write the OperationCode to the Command/Parameter Register.
                    415:   */
                    416:   HostAdapter->HostAdapterCommandCompleted = false;
                    417:   BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
                    418:   /*
                    419:     Write any additional Parameter Bytes.
                    420:   */
                    421:   TimeoutCounter = 10000;
                    422:   while (ParameterLength > 0 && --TimeoutCounter >= 0)
                    423:     {
                    424:       /*
                    425:        Wait 100 microseconds to give the Host Adapter enough time to determine
                    426:        whether the last value written to the Command/Parameter Register was
                    427:        valid or not.  If the Command Complete bit is set in the Interrupt
                    428:        Register, then the Command Invalid bit in the Status Register will be
                    429:        reset if the Operation Code or Parameter was valid and the command
                    430:        has completed, or set if the Operation Code or Parameter was invalid.
                    431:        If the Data In Register Ready bit is set in the Status Register, then
                    432:        the Operation Code was valid, and data is waiting to be read back
                    433:        from the Host Adapter.  Otherwise, wait for the Command/Parameter
                    434:        Register Busy bit in the Status Register to be reset.
                    435:       */
                    436:       udelay(100);
                    437:       InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
                    438:       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
                    439:       if (InterruptRegister & BusLogic_CommandComplete) break;
                    440:       if (HostAdapter->HostAdapterCommandCompleted) break;
                    441:       if (StatusRegister & BusLogic_DataInRegisterReady) break;
                    442:       if (StatusRegister & BusLogic_CommandParameterRegisterBusy) continue;
                    443:       BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
                    444:       ParameterLength--;
                    445:     }
                    446:   BusLogic_CommandFailureReason = "Timeout waiting for Parameter Acceptance";
                    447:   if (TimeoutCounter < 0) return -2;
                    448:   /*
                    449:     The Modify I/O Address command does not cause a Command Complete Interrupt.
                    450:   */
                    451:   if (OperationCode == BusLogic_ModifyIOAddress)
                    452:     {
                    453:       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
                    454:       BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
                    455:       if (StatusRegister & BusLogic_CommandInvalid) return -1;
                    456:       BusLogic_CommandFailureReason = NULL;
                    457:       return 0;
                    458:     }
                    459:   /*
                    460:     Select an appropriate timeout value for awaiting command completion.
                    461:   */
                    462:   switch (OperationCode)
                    463:     {
                    464:     case BusLogic_InquireInstalledDevicesID0to7:
                    465:     case BusLogic_InquireInstalledDevicesID8to15:
                    466:       /* Approximately 60 seconds. */
                    467:       TimeoutCounter = loops_per_sec << 2;
                    468:       break;
                    469:     default:
                    470:       /* Approximately 1 second. */
                    471:       TimeoutCounter = loops_per_sec >> 4;
                    472:       break;
                    473:     }
                    474:   /*
                    475:     Receive any Reply Bytes, waiting for either the Command Complete bit to
                    476:     be set in the Interrupt Register, or for the Interrupt Handler to set the
                    477:     Host Adapter Command Completed bit in the Host Adapter structure.
                    478:   */
                    479:   while (--TimeoutCounter >= 0)
                    480:     {
                    481:       InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
                    482:       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
                    483:       if (InterruptRegister & BusLogic_CommandComplete) break;
                    484:       if (HostAdapter->HostAdapterCommandCompleted) break;
                    485:       if (StatusRegister & BusLogic_DataInRegisterReady)
                    486:        if (++ReplyBytes <= ReplyLength)
                    487:          *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
                    488:        else BusLogic_ReadDataInRegister(HostAdapter);
                    489:     }
                    490:   BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
                    491:   if (TimeoutCounter < 0) return -2;
                    492:   /*
                    493:     If testing Command Complete Interrupts, wait a short while in case the
                    494:     loop immediately above terminated due to the Command Complete bit being
                    495:     set in the Interrupt Register, but the interrupt hasn't actually been
                    496:     processed yet.  Otherwise, acknowledging the interrupt here could prevent
                    497:     the interrupt test from succeeding.
                    498:   */
                    499:   if (OperationCode == BusLogic_TestCommandCompleteInterrupt)
                    500:     udelay(10000);
                    501:   /*
                    502:     Clear any pending Command Complete Interrupt.
                    503:   */
                    504:   BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
                    505:   if (BusLogic_GlobalOptions & BusLogic_TraceConfiguration)
                    506:     if (OperationCode != BusLogic_TestCommandCompleteInterrupt)
                    507:       {
                    508:        int i;
                    509:        printk("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:",
                    510:               OperationCode, StatusRegister, ReplyLength, ReplyBytes);
                    511:        if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes;
                    512:        for (i = 0; i < ReplyLength; i++)
                    513:          printk(" %02X", ((unsigned char *) ReplyData)[i]);
                    514:        printk("\n");
                    515:       }
                    516:   /*
                    517:     Process Command Invalid conditions.
                    518:   */
                    519:   if (StatusRegister & BusLogic_CommandInvalid)
                    520:     {
                    521:       /*
                    522:        Some early BusLogic Host Adapters may not recover properly from
                    523:        a Command Invalid condition, so if this appears to be the case,
                    524:        a Soft Reset is issued to the Host Adapter.  Potentially invalid
                    525:        commands are never attempted after Mailbox Initialization is
                    526:        performed, so there should be no Host Adapter state lost by a
                    527:        Soft Reset in response to a Command Invalid condition.
                    528:       */
                    529:       udelay(1000);
                    530:       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
                    531:       if (StatusRegister != (BusLogic_HostAdapterReady |
                    532:                             BusLogic_InitializationRequired))
                    533:        {
                    534:          BusLogic_WriteControlRegister(HostAdapter, BusLogic_SoftReset);
                    535:          udelay(1000);
                    536:        }
                    537:       BusLogic_CommandFailureReason = "Command Invalid";
                    538:       return -1;
                    539:     }
                    540:   /*
                    541:     Handle Excess Parameters Supplied conditions.
                    542:   */
                    543:   BusLogic_CommandFailureReason = "Excess Parameters Supplied";
                    544:   if (ParameterLength > 0) return -1;
                    545:   /*
                    546:     Indicate the command completed successfully.
                    547:   */
                    548:   BusLogic_CommandFailureReason = NULL;
                    549:   return ReplyBytes;
                    550: }
                    551: 
                    552: 
                    553: /*
                    554:   BusLogic_Failure prints a standardized error message, and then returns false.
                    555: */
                    556: 
                    557: static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter,
                    558:                                char *ErrorMessage)
                    559: {
                    560:   BusLogic_AnnounceDriver();
                    561:   printk("While configuring BusLogic Host Adapter at I/O Address 0x%X:\n",
                    562:         HostAdapter->IO_Address);
                    563:   printk("%s FAILED - DETACHING\n", ErrorMessage);
                    564:   if (BusLogic_CommandFailureReason != NULL)
                    565:     printk("ADDITIONAL FAILURE INFO - %s\n", BusLogic_CommandFailureReason);
                    566:   return false;
                    567: }
                    568: 
                    569: 
                    570: /*
                    571:   BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
                    572: */
                    573: 
                    574: static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
                    575: {
                    576:   boolean TraceProbe = (BusLogic_GlobalOptions & BusLogic_TraceProbe);
                    577:   unsigned char StatusRegister, GeometryRegister;
                    578:   /*
                    579:     Read the Status Register to test if there is an I/O port that responds.  A
                    580:     nonexistent I/O port will return 0xFF, in which case there is definitely no
                    581:     BusLogic Host Adapter at this base I/O Address.
                    582:   */
                    583:   StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
                    584:   if (TraceProbe)
                    585:     printk("BusLogic_Probe(0x%X): Status 0x%02X\n",
                    586:           HostAdapter->IO_Address, StatusRegister);
                    587:   if (StatusRegister == 0xFF) return false;
                    588:   /*
                    589:     Read the undocumented BusLogic Geometry Register to test if there is an I/O
                    590:     port that responds.  Adaptec Host Adapters do not implement the Geometry
                    591:     Register, so this test helps serve to avoid incorrectly recognizing an
                    592:     Adaptec 1542A or 1542B as a BusLogic.  Unfortunately, the Adaptec 1542C
                    593:     series does respond to the Geometry Register I/O port, but it will be
                    594:     rejected later when the Inquire Extended Setup Information command is
                    595:     issued in BusLogic_CheckHostAdapter.  The AMI FastDisk Host Adapter is a
                    596:     BusLogic clone that implements the same interface as earlier BusLogic
                    597:     boards, including the undocumented commands, and is therefore supported by
                    598:     this driver.  However, the AMI FastDisk always returns 0x00 upon reading
                    599:     the Geometry Register, so the extended translation option should always be
                    600:     left disabled on the AMI FastDisk.
                    601:   */
                    602:   GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
                    603:   if (TraceProbe)
                    604:     printk("BusLogic_Probe(0x%X): Geometry 0x%02X\n",
                    605:           HostAdapter->IO_Address, GeometryRegister);
                    606:   if (GeometryRegister == 0xFF) return false;
                    607:   /*
                    608:     Indicate the Host Adapter Probe completed successfully.
                    609:   */
                    610:   return true;
                    611: }
                    612: 
                    613: 
                    614: /*
                    615:   BusLogic_HardResetHostAdapter issues a Hard Reset to the Host Adapter,
                    616:   and waits for Host Adapter Diagnostics to complete.
                    617: */
                    618: 
                    619: static boolean BusLogic_HardResetHostAdapter(BusLogic_HostAdapter_T
                    620:                                             *HostAdapter)
                    621: {
                    622:   boolean TraceHardReset = (BusLogic_GlobalOptions & BusLogic_TraceHardReset);
                    623:   long TimeoutCounter = loops_per_sec >> 2;
                    624:   unsigned char StatusRegister = 0;
                    625:   /*
                    626:     Issue a Hard Reset Command to the Host Adapter.  The Host Adapter should
                    627:     respond by setting Diagnostic Active in the Status Register.
                    628:   */
                    629:   BusLogic_WriteControlRegister(HostAdapter, BusLogic_HardReset);
                    630:   /*
                    631:     Wait until Diagnostic Active is set in the Status Register.
                    632:   */
                    633:   while (--TimeoutCounter >= 0)
                    634:     {
                    635:       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
                    636:       if ((StatusRegister & BusLogic_DiagnosticActive)) break;
                    637:     }
                    638:   if (TraceHardReset)
                    639:     printk("BusLogic_HardReset(0x%X): Diagnostic Active, Status 0x%02X\n",
                    640:           HostAdapter->IO_Address, StatusRegister);
                    641:   if (TimeoutCounter < 0) return false;
                    642:   /*
                    643:     Wait 100 microseconds to allow completion of any initial diagnostic
                    644:     activity which might leave the contents of the Status Register
                    645:     unpredictable.
                    646:   */
                    647:   udelay(100);
                    648:   /*
                    649:     Wait until Diagnostic Active is reset in the Status Register.
                    650:   */
                    651:   while (--TimeoutCounter >= 0)
                    652:     {
                    653:       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
                    654:       if (!(StatusRegister & BusLogic_DiagnosticActive)) break;
                    655:     }
                    656:   if (TraceHardReset)
                    657:     printk("BusLogic_HardReset(0x%X): Diagnostic Completed, Status 0x%02X\n",
                    658:           HostAdapter->IO_Address, StatusRegister);
                    659:   if (TimeoutCounter < 0) return false;
                    660:   /*
                    661:     Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
                    662:     or Data In Register Ready bits is set in the Status Register.
                    663:   */
                    664:   while (--TimeoutCounter >= 0)
                    665:     {
                    666:       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
                    667:       if (StatusRegister & (BusLogic_DiagnosticFailure |
                    668:                            BusLogic_HostAdapterReady |
                    669:                            BusLogic_DataInRegisterReady))
                    670:        break;
                    671:     }
                    672:   if (TraceHardReset)
                    673:     printk("BusLogic_HardReset(0x%X): Host Adapter Ready, Status 0x%02X\n",
                    674:           HostAdapter->IO_Address, StatusRegister);
                    675:   if (TimeoutCounter < 0) return false;
                    676:   /*
                    677:     If Diagnostic Failure is set or Host Adapter Ready is reset, then an
                    678:     error occurred during the Host Adapter diagnostics.  If Data In Register
                    679:     Ready is set, then there is an Error Code available.
                    680:   */
                    681:   if ((StatusRegister & BusLogic_DiagnosticFailure) ||
                    682:       !(StatusRegister & BusLogic_HostAdapterReady))
                    683:     {
                    684:       BusLogic_CommandFailureReason = NULL;
                    685:       BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
                    686:       printk("HOST ADAPTER STATUS REGISTER = %02X\n", StatusRegister);
                    687:       if (StatusRegister & BusLogic_DataInRegisterReady)
                    688:        {
                    689:          unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
                    690:          printk("HOST ADAPTER ERROR CODE = %d\n", ErrorCode);
                    691:        }
                    692:       return false;
                    693:     }
                    694:   /*
                    695:     Indicate the Host Adapter Hard Reset completed successfully.
                    696:   */
                    697:   return true;
                    698: }
                    699: 
                    700: 
                    701: /*
                    702:   BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
                    703:   Host Adapter.
                    704: */
                    705: 
                    706: static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
                    707: {
                    708:   BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
                    709:   BusLogic_RequestedReplyLength_T RequestedReplyLength;
                    710:   unsigned long ProcessorFlags;
                    711:   int Result;
                    712:   /*
                    713:     Issue the Inquire Extended Setup Information command.  Only genuine
                    714:     BusLogic Host Adapters and true clones support this command.  Adaptec 1542C
                    715:     series Host Adapters that respond to the Geometry Register I/O port will
                    716:     fail this command.  Interrupts must be disabled around the call to
                    717:     BusLogic_Command since a Command Complete interrupt could occur if the IRQ
                    718:     Channel was previously enabled for another BusLogic Host Adapter sharing
                    719:     the same IRQ Channel.
                    720:   */
                    721:   save_flags(ProcessorFlags);
                    722:   cli();
                    723:   RequestedReplyLength = sizeof(ExtendedSetupInformation);
                    724:   Result = BusLogic_Command(HostAdapter,
                    725:                            BusLogic_InquireExtendedSetupInformation,
                    726:                            &RequestedReplyLength, sizeof(RequestedReplyLength),
                    727:                            &ExtendedSetupInformation,
                    728:                            sizeof(ExtendedSetupInformation));
                    729:   restore_flags(ProcessorFlags);
                    730:   if (BusLogic_GlobalOptions & BusLogic_TraceProbe)
                    731:     printk("BusLogic_Check(0x%X): Result %d\n",
                    732:           HostAdapter->IO_Address, Result);
                    733:   return (Result == sizeof(ExtendedSetupInformation));
                    734: }
                    735: 
                    736: 
                    737: /*
                    738:   BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
                    739:   from Host Adapter.
                    740: */
                    741: 
                    742: static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T
                    743:                                                     *HostAdapter)
                    744: {
                    745:   BusLogic_BoardID_T BoardID;
                    746:   BusLogic_Configuration_T Configuration;
                    747:   BusLogic_SetupInformation_T SetupInformation;
                    748:   BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
                    749:   BusLogic_BoardModelNumber_T BoardModelNumber;
                    750:   BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
                    751:   BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
                    752:   BusLogic_RequestedReplyLength_T RequestedReplyLength;
                    753:   unsigned char GeometryRegister, *TargetPointer, Character;
                    754:   unsigned short AllTargetsMask, DisconnectPermitted;
                    755:   unsigned short TaggedQueuingPermitted, TaggedQueuingPermittedDefault;
                    756:   boolean CommonErrorRecovery;
                    757:   int TargetID, i;
                    758:   /*
                    759:     Issue the Inquire Board ID command.
                    760:   */
                    761:   if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0,
                    762:                       &BoardID, sizeof(BoardID)) != sizeof(BoardID))
                    763:     return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
                    764:   /*
                    765:     Issue the Inquire Configuration command.
                    766:   */
                    767:   if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0,
                    768:                       &Configuration, sizeof(Configuration))
                    769:       != sizeof(Configuration))
                    770:     return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
                    771:   /*
                    772:     Issue the Inquire Setup Information command.
                    773:   */
                    774:   RequestedReplyLength = sizeof(SetupInformation);
                    775:   if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
                    776:                       &RequestedReplyLength, sizeof(RequestedReplyLength),
                    777:                       &SetupInformation, sizeof(SetupInformation))
                    778:       != sizeof(SetupInformation))
                    779:     return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
                    780:   /*
                    781:     Issue the Inquire Extended Setup Information command.
                    782:   */
                    783:   RequestedReplyLength = sizeof(ExtendedSetupInformation);
                    784:   if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation,
                    785:                       &RequestedReplyLength, sizeof(RequestedReplyLength),
                    786:                       &ExtendedSetupInformation,
                    787:                       sizeof(ExtendedSetupInformation))
                    788:       != sizeof(ExtendedSetupInformation))
                    789:     return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
                    790:   /*
                    791:     Issue the Inquire Board Model Number command.
                    792:   */
                    793:   if (!(BoardID.FirmwareVersion1stDigit == '2' &&
                    794:        ExtendedSetupInformation.BusType == 'A'))
                    795:     {
                    796:       RequestedReplyLength = sizeof(BoardModelNumber);
                    797:       if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardModelNumber,
                    798:                           &RequestedReplyLength, sizeof(RequestedReplyLength),
                    799:                           &BoardModelNumber, sizeof(BoardModelNumber))
                    800:          != sizeof(BoardModelNumber))
                    801:        return BusLogic_Failure(HostAdapter, "INQUIRE BOARD MODEL NUMBER");
                    802:     }
                    803:   else strcpy(BoardModelNumber, "542B");
                    804:   /*
                    805:     Issue the Inquire Firmware Version 3rd Digit command.
                    806:   */
                    807:   if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit,
                    808:                       NULL, 0, &FirmwareVersion3rdDigit,
                    809:                       sizeof(FirmwareVersion3rdDigit))
                    810:       != sizeof(FirmwareVersion3rdDigit))
                    811:     return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
                    812:   /*
                    813:     Issue the Inquire Firmware Version Letter command.
                    814:   */
                    815:   FirmwareVersionLetter = '\0';
                    816:   if (BoardID.FirmwareVersion1stDigit > '3' ||
                    817:       (BoardID.FirmwareVersion1stDigit == '3' &&
                    818:        BoardID.FirmwareVersion2ndDigit >= '3'))
                    819:     if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter,
                    820:                         NULL, 0, &FirmwareVersionLetter,
                    821:                         sizeof(FirmwareVersionLetter))
                    822:        != sizeof(FirmwareVersionLetter))
                    823:       return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE VERSION LETTER");
                    824:   /*
                    825:     BusLogic Host Adapters can be identified by their model number and
                    826:     the major version number of their firmware as follows:
                    827: 
                    828:     4.xx       BusLogic "C" Series Host Adapters:
                    829:                  BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
                    830:     3.xx       BusLogic "S" Series Host Adapters:
                    831:                  BT-747S/747D/757S/757D/445S/545S/542D
                    832:                  BT-542B/742A (revision H)
                    833:     2.xx       BusLogic "A" Series Host Adapters:
                    834:                  BT-542B/742A (revision G and below)
                    835:     0.xx       AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
                    836:   */
                    837:   /*
                    838:     Save the Model Name and Board Name in the Host Adapter structure.
                    839:   */
                    840:   TargetPointer = HostAdapter->ModelName;
                    841:   *TargetPointer++ = 'B';
                    842:   *TargetPointer++ = 'T';
                    843:   *TargetPointer++ = '-';
                    844:   for (i = 0; i < sizeof(BoardModelNumber); i++)
                    845:     {
                    846:       Character = BoardModelNumber[i];
                    847:       if (Character == ' ' || Character == '\0') break;
                    848:       *TargetPointer++ = Character;
                    849:     }
                    850:   *TargetPointer++ = '\0';
                    851:   strcpy(HostAdapter->BoardName, "BusLogic ");
                    852:   strcat(HostAdapter->BoardName, HostAdapter->ModelName);
                    853:   strcpy(HostAdapter->InterruptLabel, HostAdapter->BoardName);
                    854:   /*
                    855:     Save the Firmware Version in the Host Adapter structure.
                    856:   */
                    857:   TargetPointer = HostAdapter->FirmwareVersion;
                    858:   *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
                    859:   *TargetPointer++ = '.';
                    860:   *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
                    861:   if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
                    862:     *TargetPointer++ = FirmwareVersion3rdDigit;
                    863:   if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
                    864:     *TargetPointer++ = FirmwareVersionLetter;
                    865:   *TargetPointer++ = '\0';
                    866:   /*
                    867:     Determine the IRQ Channel and save it in the Host Adapter structure.
                    868:   */
                    869:   if (Configuration.IRQ_Channel9)
                    870:     HostAdapter->IRQ_Channel = 9;
                    871:   else if (Configuration.IRQ_Channel10)
                    872:     HostAdapter->IRQ_Channel = 10;
                    873:   else if (Configuration.IRQ_Channel11)
                    874:     HostAdapter->IRQ_Channel = 11;
                    875:   else if (Configuration.IRQ_Channel12)
                    876:     HostAdapter->IRQ_Channel = 12;
                    877:   else if (Configuration.IRQ_Channel14)
                    878:     HostAdapter->IRQ_Channel = 14;
                    879:   else if (Configuration.IRQ_Channel15)
                    880:     HostAdapter->IRQ_Channel = 15;
                    881:   /*
                    882:     Determine the DMA Channel and save it in the Host Adapter structure.
                    883:   */
                    884:   if (Configuration.DMA_Channel5)
                    885:     HostAdapter->DMA_Channel = 5;
                    886:   else if (Configuration.DMA_Channel6)
                    887:     HostAdapter->DMA_Channel = 6;
                    888:   else if (Configuration.DMA_Channel7)
                    889:     HostAdapter->DMA_Channel = 7;
                    890:   /*
                    891:     Save the Host Adapter SCSI ID in the Host Adapter structure.
                    892:   */
                    893:   HostAdapter->SCSI_ID = Configuration.HostAdapterID;
                    894:   /*
                    895:     Save the Synchronous Initiation flag and SCSI Parity Checking flag
                    896:     in the Host Adapter structure.
                    897:   */
                    898:   HostAdapter->SynchronousInitiation =
                    899:     SetupInformation.SynchronousInitiationEnabled;
                    900:   HostAdapter->ParityChecking = SetupInformation.ParityCheckEnabled;
                    901:   /*
                    902:     Determine the Bus Type and save it in the Host Adapter structure,
                    903:     overriding the DMA Channel if it is inappropriate for the bus type.
                    904:   */
                    905:   if (ExtendedSetupInformation.BusType == 'A')
                    906:     HostAdapter->BusType = BusLogic_ISA_Bus;
                    907:   else
                    908:     switch (HostAdapter->ModelName[3])
                    909:       {
                    910:       case '4':
                    911:        HostAdapter->BusType = BusLogic_VESA_Bus;
                    912:        HostAdapter->DMA_Channel = 0;
                    913:        break;
                    914:       case '5':
                    915:        HostAdapter->BusType = BusLogic_ISA_Bus;
                    916:        break;
                    917:       case '6':
                    918:        HostAdapter->BusType = BusLogic_MCA_Bus;
                    919:        HostAdapter->DMA_Channel = 0;
                    920:        break;
                    921:       case '7':
                    922:        HostAdapter->BusType = BusLogic_EISA_Bus;
                    923:        HostAdapter->DMA_Channel = 0;
                    924:        break;
                    925:       case '9':
                    926:        HostAdapter->BusType = BusLogic_PCI_Bus;
                    927:        HostAdapter->DMA_Channel = 0;
                    928:        break;
                    929:       }
                    930:   /*
                    931:     Determine whether Extended Translation is enabled and save it in
                    932:     the Host Adapter structure.
                    933:   */
                    934:   GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
                    935:   if (GeometryRegister & BusLogic_ExtendedTranslationEnabled)
                    936:     HostAdapter->ExtendedTranslation = true;
                    937:   /*
                    938:     Save the Disconnect/Reconnect Permitted flag bits in the Host Adapter
                    939:     structure.  The Disconnect Permitted information is only valid on "C"
                    940:     Series boards, but Disconnect/Reconnect is always permitted on "S" and
                    941:     "A" Series boards.
                    942:   */
                    943:   if (HostAdapter->FirmwareVersion[0] >= '4')
                    944:     HostAdapter->DisconnectPermitted =
                    945:       (SetupInformation.DisconnectPermittedID8to15 << 8)
                    946:       | SetupInformation.DisconnectPermittedID0to7;
                    947:   else HostAdapter->DisconnectPermitted = 0xFF;
                    948:   /*
                    949:     Save the Scatter Gather Limits, Level Sensitive Interrupts flag,
                    950:     Wide SCSI flag, and Differential SCSI flag in the Host Adapter structure.
                    951:   */
                    952:   HostAdapter->HostAdapterScatterGatherLimit =
                    953:     ExtendedSetupInformation.ScatterGatherLimit;
                    954:   HostAdapter->DriverScatterGatherLimit =
                    955:     HostAdapter->HostAdapterScatterGatherLimit;
                    956:   if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
                    957:     HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
                    958:   if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupts)
                    959:     HostAdapter->LevelSensitiveInterrupts = true;
                    960:   if (ExtendedSetupInformation.HostWideSCSI)
                    961:     {
                    962:       HostAdapter->HostWideSCSI = true;
                    963:       HostAdapter->MaxTargetIDs = 16;
                    964:       HostAdapter->MaxLogicalUnits = 64;
                    965:     }
                    966:   else
                    967:     {
                    968:       HostAdapter->HostWideSCSI = false;
                    969:       HostAdapter->MaxTargetIDs = 8;
                    970:       HostAdapter->MaxLogicalUnits = 8;
                    971:     }
                    972:   HostAdapter->HostDifferentialSCSI =
                    973:     ExtendedSetupInformation.HostDifferentialSCSI;
                    974:   /*
                    975:     Determine the Host Adapter BIOS Address if the BIOS is enabled and
                    976:     save it in the Host Adapter structure.  The BIOS is disabled if the
                    977:     BIOS_Address is 0.
                    978:   */
                    979:   HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
                    980:   /*
                    981:     BusLogic BT-445S Host Adapters prior to board revision D have a hardware
                    982:     bug whereby when the BIOS is enabled, transfers to/from the same address
                    983:     range the BIOS occupies modulo 16MB are handled incorrectly.  Only properly
                    984:     functioning BT-445S boards have firmware version 3.37, so we require that
                    985:     ISA bounce buffers be used for the buggy BT-445S models as well as for all
                    986:     ISA models.
                    987:   */
                    988:   if (HostAdapter->BusType == BusLogic_ISA_Bus ||
                    989:       (HostAdapter->BIOS_Address > 0 &&
                    990:        strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
                    991:        strcmp(HostAdapter->FirmwareVersion, "3.37") < 0))
                    992:     HostAdapter->BounceBuffersRequired = true;
                    993:   /*
                    994:     Select an appropriate value for Concurrency (Commands per Logical Unit)
                    995:     either from a Command Line Entry, or based on whether this Host Adapter
                    996:     requires that ISA bounce buffers be used.
                    997:   */
                    998:   if (HostAdapter->CommandLineEntry != NULL &&
                    999:       HostAdapter->CommandLineEntry->Concurrency > 0)
                   1000:     HostAdapter->Concurrency = HostAdapter->CommandLineEntry->Concurrency;
                   1001:   else if (HostAdapter->BounceBuffersRequired)
                   1002:     HostAdapter->Concurrency = BusLogic_Concurrency_BB;
                   1003:   else HostAdapter->Concurrency = BusLogic_Concurrency;
                   1004:   /*
                   1005:     Select an appropriate value for Bus Settle Time either from a Command
                   1006:     Line Entry, or from BusLogic_DefaultBusSettleTime.
                   1007:   */
                   1008:   if (HostAdapter->CommandLineEntry != NULL &&
                   1009:       HostAdapter->CommandLineEntry->BusSettleTime > 0)
                   1010:     HostAdapter->BusSettleTime = HostAdapter->CommandLineEntry->BusSettleTime;
                   1011:   else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
                   1012:   /*
                   1013:     Select an appropriate value for Local Options from a Command Line Entry.
                   1014:   */
                   1015:   if (HostAdapter->CommandLineEntry != NULL)
                   1016:     HostAdapter->LocalOptions = HostAdapter->CommandLineEntry->LocalOptions;
                   1017:   /*
                   1018:     Select appropriate values for the Error Recovery Option array either from
                   1019:     a Command Line Entry, or using BusLogic_ErrorRecoveryDefault.
                   1020:   */
                   1021:   if (HostAdapter->CommandLineEntry != NULL)
                   1022:     memcpy(HostAdapter->ErrorRecoveryOption,
                   1023:           HostAdapter->CommandLineEntry->ErrorRecoveryOption,
                   1024:           sizeof(HostAdapter->ErrorRecoveryOption));
                   1025:   else memset(HostAdapter->ErrorRecoveryOption,
                   1026:              BusLogic_ErrorRecoveryDefault,
                   1027:              sizeof(HostAdapter->ErrorRecoveryOption));
                   1028:   /*
                   1029:     Tagged Queuing support is available and operates properly only on "C"
                   1030:     Series boards with firmware version 4.22 and above and on "S" Series
                   1031:     boards with firmware version 3.35 and above.  Tagged Queuing is disabled
                   1032:     by default when the Concurrency value is 1 since queuing multiple commands
                   1033:     is not possible.
                   1034:   */
                   1035:   TaggedQueuingPermittedDefault = 0;
                   1036:   if (HostAdapter->Concurrency > 1)
                   1037:     switch (HostAdapter->FirmwareVersion[0])
                   1038:       {
                   1039:       case '5':
                   1040:        TaggedQueuingPermittedDefault = 0xFFFF;
                   1041:        break;
                   1042:       case '4':
                   1043:        if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
                   1044:          TaggedQueuingPermittedDefault = 0xFFFF;
                   1045:        break;
                   1046:       case '3':
                   1047:        if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
                   1048:          TaggedQueuingPermittedDefault = 0xFFFF;
                   1049:        break;
                   1050:       }
                   1051:   /*
                   1052:     Tagged Queuing is only useful if Disconnect/Reconnect is permitted.
                   1053:     Therefore, mask the Tagged Queuing Permitted Default bits with the
                   1054:     Disconnect/Reconnect Permitted bits.
                   1055:   */
                   1056:   TaggedQueuingPermittedDefault &= HostAdapter->DisconnectPermitted;
                   1057:   /*
                   1058:     Combine the default Tagged Queuing Permitted Default bits with any
                   1059:     Command Line Entry Tagged Queuing specification.
                   1060:   */
                   1061:   if (HostAdapter->CommandLineEntry != NULL)
                   1062:     HostAdapter->TaggedQueuingPermitted =
                   1063:       (HostAdapter->CommandLineEntry->TaggedQueuingPermitted &
                   1064:        HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask) |
                   1065:       (TaggedQueuingPermittedDefault &
                   1066:        ~HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask);
                   1067:   else HostAdapter->TaggedQueuingPermitted = TaggedQueuingPermittedDefault;
                   1068:   /*
                   1069:     Announce the Host Adapter Configuration.
                   1070:   */
                   1071:   printk("scsi%d: Configuring BusLogic Model %s %s%s%s SCSI Host Adapter\n",
                   1072:         HostAdapter->HostNumber, HostAdapter->ModelName,
                   1073:         BusLogic_BusNames[HostAdapter->BusType],
                   1074:         (HostAdapter->HostWideSCSI ? " Wide" : ""),
                   1075:         (HostAdapter->HostDifferentialSCSI ? " Differential" : ""));
                   1076:   printk("scsi%d:   Firmware Version: %s, I/O Address: 0x%X, "
                   1077:         "IRQ Channel: %d/%s\n",
                   1078:         HostAdapter->HostNumber, HostAdapter->FirmwareVersion,
                   1079:         HostAdapter->IO_Address, HostAdapter->IRQ_Channel,
                   1080:         (HostAdapter->LevelSensitiveInterrupts ? "Level" : "Edge"));
                   1081:   printk("scsi%d:   DMA Channel: ", HostAdapter->HostNumber);
                   1082:   if (HostAdapter->DMA_Channel > 0)
                   1083:     printk("%d, ", HostAdapter->DMA_Channel);
                   1084:   else printk("None, ");
                   1085:   if (HostAdapter->BIOS_Address > 0)
                   1086:     printk("BIOS Address: 0x%lX, ", HostAdapter->BIOS_Address);
                   1087:   else printk("BIOS Address: None, ");
                   1088:   printk("Host Adapter SCSI ID: %d\n", HostAdapter->SCSI_ID);
                   1089:   printk("scsi%d:   Scatter/Gather Limit: %d segments, "
                   1090:         "Synchronous Initiation: %s\n", HostAdapter->HostNumber,
                   1091:         HostAdapter->HostAdapterScatterGatherLimit,
                   1092:         (HostAdapter->SynchronousInitiation ? "Enabled" : "Disabled"));
                   1093:   printk("scsi%d:   SCSI Parity Checking: %s, "
                   1094:         "Extended Disk Translation: %s\n", HostAdapter->HostNumber,
                   1095:         (HostAdapter->ParityChecking ? "Enabled" : "Disabled"),
                   1096:         (HostAdapter->ExtendedTranslation ? "Enabled" : "Disabled"));
                   1097:   AllTargetsMask = (1 << HostAdapter->MaxTargetIDs) - 1;
                   1098:   DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
                   1099:   printk("scsi%d:   Disconnect/Reconnect: ", HostAdapter->HostNumber);
                   1100:   if (DisconnectPermitted == 0)
                   1101:     printk("Disabled");
                   1102:   else if (DisconnectPermitted == AllTargetsMask)
                   1103:     printk("Enabled");
                   1104:   else
                   1105:     for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
                   1106:       printk("%c", (DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
                   1107:   printk(", Tagged Queuing: ");
                   1108:   TaggedQueuingPermitted =
                   1109:     HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
                   1110:   if (TaggedQueuingPermitted == 0)
                   1111:     printk("Disabled");
                   1112:   else if (TaggedQueuingPermitted == AllTargetsMask)
                   1113:     printk("Enabled");
                   1114:   else
                   1115:     for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
                   1116:       printk("%c", (TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
                   1117:   printk("\n");
                   1118:   CommonErrorRecovery = true;
                   1119:   for (TargetID = 1; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
                   1120:     if (HostAdapter->ErrorRecoveryOption[TargetID] !=
                   1121:        HostAdapter->ErrorRecoveryOption[0])
                   1122:       {
                   1123:        CommonErrorRecovery = false;
                   1124:        break;
                   1125:       }
                   1126:   printk("scsi%d:   Error Recovery: ", HostAdapter->HostNumber);
                   1127:   if (CommonErrorRecovery)
                   1128:     printk("%s", BusLogic_ErrorRecoveryOptions[
                   1129:                   HostAdapter->ErrorRecoveryOption[0]]);
                   1130:   else
                   1131:     for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
                   1132:       printk("%s", BusLogic_ErrorRecoveryOptions2[
                   1133:                     HostAdapter->ErrorRecoveryOption[TargetID]]);
                   1134:   printk(", Mailboxes: %d, Initial CCBs: %d\n",
                   1135:         BusLogic_MailboxCount, BusLogic_InitialCCBs);
                   1136:   printk("scsi%d:   Driver Scatter/Gather Limit: %d segments, "
                   1137:         "Concurrency: %d\n", HostAdapter->HostNumber,
                   1138:         HostAdapter->DriverScatterGatherLimit, HostAdapter->Concurrency);
                   1139:   /*
                   1140:     Indicate reading the Host Adapter Configuration completed successfully.
                   1141:   */
                   1142:   return true;
                   1143: }
                   1144: 
                   1145: 
                   1146: /*
                   1147:   BusLogic_AcquireResources acquires the system resources necessary to use Host
                   1148:   Adapter, and initializes the fields in the SCSI Host structure.  The base,
                   1149:   io_port, n_io_ports, irq, and dma_channel fields in the SCSI Host structure
                   1150:   are intentionally left uninitialized, as this driver handles acquisition and
                   1151:   release of these resources explicitly, as well as ensuring exclusive access
                   1152:   to the Host Adapter hardware and data structures through explicit locking.
                   1153: */
                   1154: 
                   1155: static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter,
                   1156:                                         SCSI_Host_T *Host)
                   1157: {
                   1158:   /*
                   1159:     Acquire exclusive or shared access to the IRQ Channel.  A usage count is
                   1160:     maintained so that PCI, EISA, or MCA shared Interrupts can be supported.
                   1161:   */
                   1162:   if (BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]++ == 0)
                   1163:     {
                   1164:       if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
                   1165:                      SA_INTERRUPT, HostAdapter->InterruptLabel) < 0)
                   1166:        {
                   1167:          BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]--;
                   1168:          printk("scsi%d: UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
                   1169:                 HostAdapter->HostNumber, HostAdapter->IRQ_Channel);
                   1170:          return false;
                   1171:        }
                   1172:     }
                   1173:   else
                   1174:     {
                   1175:       BusLogic_HostAdapter_T *FirstHostAdapter =
                   1176:        BusLogic_RegisteredHostAdapters;
                   1177:       while (FirstHostAdapter != NULL)
                   1178:        {
                   1179:          if (FirstHostAdapter->IRQ_Channel == HostAdapter->IRQ_Channel)
                   1180:            {
                   1181:              if (strlen(FirstHostAdapter->InterruptLabel) + 11
                   1182:                  < sizeof(FirstHostAdapter->InterruptLabel))
                   1183:                {
                   1184:                  strcat(FirstHostAdapter->InterruptLabel, " + ");
                   1185:                  strcat(FirstHostAdapter->InterruptLabel,
                   1186:                         HostAdapter->ModelName);
                   1187:                }
                   1188:              break;
                   1189:            }
                   1190:          FirstHostAdapter = FirstHostAdapter->Next;
                   1191:        }
                   1192:     }
                   1193:   HostAdapter->IRQ_ChannelAcquired = true;
                   1194:   /*
                   1195:     Acquire exclusive access to the DMA Channel.
                   1196:   */
                   1197:   if (HostAdapter->DMA_Channel > 0)
                   1198:     {
                   1199:       if (request_dma(HostAdapter->DMA_Channel, HostAdapter->BoardName) < 0)
                   1200:        {
                   1201:          printk("scsi%d: UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
                   1202:                 HostAdapter->HostNumber, HostAdapter->DMA_Channel);
                   1203:          return false;
                   1204:        }
                   1205:       set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
                   1206:       enable_dma(HostAdapter->DMA_Channel);
                   1207:       HostAdapter->DMA_ChannelAcquired = true;
                   1208:     }
                   1209:   /*
                   1210:     Initialize necessary fields in the SCSI Host structure.
                   1211:   */
                   1212:   Host->max_id = HostAdapter->MaxTargetIDs;
                   1213:   Host->max_lun = HostAdapter->MaxLogicalUnits;
                   1214:   Host->max_channel = 0;
                   1215:   Host->this_id = HostAdapter->SCSI_ID;
                   1216:   Host->can_queue = BusLogic_MailboxCount;
                   1217:   Host->cmd_per_lun = HostAdapter->Concurrency;
                   1218:   Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
                   1219:   Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
                   1220:   /*
                   1221:     Indicate the System Resource Acquisition completed successfully,
                   1222:   */
                   1223:   return true;
                   1224: }
                   1225: 
                   1226: 
                   1227: /*
                   1228:   BusLogic_ReleaseResources releases any system resources previously acquired
                   1229:   by BusLogic_AcquireResources.
                   1230: */
                   1231: 
                   1232: static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
                   1233: {
                   1234:   /*
                   1235:     Release exclusive or shared access to the IRQ Channel.
                   1236:   */
                   1237:   if (HostAdapter->IRQ_ChannelAcquired)
                   1238:     if (--BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9] == 0)
                   1239:       free_irq(HostAdapter->IRQ_Channel);
                   1240:   /*
                   1241:     Release exclusive access to the DMA Channel.
                   1242:   */
                   1243:   if (HostAdapter->DMA_ChannelAcquired)
                   1244:     free_dma(HostAdapter->DMA_Channel);
                   1245: }
                   1246: 
                   1247: 
                   1248: /*
                   1249:   BusLogic_TestInterrupts tests for proper functioning of the Host Adapter
                   1250:   Interrupt Register and that interrupts generated by the Host Adapter are
                   1251:   getting through to the Interrupt Handler.  A large proportion of initial
                   1252:   problems with installing PCI Host Adapters are due to configuration problems
                   1253:   where either the Host Adapter or Motherboard is configured incorrectly, and
                   1254:   interrupts do not get through as a result.
                   1255: */
                   1256: 
                   1257: static boolean BusLogic_TestInterrupts(BusLogic_HostAdapter_T *HostAdapter)
                   1258: {
                   1259:   unsigned int InitialInterruptCount, FinalInterruptCount;
                   1260:   int TestCount = 5, i;
                   1261:   InitialInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel];
                   1262:   /*
                   1263:     Issue the Test Command Complete Interrupt commands.
                   1264:   */
                   1265:   for (i = 0; i < TestCount; i++)
                   1266:     BusLogic_Command(HostAdapter, BusLogic_TestCommandCompleteInterrupt,
                   1267:                     NULL, 0, NULL, 0);
                   1268:   /*
                   1269:     Verify that BusLogic_InterruptHandler was called at least TestCount times.
                   1270:     Shared IRQ Channels could cause more than TestCount interrupts to occur,
                   1271:     but there should never be fewer than TestCount.
                   1272:   */
                   1273:   FinalInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel];
                   1274:   if (FinalInterruptCount < InitialInterruptCount + TestCount)
                   1275:     {
                   1276:       BusLogic_Failure(HostAdapter, "HOST ADAPTER INTERRUPT TEST");
                   1277:       printk("\n\
                   1278: Interrupts are not getting through from the Host Adapter to the BusLogic\n\
                   1279: Driver Interrupt Handler. The most likely cause is that either the Host\n\
                   1280: Adapter or Motherboard is configured incorrectly.  Please check the Host\n\
                   1281: Adapter configuration with AutoSCSI or by examining any dip switch and\n\
                   1282: jumper settings on the Host Adapter, and verify that no other device is\n\
                   1283: attempting to use the same IRQ Channel.  For PCI Host Adapters, it may also\n\
                   1284: be necessary to investigate and manually set the PCI interrupt assignments\n\
                   1285: and edge/level interrupt type selection in the BIOS Setup Program or with\n\
                   1286: Motherboard jumpers.\n\n");
                   1287:       return false;
                   1288:     }
                   1289:   /*
                   1290:     Indicate the Host Adapter Interrupt Test completed successfully.
                   1291:   */
                   1292:   return true;
                   1293: }
                   1294: 
                   1295: 
                   1296: /*
                   1297:   BusLogic_InitializeHostAdapter initializes Host Adapter.  This is the only
                   1298:   function called during SCSI Host Adapter detection which modifies the state
                   1299:   of the Host Adapter from its initial power on or hard reset state.
                   1300: */
                   1301: 
                   1302: static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T
                   1303:                                              *HostAdapter)
                   1304: {
                   1305:   BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
                   1306:   BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
                   1307:   BusLogic_WideModeCCBRequest_T WideModeCCBRequest;
                   1308:   BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
                   1309:   /*
                   1310:     Initialize the Command Successful Flag, Read/Write Operation Count,
                   1311:     and Queued Operation Count for each Target.
                   1312:   */
                   1313:   memset(HostAdapter->CommandSuccessfulFlag, false,
                   1314:         sizeof(HostAdapter->CommandSuccessfulFlag));
                   1315:   memset(HostAdapter->ReadWriteOperationCount, 0,
                   1316:         sizeof(HostAdapter->ReadWriteOperationCount));
                   1317:   memset(HostAdapter->QueuedOperationCount, 0,
                   1318:         sizeof(HostAdapter->QueuedOperationCount));
                   1319:   /*
                   1320:     Initialize the Outgoing and Incoming Mailbox structures.
                   1321:   */
                   1322:   memset(HostAdapter->OutgoingMailboxes, 0,
                   1323:         sizeof(HostAdapter->OutgoingMailboxes));
                   1324:   memset(HostAdapter->IncomingMailboxes, 0,
                   1325:         sizeof(HostAdapter->IncomingMailboxes));
                   1326:   /*
                   1327:     Initialize the pointers to the First, Last, and Next Mailboxes.
                   1328:   */
                   1329:   HostAdapter->FirstOutgoingMailbox = &HostAdapter->OutgoingMailboxes[0];
                   1330:   HostAdapter->LastOutgoingMailbox =
                   1331:     &HostAdapter->OutgoingMailboxes[BusLogic_MailboxCount-1];
                   1332:   HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
                   1333:   HostAdapter->FirstIncomingMailbox = &HostAdapter->IncomingMailboxes[0];
                   1334:   HostAdapter->LastIncomingMailbox =
                   1335:     &HostAdapter->IncomingMailboxes[BusLogic_MailboxCount-1];
                   1336:   HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
                   1337:   /*
                   1338:     Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
                   1339:   */
                   1340:   ExtendedMailboxRequest.MailboxCount = BusLogic_MailboxCount;
                   1341:   ExtendedMailboxRequest.BaseMailboxAddress = HostAdapter->OutgoingMailboxes;
                   1342:   if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox,
                   1343:                       &ExtendedMailboxRequest,
                   1344:                       sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
                   1345:     return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
                   1346:   /*
                   1347:     Enable Strict Round Robin Mode if supported by the Host Adapter.  In Strict
                   1348:     Round Robin Mode, the Host Adapter only looks at the next Outgoing Mailbox
                   1349:     for each new command, rather than scanning through all the Outgoing
                   1350:     Mailboxes to find any that have new commands in them.  BusLogic indicates
                   1351:     that Strict Round Robin Mode is significantly more efficient.
                   1352:   */
                   1353:   if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
                   1354:     {
                   1355:       RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
                   1356:       if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
                   1357:                           &RoundRobinModeRequest,
                   1358:                           sizeof(RoundRobinModeRequest), NULL, 0) < 0)
                   1359:        return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
                   1360:     }
                   1361:   /*
                   1362:     For Wide SCSI Host Adapters, issue the Enable Wide Mode CCB command to
                   1363:     allow more than 8 Logical Units per Target to be supported.
                   1364:   */
                   1365:   if (HostAdapter->HostWideSCSI)
                   1366:     {
                   1367:       WideModeCCBRequest = BusLogic_WideModeCCB;
                   1368:       if (BusLogic_Command(HostAdapter, BusLogic_EnableWideModeCCB,
                   1369:                           &WideModeCCBRequest,
                   1370:                           sizeof(WideModeCCBRequest), NULL, 0) < 0)
                   1371:        return BusLogic_Failure(HostAdapter, "ENABLE WIDE MODE CCB");
                   1372:     }
                   1373:   /*
                   1374:     For PCI Host Adapters being accessed through the PCI compliant I/O
                   1375:     Address, disable the ISA compatible I/O Address to avoid detecting the
                   1376:     same Host Adapter at both I/O Addresses.
                   1377:   */
                   1378:   if (HostAdapter->BusType == BusLogic_PCI_Bus)
                   1379:     {
                   1380:       int Index;
                   1381:       for (Index = 0; BusLogic_IO_StandardAddresses[Index] > 0; Index++)
                   1382:        if (HostAdapter->IO_Address == BusLogic_IO_StandardAddresses[Index])
                   1383:          break;
                   1384:       if (BusLogic_IO_StandardAddresses[Index] == 0)
                   1385:        {
                   1386:          ModifyIOAddressRequest = BusLogic_ModifyIO_Disable;
                   1387:          if (BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress,
                   1388:                               &ModifyIOAddressRequest,
                   1389:                               sizeof(ModifyIOAddressRequest), NULL, 0) < 0)
                   1390:            return BusLogic_Failure(HostAdapter, "MODIFY I/O ADDRESS");
                   1391:        }
                   1392:     }
                   1393:   /*
                   1394:     Announce Successful Initialization.
                   1395:   */
                   1396:   printk("scsi%d: *** %s Initialized Successfully ***\n",
                   1397:         HostAdapter->HostNumber, HostAdapter->BoardName);
                   1398:   /*
                   1399:     Indicate the Host Adapter Initialization completed successfully.
                   1400:   */
                   1401:   return true;
                   1402: }
                   1403: 
                   1404: 
                   1405: /*
                   1406:   BusLogic_InquireTargetDevices inquires about the Target Devices accessible
                   1407:   through Host Adapter and reports on the results.
                   1408: */
                   1409: 
                   1410: static boolean BusLogic_InquireTargetDevices(BusLogic_HostAdapter_T
                   1411:                                             *HostAdapter)
                   1412: {
                   1413:   BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
                   1414:   BusLogic_InstalledDevices8_T InstalledDevicesID8to15;
                   1415:   BusLogic_SetupInformation_T SetupInformation;
                   1416:   BusLogic_SynchronousPeriod_T SynchronousPeriod;
                   1417:   BusLogic_RequestedReplyLength_T RequestedReplyLength;
                   1418:   int TargetDevicesFound = 0, TargetID;
                   1419:   /*
                   1420:     Wait a few seconds between the Host Adapter Hard Reset which initiates
                   1421:     a SCSI Bus Reset and issuing any SCSI commands.  Some SCSI devices get
                   1422:     confused if they receive SCSI commands too soon after a SCSI Bus Reset.
                   1423:   */
                   1424:   BusLogic_Delay(HostAdapter->BusSettleTime);
                   1425:   /*
                   1426:     Inhibit the Target Devices Inquiry if requested.
                   1427:   */
                   1428:   if (HostAdapter->LocalOptions & BusLogic_InhibitTargetInquiry)
                   1429:     {
                   1430:       printk("scsi%d:   Target Device Inquiry Inhibited\n",
                   1431:             HostAdapter->HostNumber);
                   1432:       return true;
                   1433:     }
                   1434:   /*
                   1435:     Issue the Inquire Installed Devices ID 0 to 7 command, and for Wide SCSI
                   1436:     Host Adapters the Inquire Installed Devices ID 8 to 15 command.  This is
                   1437:     necessary to force Synchronous Transfer Negotiation so that the Inquire
                   1438:     Setup Information and Inquire Synchronous Period commands will return
                   1439:     valid data.
                   1440:   */
                   1441:   if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7,
                   1442:                       NULL, 0, &InstalledDevicesID0to7,
                   1443:                       sizeof(InstalledDevicesID0to7))
                   1444:       != sizeof(InstalledDevicesID0to7))
                   1445:     return BusLogic_Failure(HostAdapter, "INQUIRE INSTALLED DEVICES ID 0 TO 7");
                   1446:   if (HostAdapter->HostWideSCSI)
                   1447:     if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID8to15,
                   1448:                         NULL, 0, &InstalledDevicesID8to15,
                   1449:                         sizeof(InstalledDevicesID8to15))
                   1450:        != sizeof(InstalledDevicesID8to15))
                   1451:       return BusLogic_Failure(HostAdapter,
                   1452:                              "INQUIRE INSTALLED DEVICES ID 8 TO 15");
                   1453:   /*
                   1454:     Issue the Inquire Setup Information command.
                   1455:   */
                   1456:   RequestedReplyLength = sizeof(SetupInformation);
                   1457:   if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
                   1458:                       &RequestedReplyLength, sizeof(RequestedReplyLength),
                   1459:                       &SetupInformation, sizeof(SetupInformation))
                   1460:       != sizeof(SetupInformation))
                   1461:     return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
                   1462:   /*
                   1463:     Issue the Inquire Synchronous Period command.
                   1464:   */
                   1465:   if (HostAdapter->FirmwareVersion[0] >= '3')
                   1466:     {
                   1467:       RequestedReplyLength = sizeof(SynchronousPeriod);
                   1468:       if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod,
                   1469:                           &RequestedReplyLength, sizeof(RequestedReplyLength),
                   1470:                           &SynchronousPeriod, sizeof(SynchronousPeriod))
                   1471:          != sizeof(SynchronousPeriod))
                   1472:        return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
                   1473:     }
                   1474:   else
                   1475:     for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
                   1476:       if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
                   1477:        SynchronousPeriod[TargetID] =
                   1478:          20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
                   1479:                                   .TransferPeriod;
                   1480:       else SynchronousPeriod[TargetID] = 0;
                   1481:   /*
                   1482:     Save the Installed Devices, Synchronous Values, and Synchronous Period
                   1483:     information in the Host Adapter structure.
                   1484:   */
                   1485:   memcpy(HostAdapter->InstalledDevices, InstalledDevicesID0to7,
                   1486:         sizeof(BusLogic_InstalledDevices8_T));
                   1487:   memcpy(HostAdapter->SynchronousValues,
                   1488:         SetupInformation.SynchronousValuesID0to7,
                   1489:         sizeof(BusLogic_SynchronousValues8_T));
                   1490:   if (HostAdapter->HostWideSCSI)
                   1491:     {
                   1492:       memcpy(&HostAdapter->InstalledDevices[8], InstalledDevicesID8to15,
                   1493:             sizeof(BusLogic_InstalledDevices8_T));
                   1494:       memcpy(&HostAdapter->SynchronousValues[8],
                   1495:             SetupInformation.SynchronousValuesID8to15,
                   1496:             sizeof(BusLogic_SynchronousValues8_T));
                   1497:     }
                   1498:   memcpy(HostAdapter->SynchronousPeriod, SynchronousPeriod,
                   1499:         sizeof(BusLogic_SynchronousPeriod_T));
                   1500:   for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
                   1501:     if (HostAdapter->InstalledDevices[TargetID] != 0)
                   1502:       {
                   1503:        int SynchronousPeriod = HostAdapter->SynchronousPeriod[TargetID];
                   1504:        if (SynchronousPeriod > 10)
                   1505:          {
                   1506:            int SynchronousTransferRate = 100000000 / SynchronousPeriod;
                   1507:            int RoundedSynchronousTransferRate =
                   1508:              (SynchronousTransferRate + 5000) / 10000;
                   1509:            printk("scsi%d:   Target %d: Synchronous at "
                   1510:                   "%d.%02d mega-transfers/second, offset %d\n",
                   1511:                   HostAdapter->HostNumber, TargetID,
                   1512:                   RoundedSynchronousTransferRate / 100,
                   1513:                   RoundedSynchronousTransferRate % 100,
                   1514:                   HostAdapter->SynchronousValues[TargetID].Offset);
                   1515:          }
                   1516:        else if (SynchronousPeriod > 0)
                   1517:          {
                   1518:            int SynchronousTransferRate = 100000000 / SynchronousPeriod;
                   1519:            int RoundedSynchronousTransferRate =
                   1520:              (SynchronousTransferRate + 50000) / 100000;
                   1521:            printk("scsi%d:   Target %d: Synchronous at "
                   1522:                   "%d.%01d mega-transfers/second, offset %d\n",
                   1523:                   HostAdapter->HostNumber, TargetID,
                   1524:                   RoundedSynchronousTransferRate / 10,
                   1525:                   RoundedSynchronousTransferRate % 10,
                   1526:                   HostAdapter->SynchronousValues[TargetID].Offset);
                   1527:          }
                   1528:        else printk("scsi%d:   Target %d: Asynchronous\n",
                   1529:                    HostAdapter->HostNumber, TargetID);
                   1530:        TargetDevicesFound++;
                   1531:       }
                   1532:   if (TargetDevicesFound == 0)
                   1533:     printk("scsi%d:   No Target Devices Found\n", HostAdapter->HostNumber);
                   1534:   /*
                   1535:     Indicate the Target Device Inquiry completed successfully.
                   1536:   */
                   1537:   return true;
                   1538: }
                   1539: 
                   1540: 
                   1541: /*
                   1542:   BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
                   1543:   I/O Addresses where they may be located, initializing, registering, and
                   1544:   reporting the configuration of each BusLogic Host Adapter it finds.  It
                   1545:   returns the number of BusLogic Host Adapters successfully initialized and
                   1546:   registered.
                   1547: */
                   1548: 
                   1549: int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)
                   1550: {
                   1551:   int BusLogicHostAdapterCount = 0, CommandLineEntryIndex = 0;
                   1552:   int AddressProbeIndex = 0;
                   1553:   BusLogic_InitializeAddressProbeList();
                   1554:   while (BusLogic_IO_AddressProbeList[AddressProbeIndex] > 0)
                   1555:     {
                   1556:       BusLogic_HostAdapter_T HostAdapterPrototype;
                   1557:       BusLogic_HostAdapter_T *HostAdapter = &HostAdapterPrototype;
                   1558:       SCSI_Host_T *Host;
                   1559:       memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
                   1560:       HostAdapter->IO_Address =
                   1561:        BusLogic_IO_AddressProbeList[AddressProbeIndex++];
                   1562:       /*
                   1563:        Initialize the Command Line Entry field if an explicit I/O Address
                   1564:        was specified.
                   1565:       */
                   1566:       if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
                   1567:          BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address ==
                   1568:          HostAdapter->IO_Address)
                   1569:        HostAdapter->CommandLineEntry =
                   1570:          &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
                   1571:       /*
                   1572:        Check whether the I/O Address range is already in use.
                   1573:       */
                   1574:       if (check_region(HostAdapter->IO_Address, BusLogic_IO_PortCount) < 0)
                   1575:        continue;
                   1576:       /*
                   1577:        Probe the Host Adapter.  If unsuccessful, abort further initialization.
                   1578:       */
                   1579:       if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
                   1580:       /*
                   1581:        Hard Reset the Host Adapter.  If unsuccessful, abort further
                   1582:        initialization.
                   1583:       */
                   1584:       if (!BusLogic_HardResetHostAdapter(HostAdapter)) continue;
                   1585:       /*
                   1586:        Check the Host Adapter.  If unsuccessful, abort further initialization.
                   1587:       */
                   1588:       if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
                   1589:       /*
                   1590:        Initialize the Command Line Entry field if an explicit I/O Address
                   1591:        was not specified.
                   1592:       */
                   1593:       if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
                   1594:          BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address == 0)
                   1595:        HostAdapter->CommandLineEntry =
                   1596:          &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
                   1597:       /*
                   1598:        Announce the Driver Version and Date, Author's Name, Copyright Notice,
                   1599:        and Contact Address.
                   1600:       */
                   1601:       BusLogic_AnnounceDriver();
                   1602:       /*
                   1603:        Register usage of the I/O Address range.  From this point onward, any
                   1604:        failure will be assumed to be due to a problem with the Host Adapter,
                   1605:        rather than due to having mistakenly identified this port as belonging
                   1606:        to a BusLogic Host Adapter.  The I/O Address range will not be
                   1607:        released, thereby preventing it from being incorrectly identified as
                   1608:        any other type of Host Adapter.
                   1609:       */
                   1610:       request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
                   1611:                     "BusLogic");
                   1612:       /*
                   1613:        Register the SCSI Host structure.
                   1614:       */
                   1615:       HostTemplate->proc_dir = &BusLogic_ProcDirectoryEntry;
                   1616:       Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T));
                   1617:       HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata;
                   1618:       memcpy(HostAdapter, &HostAdapterPrototype,
                   1619:             sizeof(BusLogic_HostAdapter_T));
                   1620:       HostAdapter->SCSI_Host = Host;
                   1621:       HostAdapter->HostNumber = Host->host_no;
                   1622:       /*
                   1623:        Add Host Adapter to the end of the list of registered BusLogic
                   1624:        Host Adapters.  In order for Command Complete Interrupts to be
                   1625:        properly dismissed by BusLogic_InterruptHandler, the Host Adapter
                   1626:        must be registered.  This must be done before the IRQ Channel is
                   1627:        acquired, and in a shared IRQ Channel environment, must be done
                   1628:        before any Command Complete Interrupts occur, since the IRQ Channel
                   1629:        may have already been acquired by a previous BusLogic Host Adapter.
                   1630:       */
                   1631:       BusLogic_RegisterHostAdapter(HostAdapter);
                   1632:       /*
                   1633:        Read the Host Adapter Configuration, Acquire the System Resources
                   1634:        necessary to use Host Adapter and initialize the fields in the SCSI
                   1635:        Host structure, then Test Interrupts, Create the CCBs, Initialize
                   1636:        the Host Adapter, and finally Inquire about the Target Devices.
                   1637:       */
                   1638:       if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
                   1639:          BusLogic_AcquireResources(HostAdapter, Host) &&
                   1640:          BusLogic_TestInterrupts(HostAdapter) &&
                   1641:          BusLogic_CreateCCBs(HostAdapter) &&
                   1642:          BusLogic_InitializeHostAdapter(HostAdapter) &&
                   1643:          BusLogic_InquireTargetDevices(HostAdapter))
                   1644:        {
                   1645:          /*
                   1646:            Initialization has been completed successfully.  Release and
                   1647:            re-register usage of the I/O Address range so that the Model
                   1648:            Name of the Host Adapter will appear.
                   1649:          */
                   1650:          release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
                   1651:          request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
                   1652:                         HostAdapter->BoardName);
                   1653:          BusLogicHostAdapterCount++;
                   1654:        }
                   1655:       else
                   1656:        {
                   1657:          /*
                   1658:            An error occurred during Host Adapter Configuration Querying,
                   1659:            Resource Acquisition, Interrupt Testing, CCB Creation, Host
                   1660:            Adapter Initialization, or Target Device Inquiry, so remove
                   1661:            Host Adapter from the list of registered BusLogic Host Adapters,
                   1662:            destroy the CCBs, Release the System Resources, and Unregister
                   1663:            the SCSI Host.
                   1664:          */
                   1665:          BusLogic_DestroyCCBs(HostAdapter);
                   1666:          BusLogic_ReleaseResources(HostAdapter);
                   1667:          BusLogic_UnregisterHostAdapter(HostAdapter);
                   1668:          scsi_unregister(Host);
                   1669:        }
                   1670:     }
                   1671:   return BusLogicHostAdapterCount;
                   1672: }
                   1673: 
                   1674: 
                   1675: /*
                   1676:   BusLogic_ReleaseHostAdapter releases all resources previously acquired to
                   1677:   support a specific Host Adapter, including the I/O Address range, and
                   1678:   unregisters the BusLogic Host Adapter.
                   1679: */
                   1680: 
                   1681: int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host)
                   1682: {
                   1683:   BusLogic_HostAdapter_T *HostAdapter =
                   1684:     (BusLogic_HostAdapter_T *) Host->hostdata;
                   1685:   /*
                   1686:     Destroy the CCBs and release any system resources acquired to use
                   1687:     Host Adapter.
                   1688:   */
                   1689:   BusLogic_DestroyCCBs(HostAdapter);
                   1690:   BusLogic_ReleaseResources(HostAdapter);
                   1691:   /*
                   1692:     Release usage of the I/O Address range.
                   1693:   */
                   1694:   release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
                   1695:   /*
                   1696:     Remove Host Adapter from the list of registered BusLogic Host Adapters.
                   1697:   */
                   1698:   BusLogic_UnregisterHostAdapter(HostAdapter);
                   1699:   return 0;
                   1700: }
                   1701: 
                   1702: 
                   1703: /*
                   1704:   BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
                   1705:   the Host Adapter Status and Target Device Status.
                   1706: */
                   1707: 
                   1708: static int BusLogic_ComputeResultCode(BusLogic_HostAdapterStatus_T
                   1709:                                        HostAdapterStatus,
                   1710:                                      BusLogic_TargetDeviceStatus_T
                   1711:                                        TargetDeviceStatus)
                   1712: {
                   1713:   int HostStatus;
                   1714:   switch (HostAdapterStatus)
                   1715:     {
                   1716:     case BusLogic_CommandCompletedNormally:
                   1717:     case BusLogic_LinkedCommandCompleted:
                   1718:     case BusLogic_LinkedCommandCompletedWithFlag:
                   1719:       HostStatus = DID_OK;
                   1720:       break;
                   1721:     case BusLogic_SCSISelectionTimeout:
                   1722:       HostStatus = DID_TIME_OUT;
                   1723:       break;
                   1724:     case BusLogic_InvalidOutgoingMailboxActionCode:
                   1725:     case BusLogic_InvalidCommandOperationCode:
                   1726:     case BusLogic_InvalidCommandParameter:
                   1727:       printk("BusLogic: BusLogic Driver Protocol Error 0x%02X\n",
                   1728:             HostAdapterStatus);
                   1729:     case BusLogic_DataOverUnderRun:
                   1730:     case BusLogic_UnexpectedBusFree:
                   1731:     case BusLogic_LinkedCCBhasInvalidLUN:
                   1732:     case BusLogic_AutoRequestSenseFailed:
                   1733:     case BusLogic_TaggedQueuingMessageRejected:
                   1734:     case BusLogic_UnsupportedMessageReceived:
                   1735:     case BusLogic_HostAdapterHardwareFailed:
                   1736:     case BusLogic_TargetDeviceReconnectedImproperly:
                   1737:     case BusLogic_AbortQueueGenerated:
                   1738:     case BusLogic_HostAdapterSoftwareError:
                   1739:     case BusLogic_HostAdapterHardwareTimeoutError:
                   1740:     case BusLogic_SCSIParityErrorDetected:
                   1741:       HostStatus = DID_ERROR;
                   1742:       break;
                   1743:     case BusLogic_InvalidBusPhaseRequested:
                   1744:     case BusLogic_TargetFailedResponseToATN:
                   1745:     case BusLogic_HostAdapterAssertedRST:
                   1746:     case BusLogic_OtherDeviceAssertedRST:
                   1747:     case BusLogic_HostAdapterAssertedBusDeviceReset:
                   1748:       HostStatus = DID_RESET;
                   1749:       break;
                   1750:     default:
                   1751:       printk("BusLogic: unknown Host Adapter Status 0x%02X\n",
                   1752:             HostAdapterStatus);
                   1753:       HostStatus = DID_ERROR;
                   1754:       break;
                   1755:     }
                   1756:   return (HostStatus << 16) | TargetDeviceStatus;
                   1757: }
                   1758: 
                   1759: 
                   1760: /*
                   1761:   BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
                   1762:   Adapters.  To simplify handling shared IRQ Channels, all installed BusLogic
                   1763:   Host Adapters are scanned whenever any one of them signals a hardware
                   1764:   interrupt.
                   1765: */
                   1766: 
                   1767: static void BusLogic_InterruptHandler(int IRQ_Channel,
                   1768:                                      Registers_T *InterruptRegisters)
                   1769: {
                   1770:   BusLogic_CCB_T *FirstCompletedCCB = NULL, *LastCompletedCCB = NULL;
                   1771:   BusLogic_HostAdapter_T *HostAdapter;
                   1772:   int HostAdapterResetPendingCount = 0;
                   1773:   /*
                   1774:     Iterate over the installed BusLogic Host Adapters accepting any Incoming
                   1775:     Mailbox entries and saving the completed CCBs for processing.  This
                   1776:     interrupt handler is installed with SA_INTERRUPT, so interrupts are
                   1777:     disabled when the interrupt handler is entered.
                   1778:   */
                   1779:   for (HostAdapter = BusLogic_RegisteredHostAdapters;
                   1780:        HostAdapter != NULL;
                   1781:        HostAdapter = HostAdapter->Next)
                   1782:     {
                   1783:       unsigned char InterruptRegister;
                   1784:       /*
                   1785:        Acquire exclusive access to Host Adapter.
                   1786:       */
                   1787:       BusLogic_LockHostAdapterID(HostAdapter);
                   1788:       /*
                   1789:        Read the Host Adapter Interrupt Register.
                   1790:       */
                   1791:       InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
                   1792:       if (InterruptRegister & BusLogic_InterruptValid)
                   1793:        {
                   1794:          /*
                   1795:            Acknowledge the interrupt and reset the Host Adapter
                   1796:            Interrupt Register.
                   1797:          */
                   1798:          BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
                   1799:          /*
                   1800:            Process valid SCSI Reset State and Incoming Mailbox Loaded
                   1801:            interrupts.  Command Complete interrupts are noted, and
                   1802:            Outgoing Mailbox Available interrupts are ignored, as they
                   1803:            are never enabled.
                   1804:          */
                   1805:          if (InterruptRegister & BusLogic_SCSIResetState)
                   1806:            {
                   1807:              HostAdapter->HostAdapterResetPending = true;
                   1808:              HostAdapterResetPendingCount++;
                   1809:            }
                   1810:          else if (InterruptRegister & BusLogic_IncomingMailboxLoaded)
                   1811:            {
                   1812:              /*
                   1813:                Scan through the Incoming Mailboxes in Strict Round Robin
                   1814:                fashion, saving any completed CCBs for further processing.
                   1815:                It is essential that for each CCB and SCSI Command issued,
                   1816:                command completion processing is performed exactly once.
                   1817:                Therefore, only Incoming Mailboxes with completion code
                   1818:                Command Completed Without Error, Command Completed With
                   1819:                Error, or Command Aborted At Host Request are saved for
                   1820:                completion processing.  When an Incoming Mailbox has a
                   1821:                completion code of Aborted Command Not Found, the CCB had
                   1822:                already completed or been aborted before the current Abort
                   1823:                request was processed, and so completion processing has
                   1824:                already occurred and no further action should be taken.
                   1825:              */
                   1826:              BusLogic_IncomingMailbox_T *NextIncomingMailbox =
                   1827:                HostAdapter->NextIncomingMailbox;
                   1828:              BusLogic_CompletionCode_T MailboxCompletionCode;
                   1829:              while ((MailboxCompletionCode =
                   1830:                      NextIncomingMailbox->CompletionCode) !=
                   1831:                     BusLogic_IncomingMailboxFree)
                   1832:                {
                   1833:                  BusLogic_CCB_T *CCB = NextIncomingMailbox->CCB;
                   1834:                  if (MailboxCompletionCode != BusLogic_AbortedCommandNotFound)
                   1835:                    if (CCB->Status == BusLogic_CCB_Active)
                   1836:                      {
                   1837:                        /*
                   1838:                          Mark this CCB as completed and add it to the end
                   1839:                          of the list of completed CCBs.
                   1840:                        */
                   1841:                        CCB->Status = BusLogic_CCB_Completed;
                   1842:                        CCB->MailboxCompletionCode = MailboxCompletionCode;
                   1843:                        CCB->Next = NULL;
                   1844:                        if (FirstCompletedCCB == NULL)
                   1845:                          {
                   1846:                            FirstCompletedCCB = CCB;
                   1847:                            LastCompletedCCB = CCB;
                   1848:                          }
                   1849:                        else
                   1850:                          {
                   1851:                            LastCompletedCCB->Next = CCB;
                   1852:                            LastCompletedCCB = CCB;
                   1853:                          }
                   1854:                        HostAdapter->QueuedOperationCount[CCB->TargetID]--;
                   1855:                      }
                   1856:                    else
                   1857:                      {
                   1858:                        /*
                   1859:                          If a CCB ever appears in an Incoming Mailbox and
                   1860:                          is not marked as status Active, then there is
                   1861:                          most likely a bug in the Host Adapter firmware.
                   1862:                        */
                   1863:                        printk("scsi%d: Illegal CCB #%d status %d in "
                   1864:                               "Incoming Mailbox\n", HostAdapter->HostNumber,
                   1865:                               CCB->SerialNumber, CCB->Status);
                   1866:                      }
                   1867:                  else printk("scsi%d: Aborted CCB #%d to Target %d "
                   1868:                              "Not Found\n", HostAdapter->HostNumber,
                   1869:                              CCB->SerialNumber, CCB->TargetID);
                   1870:                  NextIncomingMailbox->CompletionCode =
                   1871:                    BusLogic_IncomingMailboxFree;
                   1872:                  if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
                   1873:                    NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
                   1874:                }
                   1875:              HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
                   1876:            }
                   1877:          else if (InterruptRegister & BusLogic_CommandComplete)
                   1878:            HostAdapter->HostAdapterCommandCompleted = true;
                   1879:        }
                   1880:       /*
                   1881:        Release exclusive access to Host Adapter.
                   1882:       */
                   1883:       BusLogic_UnlockHostAdapterID(HostAdapter);
                   1884:     }
                   1885:   /*
                   1886:     Enable interrupts while the completed CCBs are processed.
                   1887:   */
                   1888:   sti();
                   1889:   /*
                   1890:     Iterate over the Host Adapters performing any pending Host Adapter Resets.
                   1891:   */
                   1892:   if (HostAdapterResetPendingCount > 0)
                   1893:     for (HostAdapter = BusLogic_RegisteredHostAdapters;
                   1894:         HostAdapter != NULL;
                   1895:         HostAdapter = HostAdapter->Next)
                   1896:       if (HostAdapter->HostAdapterResetPending)
                   1897:        {
                   1898:          BusLogic_ResetHostAdapter(HostAdapter, NULL);
                   1899:          HostAdapter->HostAdapterResetPending = false;
                   1900:          scsi_mark_host_bus_reset(HostAdapter->SCSI_Host);
                   1901:        }
                   1902:   /*
                   1903:     Iterate over the completed CCBs setting the SCSI Command Result Codes,
                   1904:     deallocating the CCBs, and calling the Completion Routines.
                   1905:   */
                   1906:   while (FirstCompletedCCB != NULL)
                   1907:     {
                   1908:       BusLogic_CCB_T *CCB = FirstCompletedCCB;
                   1909:       SCSI_Command_T *Command = CCB->Command;
                   1910:       FirstCompletedCCB = FirstCompletedCCB->Next;
                   1911:       HostAdapter = CCB->HostAdapter;
                   1912:       /*
                   1913:        Bus Device Reset CCBs have the Command field non-NULL only when a Bus
                   1914:        Device Reset was requested for a command that was not currently active
                   1915:        in the Host Adapter, and hence would not have its Completion Routine
                   1916:        called otherwise.
                   1917:       */
                   1918:       if (CCB->Opcode == BusLogic_SCSIBusDeviceReset)
                   1919:        {
                   1920:          printk("scsi%d: Bus Device Reset CCB #%d to Target %d Completed\n",
                   1921:                 HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
                   1922:          if (Command != NULL) Command->result = DID_RESET << 16;
                   1923:        }
                   1924:       else
                   1925:        /*
                   1926:          Translate the Mailbox Completion Code, Host Adapter Status, and
                   1927:          Target Device Status into a SCSI Subsystem Result Code.
                   1928:        */
                   1929:        switch (CCB->MailboxCompletionCode)
                   1930:          {
                   1931:          case BusLogic_IncomingMailboxFree:
                   1932:          case BusLogic_AbortedCommandNotFound:
                   1933:            printk("scsi%d: CCB #%d to Target %d Impossible State\n",
                   1934:                   HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
                   1935:            break;
                   1936:          case BusLogic_CommandCompletedWithoutError:
                   1937:            HostAdapter->CommandSuccessfulFlag[CCB->TargetID] = true;
                   1938:            Command->result = DID_OK << 16;
                   1939:            break;
                   1940:          case BusLogic_CommandAbortedAtHostRequest:
                   1941:            printk("scsi%d: CCB #%d to Target %d Aborted\n",
                   1942:                   HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
                   1943:            Command->result = DID_ABORT << 16;
                   1944:            break;
                   1945:          case BusLogic_CommandCompletedWithError:
                   1946:            Command->result =
                   1947:              BusLogic_ComputeResultCode(CCB->HostAdapterStatus,
                   1948:                                         CCB->TargetDeviceStatus);
                   1949:            if (BusLogic_GlobalOptions & BusLogic_TraceErrors)
                   1950:              if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
                   1951:                {
                   1952:                  int i;
                   1953:                  printk("scsi%d: CCB #%d Target %d: Result %X "
                   1954:                         "Host Adapter Status %02X Target Status %02X\n",
                   1955:                         HostAdapter->HostNumber, CCB->SerialNumber,
                   1956:                         CCB->TargetID, Command->result,
                   1957:                         CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
                   1958:                  printk("scsi%d: CDB   ", HostAdapter->HostNumber);
                   1959:                  for (i = 0; i < CCB->CDB_Length; i++)
                   1960:                    printk(" %02X", CCB->CDB[i]);
                   1961:                  printk("\n");
                   1962:                  printk("scsi%d: Sense ", HostAdapter->HostNumber);
                   1963:                  for (i = 0; i < CCB->SenseDataLength; i++)
                   1964:                    printk(" %02X", (*CCB->SenseDataPointer)[i]);
                   1965:                  printk("\n");
                   1966:                }
                   1967:            break;
                   1968:          }
                   1969:       /*
                   1970:        Place CCB back on the Host Adapter's free list.
                   1971:       */
                   1972:       BusLogic_DeallocateCCB(CCB);
                   1973:       /*
                   1974:        Call the SCSI Command Completion Routine if appropriate.
                   1975:       */
                   1976:       if (Command != NULL) Command->scsi_done(Command);
                   1977:     }
                   1978: }
                   1979: 
                   1980: 
                   1981: /*
                   1982:   BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
                   1983:   Mailbox for execution by Host Adapter.
                   1984: */
                   1985: 
                   1986: static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T
                   1987:                                               *HostAdapter,
                   1988:                                             BusLogic_ActionCode_T ActionCode,
                   1989:                                             BusLogic_CCB_T *CCB)
                   1990: {
                   1991:   BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
                   1992:   boolean Result = false;
                   1993:   BusLogic_LockHostAdapter(HostAdapter);
                   1994:   NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
                   1995:   if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
                   1996:     {
                   1997:       CCB->Status = BusLogic_CCB_Active;
                   1998:       /*
                   1999:        The CCB field must be written before the Action Code field since
                   2000:        the Host Adapter is operating asynchronously and the locking code
                   2001:        does not protect against simultaneous access by the Host Adapter.
                   2002:       */
                   2003:       NextOutgoingMailbox->CCB = CCB;
                   2004:       NextOutgoingMailbox->ActionCode = ActionCode;
                   2005:       BusLogic_StartMailboxScan(HostAdapter);
                   2006:       if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
                   2007:        NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
                   2008:       HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
                   2009:       if (ActionCode == BusLogic_MailboxStartCommand)
                   2010:        HostAdapter->QueuedOperationCount[CCB->TargetID]++;
                   2011:       Result = true;
                   2012:     }
                   2013:   BusLogic_UnlockHostAdapter(HostAdapter);
                   2014:   return Result;
                   2015: }
                   2016: 
                   2017: 
                   2018: /*
                   2019:   BusLogic_QueueCommand creates a CCB for Command and places it into an
                   2020:   Outgoing Mailbox for execution by the associated Host Adapter.
                   2021: */
                   2022: 
                   2023: int BusLogic_QueueCommand(SCSI_Command_T *Command,
                   2024:                          void (*CompletionRoutine)(SCSI_Command_T *))
                   2025: {
                   2026:   BusLogic_HostAdapter_T *HostAdapter =
                   2027:     (BusLogic_HostAdapter_T *) Command->host->hostdata;
                   2028:   unsigned char *CDB = Command->cmnd;
                   2029:   unsigned char CDB_Length = Command->cmd_len;
                   2030:   unsigned char TargetID = Command->target;
                   2031:   unsigned char LogicalUnit = Command->lun;
                   2032:   void *BufferPointer = Command->request_buffer;
                   2033:   int BufferLength = Command->request_bufflen;
                   2034:   int SegmentCount = Command->use_sg;
                   2035:   BusLogic_CCB_T *CCB;
                   2036:   long EnableTQ;
                   2037:   /*
                   2038:     SCSI REQUEST_SENSE commands will be executed automatically by the Host
                   2039:     Adapter for any errors, so they should not be executed explicitly unless
                   2040:     the Sense Data is zero indicating that no error occurred.
                   2041:   */
                   2042:   if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
                   2043:     {
                   2044:       Command->result = DID_OK << 16;
                   2045:       CompletionRoutine(Command);
                   2046:       return 0;
                   2047:     }
                   2048:   /*
                   2049:     Allocate a CCB from the Host Adapter's free list.  If there are none
                   2050:     available and memory allocation fails, return a result code of Bus Busy
                   2051:     so that this Command will be retried.
                   2052:   */
                   2053:   CCB = BusLogic_AllocateCCB(HostAdapter);
                   2054:   if (CCB == NULL)
                   2055:     {
                   2056:       Command->result = DID_BUS_BUSY << 16;
                   2057:       CompletionRoutine(Command);
                   2058:       return 0;
                   2059:     }
                   2060:   /*
                   2061:     Initialize the fields in the BusLogic Command Control Block (CCB).
                   2062:   */
                   2063:   if (SegmentCount == 0)
                   2064:     {
                   2065:       CCB->Opcode = BusLogic_InitiatorCCB;
                   2066:       CCB->DataLength = BufferLength;
                   2067:       CCB->DataPointer = BufferPointer;
                   2068:     }
                   2069:   else
                   2070:     {
                   2071:       SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
                   2072:       int Segment;
                   2073:       CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
                   2074:       CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
                   2075:       CCB->DataPointer = CCB->ScatterGatherList;
                   2076:       for (Segment = 0; Segment < SegmentCount; Segment++)
                   2077:        {
                   2078:          CCB->ScatterGatherList[Segment].SegmentByteCount =
                   2079:            ScatterList[Segment].length;
                   2080:          CCB->ScatterGatherList[Segment].SegmentDataPointer =
                   2081:            ScatterList[Segment].address;
                   2082:        }
                   2083:     }
                   2084:   switch (CDB[0])
                   2085:     {
                   2086:     case READ_6:
                   2087:     case READ_10:
                   2088:       CCB->DataDirection = BusLogic_DataInLengthChecked;
                   2089:       HostAdapter->ReadWriteOperationCount[TargetID]++;
                   2090:       break;
                   2091:     case WRITE_6:
                   2092:     case WRITE_10:
                   2093:       CCB->DataDirection = BusLogic_DataOutLengthChecked;
                   2094:       HostAdapter->ReadWriteOperationCount[TargetID]++;
                   2095:       break;
                   2096:     default:
                   2097:       CCB->DataDirection = BusLogic_UncheckedDataTransfer;
                   2098:       break;
                   2099:     }
                   2100:   CCB->CDB_Length = CDB_Length;
                   2101:   CCB->SenseDataLength = sizeof(Command->sense_buffer);
                   2102:   CCB->HostAdapterStatus = 0;
                   2103:   CCB->TargetDeviceStatus = 0;
                   2104:   CCB->TargetID = TargetID;
                   2105:   CCB->LogicalUnit = LogicalUnit;
                   2106:   /*
                   2107:     For Wide SCSI Host Adapters, Wide Mode CCBs are used to support more than
                   2108:     8 Logical Units per Target, and this requires setting the overloaded
                   2109:     TagEnable field to Logical Unit bit 5.
                   2110:   */
                   2111:   if (HostAdapter->HostWideSCSI)
                   2112:     {
                   2113:       CCB->TagEnable = LogicalUnit >> 5;
                   2114:       CCB->WideModeTagEnable = false;
                   2115:     }
                   2116:   else CCB->TagEnable = false;
                   2117:   /*
                   2118:     BusLogic recommends that after a Reset the first couple of commands that
                   2119:     are sent to a Target be sent in a non Tagged Queue fashion so that the Host
                   2120:     Adapter and Target can establish Synchronous Transfer before Queue Tag
                   2121:     messages can interfere with the Synchronous Negotiation message.  By
                   2122:     waiting to enable tagged Queuing until after the first 16 read/write
                   2123:     commands have been sent, it is assured that the Tagged Queuing message
                   2124:     will not occur while the partition table is printed.
                   2125:   */
                   2126:   if ((HostAdapter->TaggedQueuingPermitted & (1 << TargetID)) &&
                   2127:       Command->device->tagged_supported &&
                   2128:       (EnableTQ = HostAdapter->ReadWriteOperationCount[TargetID] - 16) >= 0)
                   2129:     {
                   2130:       BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
                   2131:       unsigned long CurrentTime = jiffies;
                   2132:       if (EnableTQ == 0)
                   2133:        printk("scsi%d: Tagged Queuing now active for Target %d\n",
                   2134:               HostAdapter->HostNumber, TargetID);
                   2135:       /*
                   2136:        When using Tagged Queuing with Simple Queue Tags, it appears that disk
                   2137:        drive controllers do not guarantee that a queued command will not
                   2138:        remain in a disconnected state indefinitely if commands that read or
                   2139:        write nearer the head position continue to arrive without interruption.
                   2140:        Therefore, for each Target Device this driver keeps track of the last
                   2141:        time either the queue was empty or an Ordered Queue Tag was issued.  If
                   2142:        more than 2 seconds have elapsed since this last sequence point, this
                   2143:        command will be issued with an Ordered Queue Tag rather than a Simple
                   2144:        Queue Tag, which forces the Target Device to complete all previously
                   2145:        queued commands before this command may be executed.
                   2146:       */
                   2147:       if (HostAdapter->QueuedOperationCount[TargetID] == 0)
                   2148:        HostAdapter->LastSequencePoint[TargetID] = CurrentTime;
                   2149:       else if (CurrentTime - HostAdapter->LastSequencePoint[TargetID] > 2*HZ)
                   2150:        {
                   2151:          HostAdapter->LastSequencePoint[TargetID] = CurrentTime;
                   2152:          QueueTag = BusLogic_OrderedQueueTag;
                   2153:        }
                   2154:       if (HostAdapter->HostWideSCSI)
                   2155:        {
                   2156:          CCB->WideModeTagEnable = true;
                   2157:          CCB->WideModeQueueTag = QueueTag;
                   2158:        }
                   2159:       else
                   2160:        {
                   2161:          CCB->TagEnable = true;
                   2162:          CCB->QueueTag = QueueTag;
                   2163:        }
                   2164:     }
                   2165:   memcpy(CCB->CDB, CDB, CDB_Length);
                   2166:   CCB->SenseDataPointer = (SCSI_SenseData_T *) &Command->sense_buffer;
                   2167:   CCB->Command = Command;
                   2168:   Command->scsi_done = CompletionRoutine;
                   2169:   /*
                   2170:     Place the CCB in an Outgoing Mailbox.  If there are no Outgoing
                   2171:     Mailboxes available, return a result code of Bus Busy so that this
                   2172:     Command will be retried.
                   2173:   */
                   2174:   if (!(BusLogic_WriteOutgoingMailbox(HostAdapter,
                   2175:                                      BusLogic_MailboxStartCommand, CCB)))
                   2176:     {
                   2177:       printk("scsi%d: cannot write Outgoing Mailbox\n",
                   2178:             HostAdapter->HostNumber);
                   2179:       BusLogic_DeallocateCCB(CCB);
                   2180:       Command->result = DID_BUS_BUSY << 16;
                   2181:       CompletionRoutine(Command);
                   2182:     }
                   2183:   return 0;
                   2184: }
                   2185: 
                   2186: 
                   2187: /*
                   2188:   BusLogic_AbortCommand aborts Command if possible.
                   2189: */
                   2190: 
                   2191: int BusLogic_AbortCommand(SCSI_Command_T *Command)
                   2192: {
                   2193:   BusLogic_HostAdapter_T *HostAdapter =
                   2194:     (BusLogic_HostAdapter_T *) Command->host->hostdata;
                   2195:   unsigned long CommandPID = Command->pid;
                   2196:   unsigned char InterruptRegister;
                   2197:   BusLogic_CCB_T *CCB;
                   2198:   int Result;
                   2199:   /*
                   2200:     If the Host Adapter has posted an interrupt but the Interrupt Handler
                   2201:     has not been called for some reason (i.e. the interrupt was lost), try
                   2202:     calling the Interrupt Handler directly to process the commands that
                   2203:     have been completed.
                   2204:   */
                   2205:   InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
                   2206:   if (InterruptRegister & BusLogic_InterruptValid)
                   2207:     {
                   2208:       unsigned long ProcessorFlags;
                   2209:       printk("scsi%d: Recovering Lost/Delayed Interrupt for IRQ Channel %d\n",
                   2210:             HostAdapter->HostNumber, HostAdapter->IRQ_Channel);
                   2211:       save_flags(ProcessorFlags);
                   2212:       cli();
                   2213:       BusLogic_InterruptHandler(HostAdapter->IRQ_Channel, NULL);
                   2214:       restore_flags(ProcessorFlags);
                   2215:       return SCSI_ABORT_SNOOZE;
                   2216:     }
                   2217:   /*
                   2218:     Find the CCB to be aborted if possible.
                   2219:   */
                   2220:   BusLogic_LockHostAdapter(HostAdapter);
                   2221:   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
                   2222:     if (CCB->Command == Command) break;
                   2223:   BusLogic_UnlockHostAdapter(HostAdapter);
                   2224:   if (CCB == NULL)
                   2225:     {
                   2226:       printk("scsi%d: Unable to Abort Command to Target %d - No CCB Found\n",
                   2227:             HostAdapter->HostNumber, Command->target);
                   2228:       return SCSI_ABORT_NOT_RUNNING;
                   2229:     }
                   2230:   /*
                   2231:     Briefly pause to see if this command will complete.
                   2232:   */
                   2233:   printk("scsi%d: Pausing briefly to see if CCB #%d "
                   2234:         "to Target %d will complete\n",
                   2235:         HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
                   2236:   BusLogic_Delay(2);
                   2237:   /*
                   2238:     If this CCB is still Active and still refers to the same Command, then
                   2239:     actually aborting this Command is necessary.
                   2240:   */
                   2241:   BusLogic_LockHostAdapter(HostAdapter);
                   2242:   Result = SCSI_ABORT_NOT_RUNNING;
                   2243:   if (CCB->Status == BusLogic_CCB_Active &&
                   2244:       CCB->Command == Command && Command->pid == CommandPID)
                   2245:     {
                   2246:       /*
                   2247:        Attempt to abort this CCB.
                   2248:       */
                   2249:       if (BusLogic_WriteOutgoingMailbox(HostAdapter,
                   2250:                                        BusLogic_MailboxAbortCommand, CCB))
                   2251:        {
                   2252:          printk("scsi%d: Aborting CCB #%d to Target %d\n",
                   2253:                 HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
                   2254:          Result = SCSI_ABORT_PENDING;
                   2255:        }
                   2256:       else
                   2257:        {
                   2258:          printk("scsi%d: Unable to Abort CCB #%d to Target %d - "
                   2259:                 "No Outgoing Mailboxes\n", HostAdapter->HostNumber,
                   2260:                 CCB->SerialNumber, CCB->TargetID);
                   2261:          Result = SCSI_ABORT_BUSY;
                   2262:        }
                   2263:     }
                   2264:   else printk("scsi%d: CCB #%d to Target %d completed\n",
                   2265:              HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
                   2266:   BusLogic_UnlockHostAdapter(HostAdapter);
                   2267:   return Result;
                   2268: }
                   2269: 
                   2270: 
                   2271: /*
                   2272:   BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
                   2273:   currently executing SCSI commands as having been reset, as well as
                   2274:   the specified Command if non-NULL.
                   2275: */
                   2276: 
                   2277: static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
                   2278:                                     SCSI_Command_T *Command)
                   2279: {
                   2280:   BusLogic_CCB_T *CCB;
                   2281:   if (Command == NULL)
                   2282:     printk("scsi%d: Resetting %s due to SCSI Reset State Interrupt\n",
                   2283:           HostAdapter->HostNumber, HostAdapter->BoardName);
                   2284:   else printk("scsi%d: Resetting %s due to Target %d\n",
                   2285:              HostAdapter->HostNumber, HostAdapter->BoardName, Command->target);
                   2286:   /*
                   2287:     Attempt to Reset and Reinitialize the Host Adapter.
                   2288:   */
                   2289:   BusLogic_LockHostAdapter(HostAdapter);
                   2290:   if (!(BusLogic_HardResetHostAdapter(HostAdapter) &&
                   2291:        BusLogic_InitializeHostAdapter(HostAdapter)))
                   2292:     {
                   2293:       printk("scsi%d: Resetting %s Failed\n",
                   2294:              HostAdapter->HostNumber, HostAdapter->BoardName);
                   2295:       BusLogic_UnlockHostAdapter(HostAdapter);
                   2296:       return SCSI_RESET_ERROR;
                   2297:     }
                   2298:   BusLogic_UnlockHostAdapter(HostAdapter);
                   2299:   /*
                   2300:     Wait a few seconds between the Host Adapter Hard Reset which initiates
                   2301:     a SCSI Bus Reset and issuing any SCSI commands.  Some SCSI devices get
                   2302:     confused if they receive SCSI commands too soon after a SCSI Bus Reset.
                   2303:   */
                   2304:   BusLogic_Delay(HostAdapter->BusSettleTime);
                   2305:   /*
                   2306:     Mark all currently executing CCBs as having been reset.
                   2307:   */
                   2308:   BusLogic_LockHostAdapter(HostAdapter);
                   2309:   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
                   2310:     if (CCB->Status == BusLogic_CCB_Active)
                   2311:       {
                   2312:        CCB->Status = BusLogic_CCB_Reset;
                   2313:        if (CCB->Command == Command)
                   2314:          {
                   2315:            CCB->Command = NULL;
                   2316:            /*
                   2317:              Disable Tagged Queuing if it was active for this Target Device.
                   2318:            */
                   2319:            if (((HostAdapter->HostWideSCSI && CCB->WideModeTagEnable) ||
                   2320:                 (!HostAdapter->HostWideSCSI && CCB->TagEnable)) &&
                   2321:                (HostAdapter->TaggedQueuingPermitted & (1 << CCB->TargetID)))
                   2322:              {
                   2323:                HostAdapter->TaggedQueuingPermitted &= ~(1 << CCB->TargetID);
                   2324:                printk("scsi%d: Tagged Queuing now disabled for Target %d\n",
                   2325:                       HostAdapter->HostNumber, CCB->TargetID);
                   2326:              }
                   2327:          }
                   2328:       }
                   2329:   BusLogic_UnlockHostAdapter(HostAdapter);
                   2330:   /*
                   2331:     Perform completion processing for the Command being Reset.
                   2332:   */
                   2333:   if (Command != NULL)
                   2334:     {
                   2335:       Command->result = DID_RESET << 16;
                   2336:       Command->scsi_done(Command);
                   2337:     }
                   2338:   /*
                   2339:     Perform completion processing for any other active CCBs.
                   2340:   */
                   2341:   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
                   2342:     if (CCB->Status == BusLogic_CCB_Reset)
                   2343:       {
                   2344:        Command = CCB->Command;
                   2345:        BusLogic_DeallocateCCB(CCB);
                   2346:        if (Command != NULL)
                   2347:          {
                   2348:            Command->result = DID_RESET << 16;
                   2349:            Command->scsi_done(Command);
                   2350:          }
                   2351:       }
                   2352:   return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
                   2353: }
                   2354: 
                   2355: 
                   2356: /*
                   2357:   BusLogic_BusDeviceReset sends a Bus Device Reset to the Target
                   2358:   associated with Command.
                   2359: */
                   2360: 
                   2361: static int BusLogic_BusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
                   2362:                                   SCSI_Command_T *Command)
                   2363: {
                   2364:   BusLogic_CCB_T *CCB = BusLogic_AllocateCCB(HostAdapter), *XCCB;
                   2365:   unsigned char TargetID = Command->target;
                   2366:   /*
                   2367:     If sending a Bus Device Reset is impossible, attempt a full Host
                   2368:     Adapter Hard Reset and SCSI Bus Reset.
                   2369:   */
                   2370:   if (CCB == NULL)
                   2371:     return BusLogic_ResetHostAdapter(HostAdapter, Command);
                   2372:   printk("scsi%d: Sending Bus Device Reset CCB #%d to Target %d\n",
                   2373:         HostAdapter->HostNumber, CCB->SerialNumber, TargetID);
                   2374:   CCB->Opcode = BusLogic_SCSIBusDeviceReset;
                   2375:   CCB->TargetID = TargetID;
                   2376:   CCB->Command = Command;
                   2377:   /*
                   2378:     If there is a currently executing CCB in the Host Adapter for this Command,
                   2379:     then an Incoming Mailbox entry will be made with a completion code of
                   2380:     BusLogic_HostAdapterAssertedBusDeviceReset.  Otherwise, the CCB's Command
                   2381:     field will be left pointing to the Command so that the interrupt for the
                   2382:     completion of the Bus Device Reset can call the Completion Routine for the
                   2383:     Command.
                   2384:   */
                   2385:   BusLogic_LockHostAdapter(HostAdapter);
                   2386:   for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll)
                   2387:     if (XCCB->Command == Command && XCCB->Status == BusLogic_CCB_Active)
                   2388:       {
                   2389:        CCB->Command = NULL;
                   2390:        /*
                   2391:          Disable Tagged Queuing if it was active for this Target Device.
                   2392:        */
                   2393:        if (((HostAdapter->HostWideSCSI && XCCB->WideModeTagEnable) ||
                   2394:            (!HostAdapter->HostWideSCSI && XCCB->TagEnable)) &&
                   2395:            (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
                   2396:          {
                   2397:            HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
                   2398:            printk("scsi%d: Tagged Queuing now disabled for Target %d\n",
                   2399:                   HostAdapter->HostNumber, TargetID);
                   2400:          }
                   2401:        break;
                   2402:       }
                   2403:   BusLogic_UnlockHostAdapter(HostAdapter);
                   2404:   /*
                   2405:     Attempt to write an Outgoing Mailbox with the Bus Device Reset CCB.
                   2406:     If sending a Bus Device Reset is impossible, attempt a full Host
                   2407:     Adapter Hard Reset and SCSI Bus Reset.
                   2408:   */
                   2409:   if (!(BusLogic_WriteOutgoingMailbox(HostAdapter,
                   2410:                                      BusLogic_MailboxStartCommand, CCB)))
                   2411:     {
                   2412:       printk("scsi%d: cannot write Outgoing Mailbox for Bus Device Reset\n",
                   2413:             HostAdapter->HostNumber);
                   2414:       BusLogic_DeallocateCCB(CCB);
                   2415:       return BusLogic_ResetHostAdapter(HostAdapter, Command);
                   2416:     }
                   2417:   HostAdapter->ReadWriteOperationCount[TargetID] = 0;
                   2418:   HostAdapter->QueuedOperationCount[TargetID] = 0;
                   2419:   return SCSI_RESET_PENDING;
                   2420: }
                   2421: 
                   2422: 
                   2423: /*
                   2424:   BusLogic_ResetCommand takes appropriate action to reset Command.
                   2425: */
                   2426: 
                   2427: int BusLogic_ResetCommand(SCSI_Command_T *Command)
                   2428: {
                   2429:   BusLogic_HostAdapter_T *HostAdapter =
                   2430:     (BusLogic_HostAdapter_T *) Command->host->hostdata;
                   2431:   unsigned char TargetID = Command->target;
                   2432:   unsigned char ErrorRecoveryOption =
                   2433:     HostAdapter->ErrorRecoveryOption[TargetID];
                   2434:   if (ErrorRecoveryOption == BusLogic_ErrorRecoveryDefault)
                   2435:     if (Command->host->suggest_bus_reset)
                   2436:       ErrorRecoveryOption = BusLogic_ErrorRecoveryHardReset;
                   2437:     else ErrorRecoveryOption = BusLogic_ErrorRecoveryBusDeviceReset;
                   2438:   switch (ErrorRecoveryOption)
                   2439:     {
                   2440:     case BusLogic_ErrorRecoveryHardReset:
                   2441:       return BusLogic_ResetHostAdapter(HostAdapter, Command);
                   2442:     case BusLogic_ErrorRecoveryBusDeviceReset:
                   2443:       if (HostAdapter->CommandSuccessfulFlag[TargetID])
                   2444:        {
                   2445:          HostAdapter->CommandSuccessfulFlag[TargetID] = false;
                   2446:          return BusLogic_BusDeviceReset(HostAdapter, Command);
                   2447:        }
                   2448:       else return BusLogic_ResetHostAdapter(HostAdapter, Command);
                   2449:     }
                   2450:   printk("scsi%d: Error Recovery for Target %d Suppressed\n",
                   2451:         HostAdapter->HostNumber, TargetID);
                   2452:   return SCSI_RESET_PUNT;
                   2453: }
                   2454: 
                   2455: 
                   2456: /*
                   2457:   BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
                   2458:   Parameters for Disk.  The default disk geometry is 64 heads, 32 sectors, and
                   2459:   the appropriate number of cylinders so as not to exceed drive capacity.  In
                   2460:   order for disks equal to or larger than 1 GB to be addressable by the BIOS
                   2461:   without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
                   2462:   may be enabled in AutoSCSI on "C" Series boards or by a dip switch setting
                   2463:   on older boards.  With Extended Translation enabled, drives between 1 GB
                   2464:   inclusive and 2 GB exclusive are given a disk geometry of 128 heads and 32
                   2465:   sectors, and drives between 2 GB inclusive and 8 GB exclusive are given a
                   2466:   disk geometry of 255 heads and 63 sectors.  On "C" Series boards the firmware
                   2467:   can be queried for the precise translation in effect for each drive
                   2468:   individually, but there is really no need to do so since we know the total
                   2469:   capacity of the drive and whether Extended Translation is enabled, hence we
                   2470:   can deduce the BIOS disk geometry that must be in effect.
                   2471: */
                   2472: 
                   2473: int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
                   2474:                                int *Parameters)
                   2475: {
                   2476:   BusLogic_HostAdapter_T *HostAdapter =
                   2477:     (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
                   2478:   BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
                   2479:   if (HostAdapter->ExtendedTranslation &&
                   2480:       Disk->capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */)
                   2481:     if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
                   2482:       {
                   2483:        DiskParameters->Heads = 255;
                   2484:        DiskParameters->Sectors = 63;
                   2485:       }
                   2486:     else
                   2487:       {
                   2488:        DiskParameters->Heads = 128;
                   2489:        DiskParameters->Sectors = 32;
                   2490:       }
                   2491:   else
                   2492:     {
                   2493:       DiskParameters->Heads = 64;
                   2494:       DiskParameters->Sectors = 32;
                   2495:     }
                   2496:   DiskParameters->Cylinders =
                   2497:     Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
                   2498:   return 0;
                   2499: }
                   2500: 
                   2501: 
                   2502: /*
                   2503:   BusLogic_Setup handles processing of Kernel Command Line Arguments.
                   2504: 
                   2505:   For the BusLogic driver, a kernel command line entry comprises the driver
                   2506:   identifier "BusLogic=" optionally followed by a comma-separated sequence of
                   2507:   integers and then optionally followed by a comma-separated sequence of
                   2508:   strings.  Each command line entry applies to one BusLogic Host Adapter.
                   2509:   Multiple command line entries may be used in systems which contain multiple
                   2510:   BusLogic Host Adapters.
                   2511: 
                   2512:   The first integer specified is the I/O Address at which the Host Adapter is
                   2513:   located.  If unspecified, it defaults to 0 which means to apply this entry to
                   2514:   the first BusLogic Host Adapter found during the default probe sequence.  If
                   2515:   any I/O Address parameters are provided on the command line, then the default
                   2516:   probe sequence is omitted.
                   2517: 
                   2518:   The second integer specified is the number of Concurrent Commands per Logical
                   2519:   Unit to allow for Target Devices on the Host Adapter.  If unspecified, it
                   2520:   defaults to 0 which means to use the value of BusLogic_Concurrency for
                   2521:   non-ISA Host Adapters, or BusLogic_Concurrency_ISA for ISA Host Adapters.
                   2522: 
                   2523:   The third integer specified is the Bus Settle Time in seconds.  This is
                   2524:   the amount of time to wait between a Host Adapter Hard Reset which initiates
                   2525:   a SCSI Bus Reset and issuing any SCSI commands.  If unspecified, it defaults
                   2526:   to 0 which means to use the value of BusLogic_DefaultBusSettleTime.
                   2527: 
                   2528:   The fourth integer specified is the Local Options.  If unspecified, it
                   2529:   defaults to 0.  Note that Local Options are only applied to a specific Host
                   2530:   Adapter.
                   2531: 
                   2532:   The fifth integer specified is the Global Options.  If unspecified, it
                   2533:   defaults to 0.  Note that Global Options are applied across all Host
                   2534:   Adapters.
                   2535: 
                   2536:   The string options are used to provide control over Tagged Queuing and Error
                   2537:   Recovery. If both Tagged Queuing and Error Recovery strings are provided, the
                   2538:   Tagged Queuing specification string must come first.
                   2539: 
                   2540:   The Tagged Queuing specification begins with "TQ:" and allows for explicitly
                   2541:   specifying whether Tagged Queuing is permitted on Target Devices that support
                   2542:   it.  The following specification options are available:
                   2543: 
                   2544:   TQ:Default           Tagged Queuing will be permitted based on the firmware
                   2545:                        version of the BusLogic Host Adapter and based on
                   2546:                        whether the Concurrency value allows queuing multiple
                   2547:                        commands.
                   2548: 
                   2549:   TQ:Enable            Tagged Queuing will be enabled for all Target Devices
                   2550:                        on this Host Adapter overriding any limitation that
                   2551:                        would otherwise be imposed based on the Host Adapter
                   2552:                        firmware version.
                   2553: 
                   2554:   TQ:Disable           Tagged Queuing will be disabled for all Target Devices
                   2555:                        on this Host Adapter.
                   2556: 
                   2557:   TQ:<Per-Target-Spec> Tagged Queuing will be controlled individually for each
                   2558:                        Target Device.  <Per-Target-Spec> is a sequence of "Y",
                   2559:                        "N", and "X" characters.  "Y" enabled Tagged Queuing,
                   2560:                        "N" disables Tagged Queuing, and "X" accepts the
                   2561:                        default based on the firmware version.  The first
                   2562:                        character refers to Target 0, the second to Target 1,
                   2563:                        and so on; if the sequence of "Y", "N", and "X"
                   2564:                        characters does not cover all the Target Devices,
                   2565:                        unspecified characters are assumed to be "X".
                   2566: 
                   2567:   Note that explicitly requesting Tagged Queuing may lead to problems; this
                   2568:   facility is provided primarily to allow disabling Tagged Queuing on Target
                   2569:   Devices that do not implement it correctly.
                   2570: 
                   2571:   The Error Recovery specification begins with "ER:" and allows for explicitly
                   2572:   specifying the Error Recovery action to be performed when ResetCommand is
                   2573:   called due to a SCSI Command failing to complete successfully.  The following
                   2574:   specification options are available:
                   2575: 
                   2576:   ER:Default           Error Recovery will select between the Hard Reset and
                   2577:                        Bus Device Reset options based on the recommendation
                   2578:                        of the SCSI Subsystem.
                   2579: 
                   2580:   ER:HardReset         Error Recovery will initiate a Host Adapter Hard Reset
                   2581:                        which also causes a SCSI Bus Reset.
                   2582: 
                   2583:   ER:BusDeviceReset    Error Recovery will send a Bus Device Reset message to
                   2584:                        the individual Target Device causing the error.  If
                   2585:                        Error Recovery is again initiated for this Target
                   2586:                        Device and no SCSI Command to this Target Device has
                   2587:                        completed successfully since the Bus Device Reset
                   2588:                        message was sent, then a Hard Reset will be attempted.
                   2589: 
                   2590:   ER:None              Error Recovery will be suppressed.  This option should
                   2591:                        only be selected if a SCSI Bus Reset or Bus Device
                   2592:                        Reset will cause the Target Device to fail completely
                   2593:                        and unrecoverably.
                   2594: 
                   2595:   ER:<Per-Target-Spec> Error Recovery will be controlled individually for each
                   2596:                        Target Device.  <Per-Target-Spec> is a sequence of "D",
                   2597:                        "H", "B", and "N" characters.  "D" selects Default, "H"
                   2598:                        selects Hard Reset, "B" selects Bus Device Reset, and
                   2599:                        "N" selects None.  The first character refers to Target
                   2600:                        0, the second to Target 1, and so on; if the sequence
                   2601:                        of "D", "H", "B", and "N" characters does not cover all
                   2602:                        the Target Devices, unspecified characters are assumed
                   2603:                        to be "D".
                   2604: */
                   2605: 
                   2606: void BusLogic_Setup(char *Strings, int *Integers)
                   2607: {
                   2608:   BusLogic_CommandLineEntry_T *CommandLineEntry =
                   2609:     &BusLogic_CommandLineEntries[BusLogic_CommandLineEntryCount++];
                   2610:   static int ProbeListIndex = 0;
                   2611:   int IntegerCount = Integers[0], TargetID, i;
                   2612:   CommandLineEntry->IO_Address = 0;
                   2613:   CommandLineEntry->Concurrency = 0;
                   2614:   CommandLineEntry->BusSettleTime = 0;
                   2615:   CommandLineEntry->LocalOptions = 0;
                   2616:   CommandLineEntry->TaggedQueuingPermitted = 0;
                   2617:   CommandLineEntry->TaggedQueuingPermittedMask = 0;
                   2618:   memset(CommandLineEntry->ErrorRecoveryOption,
                   2619:         BusLogic_ErrorRecoveryDefault,
                   2620:         sizeof(CommandLineEntry->ErrorRecoveryOption));
                   2621:   if (IntegerCount > 5)
                   2622:     printk("BusLogic: Unexpected Command Line Integers ignored\n");
                   2623:   if (IntegerCount >= 1)
                   2624:     {
                   2625:       unsigned short IO_Address = Integers[1];
                   2626:       if (IO_Address > 0)
                   2627:        {
                   2628:          for (i = 0; ; i++)
                   2629:            if (BusLogic_IO_StandardAddresses[i] == 0)
                   2630:              {
                   2631:                printk("BusLogic: Invalid Command Line Entry "
                   2632:                       "(illegal I/O Address 0x%X)\n", IO_Address);
                   2633:                return;
                   2634:              }
                   2635:            else if (i < ProbeListIndex &&
                   2636:                     IO_Address == BusLogic_IO_AddressProbeList[i])
                   2637:              {
                   2638:                printk("BusLogic: Invalid Command Line Entry "
                   2639:                       "(duplicate I/O Address 0x%X)\n", IO_Address);
                   2640:                return;
                   2641:              }
                   2642:            else if (IO_Address >= 0x1000 ||
                   2643:                     IO_Address == BusLogic_IO_StandardAddresses[i]) break;
                   2644:          BusLogic_IO_AddressProbeList[ProbeListIndex++] = IO_Address;
                   2645:          BusLogic_IO_AddressProbeList[ProbeListIndex] = 0;
                   2646:        }
                   2647:       CommandLineEntry->IO_Address = IO_Address;
                   2648:     }
                   2649:   if (IntegerCount >= 2)
                   2650:     {
                   2651:       unsigned short Concurrency = Integers[2];
                   2652:       if (Concurrency > BusLogic_MailboxCount)
                   2653:        {
                   2654:          printk("BusLogic: Invalid Command Line Entry "
                   2655:                 "(illegal Concurrency %d)\n", Concurrency);
                   2656:          return;
                   2657:        }
                   2658:       CommandLineEntry->Concurrency = Concurrency;
                   2659:     }
                   2660:   if (IntegerCount >= 3)
                   2661:     CommandLineEntry->BusSettleTime = Integers[3];
                   2662:   if (IntegerCount >= 4)
                   2663:     CommandLineEntry->LocalOptions = Integers[4];
                   2664:   if (IntegerCount >= 5)
                   2665:     BusLogic_GlobalOptions |= Integers[5];
                   2666:   if (!(BusLogic_CommandLineEntryCount == 0 || ProbeListIndex == 0 ||
                   2667:        BusLogic_CommandLineEntryCount == ProbeListIndex))
                   2668:     {
                   2669:       printk("BusLogic: Invalid Command Line Entry "
                   2670:             "(all or no I/O Addresses must be specified)\n");
                   2671:       return;
                   2672:     }
                   2673:   if (Strings == NULL) return;
                   2674:   if (strncmp(Strings, "TQ:", 3) == 0)
                   2675:     {
                   2676:       Strings += 3;
                   2677:       if (strncmp(Strings, "Default", 7) == 0)
                   2678:        Strings += 7;
                   2679:       else if (strncmp(Strings, "Enable", 6) == 0)
                   2680:        {
                   2681:          Strings += 6;
                   2682:          CommandLineEntry->TaggedQueuingPermitted = 0xFFFF;
                   2683:          CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
                   2684:        }
                   2685:       else if (strncmp(Strings, "Disable", 7) == 0)
                   2686:        {
                   2687:          Strings += 7;
                   2688:          CommandLineEntry->TaggedQueuingPermitted = 0x0000;
                   2689:          CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
                   2690:        }
                   2691:       else
                   2692:        for (TargetID = 0; TargetID < BusLogic_MaxTargetIDs; TargetID++)
                   2693:          switch (*Strings++)
                   2694:            {
                   2695:            case 'Y':
                   2696:              CommandLineEntry->TaggedQueuingPermitted |= 1 << TargetID;
                   2697:              CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
                   2698:              break;
                   2699:            case 'N':
                   2700:              CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
                   2701:              break;
                   2702:            case 'X':
                   2703:              break;
                   2704:            default:
                   2705:              Strings--;
                   2706:              TargetID = BusLogic_MaxTargetIDs;
                   2707:              break;
                   2708:            }
                   2709:     }
                   2710:   if (*Strings == ',') Strings++;
                   2711:   if (strncmp(Strings, "ER:", 3) == 0)
                   2712:     {
                   2713:       Strings += 3;
                   2714:       if (strncmp(Strings, "Default", 7) == 0)
                   2715:        Strings += 7;
                   2716:       else if (strncmp(Strings, "HardReset", 9) == 0)
                   2717:        {
                   2718:          Strings += 9;
                   2719:          memset(CommandLineEntry->ErrorRecoveryOption,
                   2720:                 BusLogic_ErrorRecoveryHardReset,
                   2721:                 sizeof(CommandLineEntry->ErrorRecoveryOption));
                   2722:        }
                   2723:       else if (strncmp(Strings, "BusDeviceReset", 14) == 0)
                   2724:        {
                   2725:          Strings += 14;
                   2726:          memset(CommandLineEntry->ErrorRecoveryOption,
                   2727:                 BusLogic_ErrorRecoveryBusDeviceReset,
                   2728:                 sizeof(CommandLineEntry->ErrorRecoveryOption));
                   2729:        }
                   2730:       else if (strncmp(Strings, "None", 4) == 0)
                   2731:        {
                   2732:          Strings += 4;
                   2733:          memset(CommandLineEntry->ErrorRecoveryOption,
                   2734:                 BusLogic_ErrorRecoveryNone,
                   2735:                 sizeof(CommandLineEntry->ErrorRecoveryOption));
                   2736:        }
                   2737:       else
                   2738:        for (TargetID = 0; TargetID < BusLogic_MaxTargetIDs; TargetID++)
                   2739:          switch (*Strings++)
                   2740:            {
                   2741:            case 'D':
                   2742:              CommandLineEntry->ErrorRecoveryOption[TargetID] =
                   2743:                BusLogic_ErrorRecoveryDefault;
                   2744:              break;
                   2745:            case 'H':
                   2746:              CommandLineEntry->ErrorRecoveryOption[TargetID] =
                   2747:                BusLogic_ErrorRecoveryHardReset;
                   2748:              break;
                   2749:            case 'B':
                   2750:              CommandLineEntry->ErrorRecoveryOption[TargetID] =
                   2751:                BusLogic_ErrorRecoveryBusDeviceReset;
                   2752:              break;
                   2753:            case 'N':
                   2754:              CommandLineEntry->ErrorRecoveryOption[TargetID] =
                   2755:                BusLogic_ErrorRecoveryNone;
                   2756:              break;
                   2757:            default:
                   2758:              Strings--;
                   2759:              TargetID = BusLogic_MaxTargetIDs;
                   2760:              break;
                   2761:            }
                   2762:     }
                   2763:   if (*Strings != '\0')
                   2764:     printk("BusLogic: Unexpected Command Line String '%s' ignored\n", Strings);
                   2765: }
                   2766: 
                   2767: 
                   2768: /*
                   2769:   Include Module support if requested.
                   2770: */
                   2771: 
                   2772: 
                   2773: #ifdef MODULE
                   2774: 
                   2775: SCSI_Host_Template_T driver_template = BUSLOGIC;
                   2776: 
                   2777: #include "scsi_module.c"
                   2778: 
                   2779: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.