Annotation of Gnu-Mach/linux/src/drivers/scsi/BusLogic.c, revision 1.1.1.1

1.1       root        1: /*
                      2: 
                      3:   Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
                      4: 
                      5:   Copyright 1995-1998 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.
                     10: 
                     11:   This program is distributed in the hope that it will be useful, but
                     12:   WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
                     13:   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     14:   for complete details.
                     15: 
                     16:   The author respectfully requests that any modifications to this software be
                     17:   sent directly to him for evaluation and testing.
                     18: 
                     19:   Special thanks to Wayne Yen, Jin-Lon Hon, and Alex Win of BusLogic, whose
                     20:   advice has been invaluable, to David Gentzel, for writing the original Linux
                     21:   BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site.
                     22: 
                     23:   Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
                     24:   Manager available as freely redistributable source code.
                     25: 
                     26: */
                     27: 
                     28: 
                     29: #define BusLogic_DriverVersion         "2.0.15"
                     30: #define BusLogic_DriverDate            "17 August 1998"
                     31: 
                     32: 
                     33: #include <linux/version.h>
                     34: #include <linux/module.h>
                     35: #include <linux/config.h>
                     36: #include <linux/types.h>
                     37: #include <linux/blkdev.h>
                     38: #include <linux/delay.h>
                     39: #include <linux/ioport.h>
                     40: #include <linux/mm.h>
                     41: #include <linux/sched.h>
                     42: #include <linux/stat.h>
                     43: #include <linux/pci.h>
                     44: #include <linux/bios32.h>
                     45: #include <asm/dma.h>
                     46: #include <asm/io.h>
                     47: #include <asm/irq.h>
                     48: #include <asm/system.h>
                     49: #include "scsi.h"
                     50: #include "hosts.h"
                     51: #include "sd.h"
                     52: #include "BusLogic.h"
                     53: #include "FlashPoint.c"
                     54: 
                     55: 
                     56: /*
                     57:   BusLogic_DriverOptionsCount is a count of the number of BusLogic Driver
                     58:   Options specifications provided via the Linux Kernel Command Line or via
                     59:   the Loadable Kernel Module Installation Facility.
                     60: */
                     61: 
                     62: static int
                     63:   BusLogic_DriverOptionsCount =                        0;
                     64: 
                     65: 
                     66: /*
                     67:   BusLogic_DriverOptions is an array of Driver Options structures representing
                     68:   BusLogic Driver Options specifications provided via the Linux Kernel Command
                     69:   Line or via the Loadable Kernel Module Installation Facility.
                     70: */
                     71: 
                     72: static BusLogic_DriverOptions_T
                     73:   BusLogic_DriverOptions[BusLogic_MaxHostAdapters];
                     74: 
                     75: 
                     76: /*
                     77:   BusLogic_Options can be assigned a string by the Loadable Kernel Module
                     78:   Installation Facility to be parsed for BusLogic Driver Options
                     79:   specifications.
                     80: */
                     81: 
                     82: static char
                     83:   *BusLogic_Options =                          NULL;
                     84: 
                     85: 
                     86: /*
                     87:   BusLogic_ProbeOptions is a set of Probe Options to be applied across
                     88:   all BusLogic Host Adapters.
                     89: */
                     90: 
                     91: static BusLogic_ProbeOptions_T
                     92:   BusLogic_ProbeOptions =                      { 0 };
                     93: 
                     94: 
                     95: /*
                     96:   BusLogic_GlobalOptions is a set of Global Options to be applied across
                     97:   all BusLogic Host Adapters.
                     98: */
                     99: 
                    100: static BusLogic_GlobalOptions_T
                    101:   BusLogic_GlobalOptions =                     { 0 };
                    102: 
                    103: 
                    104: /*
                    105:   BusLogic_FirstRegisteredHostAdapter and BusLogic_LastRegisteredHostAdapter
                    106:   are pointers to the first and last registered BusLogic Host Adapters.
                    107: */
                    108: 
                    109: static BusLogic_HostAdapter_T
                    110:   *BusLogic_FirstRegisteredHostAdapter =       NULL,
                    111:   *BusLogic_LastRegisteredHostAdapter =                NULL;
                    112: 
                    113: 
                    114: /*
                    115:   BusLogic_ProbeInfoCount is the number of entries in BusLogic_ProbeInfoList.
                    116: */
                    117: 
                    118: static int
                    119:   BusLogic_ProbeInfoCount =                    0;
                    120: 
                    121: 
                    122: /*
                    123:   BusLogic_ProbeInfoList is the list of I/O Addresses and Bus Probe Information
                    124:   to be checked for potential BusLogic Host Adapters.  It is initialized by
                    125:   interrogating the PCI Configuration Space on PCI machines as well as from the
                    126:   list of standard BusLogic I/O Addresses.
                    127: */
                    128: 
                    129: static BusLogic_ProbeInfo_T
                    130:   *BusLogic_ProbeInfoList =                    NULL;
                    131: 
                    132: 
                    133: /*
                    134:   BusLogic_CommandFailureReason holds a string identifying the reason why a
                    135:   call to BusLogic_Command failed.  It is only non-NULL when BusLogic_Command
                    136:   returns a failure code.
                    137: */
                    138: 
                    139: static char
                    140:   *BusLogic_CommandFailureReason;
                    141: 
                    142: 
                    143: /*
                    144:   BusLogic_ProcDirectoryEntry is the BusLogic /proc/scsi directory entry.
                    145: */
                    146: 
                    147: PROC_DirectoryEntry_T
                    148:   BusLogic_ProcDirectoryEntry =
                    149:     { PROC_SCSI_BUSLOGIC, 8, "BusLogic", S_IFDIR | S_IRUGO | S_IXUGO, 2 };
                    150: 
                    151: 
                    152: /*
                    153:   BusLogic_AnnounceDriver announces the Driver Version and Date, Author's
                    154:   Name, Copyright Notice, and Electronic Mail Address.
                    155: */
                    156: 
                    157: static void BusLogic_AnnounceDriver(BusLogic_HostAdapter_T *HostAdapter)
                    158: {
                    159:   BusLogic_Announce("***** BusLogic SCSI Driver Version "
                    160:                    BusLogic_DriverVersion " of "
                    161:                    BusLogic_DriverDate " *****\n", HostAdapter);
                    162:   BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff "
                    163:                    "<[email protected]>\n", HostAdapter);
                    164: }
                    165: 
                    166: 
                    167: /*
                    168:   BusLogic_DriverInfo returns the Host Adapter Name to identify this SCSI
                    169:   Driver and Host Adapter.
                    170: */
                    171: 
                    172: const char *BusLogic_DriverInfo(SCSI_Host_T *Host)
                    173: {
                    174:   BusLogic_HostAdapter_T *HostAdapter =
                    175:     (BusLogic_HostAdapter_T *) Host->hostdata;
                    176:   return HostAdapter->FullModelName;
                    177: }
                    178: 
                    179: 
                    180: /*
                    181:   BusLogic_RegisterHostAdapter adds Host Adapter to the list of registered
                    182:   BusLogic Host Adapters.
                    183: */
                    184: 
                    185: static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
                    186: {
                    187:   HostAdapter->Next = NULL;
                    188:   if (BusLogic_FirstRegisteredHostAdapter == NULL)
                    189:     {
                    190:       BusLogic_FirstRegisteredHostAdapter = HostAdapter;
                    191:       BusLogic_LastRegisteredHostAdapter = HostAdapter;
                    192:     }
                    193:   else
                    194:     {
                    195:       BusLogic_LastRegisteredHostAdapter->Next = HostAdapter;
                    196:       BusLogic_LastRegisteredHostAdapter = HostAdapter;
                    197:     }
                    198: }
                    199: 
                    200: 
                    201: /*
                    202:   BusLogic_UnregisterHostAdapter removes Host Adapter from the list of
                    203:   registered BusLogic Host Adapters.
                    204: */
                    205: 
                    206: static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
                    207: {
                    208:   if (HostAdapter == BusLogic_FirstRegisteredHostAdapter)
                    209:     {
                    210:       BusLogic_FirstRegisteredHostAdapter =
                    211:        BusLogic_FirstRegisteredHostAdapter->Next;
                    212:       if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
                    213:        BusLogic_LastRegisteredHostAdapter = NULL;
                    214:     }
                    215:   else
                    216:     {
                    217:       BusLogic_HostAdapter_T *PreviousHostAdapter =
                    218:        BusLogic_FirstRegisteredHostAdapter;
                    219:       while (PreviousHostAdapter != NULL &&
                    220:             PreviousHostAdapter->Next != HostAdapter)
                    221:        PreviousHostAdapter = PreviousHostAdapter->Next;
                    222:       if (PreviousHostAdapter != NULL)
                    223:        PreviousHostAdapter->Next = HostAdapter->Next;
                    224:     }
                    225:   HostAdapter->Next = NULL;
                    226: }
                    227: 
                    228: 
                    229: /*
                    230:   BusLogic_InitializeCCBs initializes a group of Command Control Blocks (CCBs)
                    231:   for Host Adapter from the BlockSize bytes located at BlockPointer.  The newly
                    232:   created CCBs are added to Host Adapter's free list.
                    233: */
                    234: 
                    235: static void BusLogic_InitializeCCBs(BusLogic_HostAdapter_T *HostAdapter,
                    236:                                    void *BlockPointer, int BlockSize)
                    237: {
                    238:   BusLogic_CCB_T *CCB = (BusLogic_CCB_T *) BlockPointer;
                    239:   memset(BlockPointer, 0, BlockSize);
                    240:   CCB->AllocationGroupHead = true;
                    241:   while ((BlockSize -= sizeof(BusLogic_CCB_T)) >= 0)
                    242:     {
                    243:       CCB->Status = BusLogic_CCB_Free;
                    244:       CCB->HostAdapter = HostAdapter;
                    245:       if (BusLogic_FlashPointHostAdapterP(HostAdapter))
                    246:        {
                    247:          CCB->CallbackFunction = BusLogic_QueueCompletedCCB;
                    248:          CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress;
                    249:        }
                    250:       CCB->Next = HostAdapter->Free_CCBs;
                    251:       CCB->NextAll = HostAdapter->All_CCBs;
                    252:       HostAdapter->Free_CCBs = CCB;
                    253:       HostAdapter->All_CCBs = CCB;
                    254:       HostAdapter->AllocatedCCBs++;
                    255:       CCB++;
                    256:     }
                    257: }
                    258: 
                    259: 
                    260: /*
                    261:   BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter.
                    262: */
                    263: 
                    264: static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter)
                    265: {
                    266:   int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T);
                    267:   while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs)
                    268:     {
                    269:       void *BlockPointer = kmalloc(BlockSize,
                    270:                                   (HostAdapter->BounceBuffersRequired
                    271:                                    ? GFP_ATOMIC | GFP_DMA
                    272:                                    : GFP_ATOMIC));
                    273:       if (BlockPointer == NULL)
                    274:        {
                    275:          BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n",
                    276:                         HostAdapter);
                    277:          return false;
                    278:        }
                    279:       BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize);
                    280:     }
                    281:   return true;
                    282: }
                    283: 
                    284: 
                    285: /*
                    286:   BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
                    287: */
                    288: 
                    289: static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *HostAdapter)
                    290: {
                    291:   BusLogic_CCB_T *NextCCB = HostAdapter->All_CCBs, *CCB;
                    292:   HostAdapter->All_CCBs = NULL;
                    293:   HostAdapter->Free_CCBs = NULL;
                    294:   while ((CCB = NextCCB) != NULL)
                    295:     {
                    296:       NextCCB = CCB->NextAll;
                    297:       if (CCB->AllocationGroupHead)
                    298:        kfree(CCB);
                    299:     }
                    300: }
                    301: 
                    302: 
                    303: /*
                    304:   BusLogic_CreateAdditionalCCBs allocates Additional CCBs for Host Adapter.  If
                    305:   allocation fails and there are no remaining CCBs available, the Driver Queue
                    306:   Depth is decreased to a known safe value to avoid potential deadlocks when
                    307:   multiple host adapters share the same IRQ Channel.
                    308: */
                    309: 
                    310: static void BusLogic_CreateAdditionalCCBs(BusLogic_HostAdapter_T *HostAdapter,
                    311:                                          int AdditionalCCBs,
                    312:                                          boolean SuccessMessageP)
                    313: {
                    314:   int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T);
                    315:   int PreviouslyAllocated = HostAdapter->AllocatedCCBs;
                    316:   if (AdditionalCCBs <= 0) return;
                    317:   while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs)
                    318:     {
                    319:       void *BlockPointer = kmalloc(BlockSize,
                    320:                                   (HostAdapter->BounceBuffersRequired
                    321:                                    ? GFP_ATOMIC | GFP_DMA
                    322:                                    : GFP_ATOMIC));
                    323:       if (BlockPointer == NULL) break;
                    324:       BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize);
                    325:     }
                    326:   if (HostAdapter->AllocatedCCBs > PreviouslyAllocated)
                    327:     {
                    328:       if (SuccessMessageP)
                    329:        BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n",
                    330:                        HostAdapter,
                    331:                        HostAdapter->AllocatedCCBs - PreviouslyAllocated,
                    332:                        HostAdapter->AllocatedCCBs);
                    333:       return;
                    334:     }
                    335:   BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter);
                    336:   if (HostAdapter->DriverQueueDepth >
                    337:       HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount)
                    338:     {
                    339:       HostAdapter->DriverQueueDepth =
                    340:        HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount;
                    341:       HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
                    342:     }
                    343: }
                    344: 
                    345: 
                    346: /*
                    347:   BusLogic_AllocateCCB allocates a CCB from Host Adapter's free list,
                    348:   allocating more memory from the Kernel if necessary.  The Host Adapter's
                    349:   Lock should already have been acquired by the caller.
                    350: */
                    351: 
                    352: static BusLogic_CCB_T *BusLogic_AllocateCCB(BusLogic_HostAdapter_T
                    353:                                            *HostAdapter)
                    354: {
                    355:   static unsigned long SerialNumber = 0;
                    356:   BusLogic_CCB_T *CCB;
                    357:   CCB = HostAdapter->Free_CCBs;
                    358:   if (CCB != NULL)
                    359:     {
                    360:       CCB->SerialNumber = ++SerialNumber;
                    361:       HostAdapter->Free_CCBs = CCB->Next;
                    362:       CCB->Next = NULL;
                    363:       if (HostAdapter->Free_CCBs == NULL)
                    364:        BusLogic_CreateAdditionalCCBs(HostAdapter,
                    365:                                      HostAdapter->IncrementalCCBs,
                    366:                                      true);
                    367:       return CCB;
                    368:     }
                    369:   BusLogic_CreateAdditionalCCBs(HostAdapter,
                    370:                                HostAdapter->IncrementalCCBs,
                    371:                                true);
                    372:   CCB = HostAdapter->Free_CCBs;
                    373:   if (CCB == NULL) return NULL;
                    374:   CCB->SerialNumber = ++SerialNumber;
                    375:   HostAdapter->Free_CCBs = CCB->Next;
                    376:   CCB->Next = NULL;
                    377:   return CCB;
                    378: }
                    379: 
                    380: 
                    381: /*
                    382:   BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's
                    383:   free list.  The Host Adapter's Lock should already have been acquired by the
                    384:   caller.
                    385: */
                    386: 
                    387: static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB)
                    388: {
                    389:   BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
                    390:   CCB->Command = NULL;
                    391:   CCB->Status = BusLogic_CCB_Free;
                    392:   CCB->Next = HostAdapter->Free_CCBs;
                    393:   HostAdapter->Free_CCBs = CCB;
                    394: }
                    395: 
                    396: 
                    397: /*
                    398:   BusLogic_Command sends the command OperationCode to HostAdapter, optionally
                    399:   providing ParameterLength bytes of ParameterData and receiving at most
                    400:   ReplyLength bytes of ReplyData; any excess reply data is received but
                    401:   discarded.
                    402: 
                    403:   On success, this function returns the number of reply bytes read from
                    404:   the Host Adapter (including any discarded data); on failure, it returns
                    405:   -1 if the command was invalid, or -2 if a timeout occurred.
                    406: 
                    407:   BusLogic_Command is called exclusively during host adapter detection and
                    408:   initialization, so performance and latency are not critical, and exclusive
                    409:   access to the Host Adapter hardware is assumed.  Once the host adapter and
                    410:   driver are initialized, the only Host Adapter command that is issued is the
                    411:   single byte Execute Mailbox Command operation code, which does not require
                    412:   waiting for the Host Adapter Ready bit to be set in the Status Register.
                    413: */
                    414: 
                    415: static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
                    416:                            BusLogic_OperationCode_T OperationCode,
                    417:                            void *ParameterData,
                    418:                            int ParameterLength,
                    419:                            void *ReplyData,
                    420:                            int ReplyLength)
                    421: {
                    422:   unsigned char *ParameterPointer = (unsigned char *) ParameterData;
                    423:   unsigned char *ReplyPointer = (unsigned char *) ReplyData;
                    424:   BusLogic_StatusRegister_T StatusRegister;
                    425:   BusLogic_InterruptRegister_T InterruptRegister;
                    426:   ProcessorFlags_T ProcessorFlags = 0;
                    427:   int ReplyBytes = 0, Result;
                    428:   long TimeoutCounter;
                    429:   /*
                    430:     Clear out the Reply Data if provided.
                    431:   */
                    432:   if (ReplyLength > 0)
                    433:     memset(ReplyData, 0, ReplyLength);
                    434:   /*
                    435:     If the IRQ Channel has not yet been acquired, then interrupts must be
                    436:     disabled while issuing host adapter commands since a Command Complete
                    437:     interrupt could occur if the IRQ Channel was previously enabled by another
                    438:     BusLogic Host Adapter or another driver sharing the same IRQ Channel.
                    439:   */
                    440:   if (!HostAdapter->IRQ_ChannelAcquired)
                    441:     {
                    442:       save_flags(ProcessorFlags);
                    443:       cli();
                    444:     }
                    445:   /*
                    446:     Wait for the Host Adapter Ready bit to be set and the Command/Parameter
                    447:     Register Busy bit to be reset in the Status Register.
                    448:   */
                    449:   TimeoutCounter = 10000;
                    450:   while (--TimeoutCounter >= 0)
                    451:     {
                    452:       StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
                    453:       if (StatusRegister.Bits.HostAdapterReady &&
                    454:          !StatusRegister.Bits.CommandParameterRegisterBusy)
                    455:        break;
                    456:       udelay(100);
                    457:     }
                    458:   if (TimeoutCounter < 0)
                    459:     {
                    460:       BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
                    461:       Result = -2;
                    462:       goto Done;
                    463:     }
                    464:   /*
                    465:     Write the OperationCode to the Command/Parameter Register.
                    466:   */
                    467:   HostAdapter->HostAdapterCommandCompleted = false;
                    468:   BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
                    469:   /*
                    470:     Write any additional Parameter Bytes.
                    471:   */
                    472:   TimeoutCounter = 10000;
                    473:   while (ParameterLength > 0 && --TimeoutCounter >= 0)
                    474:     {
                    475:       /*
                    476:        Wait 100 microseconds to give the Host Adapter enough time to determine
                    477:        whether the last value written to the Command/Parameter Register was
                    478:        valid or not.  If the Command Complete bit is set in the Interrupt
                    479:        Register, then the Command Invalid bit in the Status Register will be
                    480:        reset if the Operation Code or Parameter was valid and the command
                    481:        has completed, or set if the Operation Code or Parameter was invalid.
                    482:        If the Data In Register Ready bit is set in the Status Register, then
                    483:        the Operation Code was valid, and data is waiting to be read back
                    484:        from the Host Adapter.  Otherwise, wait for the Command/Parameter
                    485:        Register Busy bit in the Status Register to be reset.
                    486:       */
                    487:       udelay(100);
                    488:       InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
                    489:       StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
                    490:       if (InterruptRegister.Bits.CommandComplete) break;
                    491:       if (HostAdapter->HostAdapterCommandCompleted) break;
                    492:       if (StatusRegister.Bits.DataInRegisterReady) break;
                    493:       if (StatusRegister.Bits.CommandParameterRegisterBusy) continue;
                    494:       BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
                    495:       ParameterLength--;
                    496:     }
                    497:   if (TimeoutCounter < 0)
                    498:     {
                    499:       BusLogic_CommandFailureReason =
                    500:        "Timeout waiting for Parameter Acceptance";
                    501:       Result = -2;
                    502:       goto Done;
                    503:     }
                    504:   /*
                    505:     The Modify I/O Address command does not cause a Command Complete Interrupt.
                    506:   */
                    507:   if (OperationCode == BusLogic_ModifyIOAddress)
                    508:     {
                    509:       StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
                    510:       if (StatusRegister.Bits.CommandInvalid)
                    511:        {
                    512:          BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
                    513:          Result = -1;
                    514:          goto Done;
                    515:        }
                    516:       if (BusLogic_GlobalOptions.TraceConfiguration)
                    517:        BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: "
                    518:                        "(Modify I/O Address)\n", HostAdapter,
                    519:                        OperationCode, StatusRegister.All);
                    520:       Result = 0;
                    521:       goto Done;
                    522:     }
                    523:   /*
                    524:     Select an appropriate timeout value for awaiting command completion.
                    525:   */
                    526:   switch (OperationCode)
                    527:     {
                    528:     case BusLogic_InquireInstalledDevicesID0to7:
                    529:     case BusLogic_InquireInstalledDevicesID8to15:
                    530:     case BusLogic_InquireTargetDevices:
                    531:       /* Approximately 60 seconds. */
                    532:       TimeoutCounter = 60*10000;
                    533:       break;
                    534:     default:
                    535:       /* Approximately 1 second. */
                    536:       TimeoutCounter = 10000;
                    537:       break;
                    538:     }
                    539:   /*
                    540:     Receive any Reply Bytes, waiting for either the Command Complete bit to
                    541:     be set in the Interrupt Register, or for the Interrupt Handler to set the
                    542:     Host Adapter Command Completed bit in the Host Adapter structure.
                    543:   */
                    544:   while (--TimeoutCounter >= 0)
                    545:     {
                    546:       InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
                    547:       StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
                    548:       if (InterruptRegister.Bits.CommandComplete) break;
                    549:       if (HostAdapter->HostAdapterCommandCompleted) break;
                    550:       if (StatusRegister.Bits.DataInRegisterReady)
                    551:        {
                    552:          if (++ReplyBytes <= ReplyLength)
                    553:            *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
                    554:          else BusLogic_ReadDataInRegister(HostAdapter);
                    555:        }
                    556:       if (OperationCode == BusLogic_FetchHostAdapterLocalRAM &&
                    557:          StatusRegister.Bits.HostAdapterReady) break;
                    558:       udelay(100);
                    559:     }
                    560:   if (TimeoutCounter < 0)
                    561:     {
                    562:       BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
                    563:       Result = -2;
                    564:       goto Done;
                    565:     }
                    566:   /*
                    567:     Clear any pending Command Complete Interrupt.
                    568:   */
                    569:   BusLogic_InterruptReset(HostAdapter);
                    570:   /*
                    571:     Provide tracing information if requested.
                    572:   */
                    573:   if (BusLogic_GlobalOptions.TraceConfiguration)
                    574:     {
                    575:       int i;
                    576:       BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:",
                    577:                      HostAdapter, OperationCode,
                    578:                      StatusRegister.All, ReplyLength, ReplyBytes);
                    579:       if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes;
                    580:       for (i = 0; i < ReplyLength; i++)
                    581:        BusLogic_Notice(" %02X", HostAdapter,
                    582:                        ((unsigned char *) ReplyData)[i]);
                    583:       BusLogic_Notice("\n", HostAdapter);
                    584:     }
                    585:   /*
                    586:     Process Command Invalid conditions.
                    587:   */
                    588:   if (StatusRegister.Bits.CommandInvalid)
                    589:     {
                    590:       /*
                    591:        Some early BusLogic Host Adapters may not recover properly from
                    592:        a Command Invalid condition, so if this appears to be the case,
                    593:        a Soft Reset is issued to the Host Adapter.  Potentially invalid
                    594:        commands are never attempted after Mailbox Initialization is
                    595:        performed, so there should be no Host Adapter state lost by a
                    596:        Soft Reset in response to a Command Invalid condition.
                    597:       */
                    598:       udelay(1000);
                    599:       StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
                    600:       if (StatusRegister.Bits.CommandInvalid ||
                    601:          StatusRegister.Bits.Reserved ||
                    602:          StatusRegister.Bits.DataInRegisterReady ||
                    603:          StatusRegister.Bits.CommandParameterRegisterBusy ||
                    604:          !StatusRegister.Bits.HostAdapterReady ||
                    605:          !StatusRegister.Bits.InitializationRequired ||
                    606:          StatusRegister.Bits.DiagnosticActive ||
                    607:          StatusRegister.Bits.DiagnosticFailure)
                    608:        {
                    609:          BusLogic_SoftReset(HostAdapter);
                    610:          udelay(1000);
                    611:        }
                    612:       BusLogic_CommandFailureReason = "Command Invalid";
                    613:       Result = -1;
                    614:       goto Done;
                    615:     }
                    616:   /*
                    617:     Handle Excess Parameters Supplied conditions.
                    618:   */
                    619:   if (ParameterLength > 0)
                    620:     {
                    621:       BusLogic_CommandFailureReason = "Excess Parameters Supplied";
                    622:       Result = -1;
                    623:       goto Done;
                    624:     }
                    625:   /*
                    626:     Indicate the command completed successfully.
                    627:   */
                    628:   BusLogic_CommandFailureReason = NULL;
                    629:   Result = ReplyBytes;
                    630:   /*
                    631:     Restore the interrupt status if necessary and return.
                    632:   */
                    633: Done:
                    634:   if (!HostAdapter->IRQ_ChannelAcquired)
                    635:     restore_flags(ProcessorFlags);
                    636:   return Result;
                    637: }
                    638: 
                    639: 
                    640: /*
                    641:   BusLogic_AppendProbeAddressISA appends a single ISA I/O Address to the list
                    642:   of I/O Address and Bus Probe Information to be checked for potential BusLogic
                    643:   Host Adapters.
                    644: */
                    645: 
                    646: static void BusLogic_AppendProbeAddressISA(BusLogic_IO_Address_T IO_Address)
                    647: {
                    648:   BusLogic_ProbeInfo_T *ProbeInfo;
                    649:   if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return;
                    650:   ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
                    651:   ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
                    652:   ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
                    653:   ProbeInfo->IO_Address = IO_Address;
                    654: }
                    655: 
                    656: 
                    657: /*
                    658:   BusLogic_InitializeProbeInfoListISA initializes the list of I/O Address and
                    659:   Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters
                    660:   only from the list of standard BusLogic MultiMaster ISA I/O Addresses.
                    661: */
                    662: 
                    663: static void BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T
                    664:                                                *PrototypeHostAdapter)
                    665: {
                    666:   /*
                    667:     If BusLogic Driver Options specifications requested that ISA Bus Probes
                    668:     be inhibited, do not proceed further.
                    669:   */
                    670:   if (BusLogic_ProbeOptions.NoProbeISA) return;
                    671:   /*
                    672:     Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
                    673:   */
                    674:   if (BusLogic_ProbeOptions.LimitedProbeISA
                    675:       ? BusLogic_ProbeOptions.Probe330
                    676:       : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)
                    677:     BusLogic_AppendProbeAddressISA(0x330);
                    678:   if (BusLogic_ProbeOptions.LimitedProbeISA
                    679:       ? BusLogic_ProbeOptions.Probe334
                    680:       : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)
                    681:     BusLogic_AppendProbeAddressISA(0x334);
                    682:   if (BusLogic_ProbeOptions.LimitedProbeISA
                    683:       ? BusLogic_ProbeOptions.Probe230
                    684:       : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)
                    685:     BusLogic_AppendProbeAddressISA(0x230);
                    686:   if (BusLogic_ProbeOptions.LimitedProbeISA
                    687:       ? BusLogic_ProbeOptions.Probe234
                    688:       : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)
                    689:     BusLogic_AppendProbeAddressISA(0x234);
                    690:   if (BusLogic_ProbeOptions.LimitedProbeISA
                    691:       ? BusLogic_ProbeOptions.Probe130
                    692:       : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)
                    693:     BusLogic_AppendProbeAddressISA(0x130);
                    694:   if (BusLogic_ProbeOptions.LimitedProbeISA
                    695:       ? BusLogic_ProbeOptions.Probe134
                    696:       : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)
                    697:     BusLogic_AppendProbeAddressISA(0x134);
                    698: }
                    699: 
                    700: 
                    701: #ifdef CONFIG_PCI
                    702: 
                    703: 
                    704: /*
                    705:   BusLogic_SortProbeInfo sorts a section of BusLogic_ProbeInfoList in order
                    706:   of increasing PCI Bus and Device Number.
                    707: */
                    708: 
                    709: static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *ProbeInfoList,
                    710:                                   int ProbeInfoCount)
                    711: {
                    712:   int LastInterchange = ProbeInfoCount-1, Bound, j;
                    713:   while (LastInterchange > 0)
                    714:     {
                    715:       Bound = LastInterchange;
                    716:       LastInterchange = 0;
                    717:       for (j = 0; j < Bound; j++)
                    718:        {
                    719:          BusLogic_ProbeInfo_T *ProbeInfo1 = &ProbeInfoList[j];
                    720:          BusLogic_ProbeInfo_T *ProbeInfo2 = &ProbeInfoList[j+1];
                    721:          if (ProbeInfo1->Bus > ProbeInfo2->Bus ||
                    722:              (ProbeInfo1->Bus == ProbeInfo2->Bus &&
                    723:               (ProbeInfo1->Device > ProbeInfo2->Device)))
                    724:            {
                    725:              BusLogic_ProbeInfo_T TempProbeInfo;
                    726:              memcpy(&TempProbeInfo, ProbeInfo1, sizeof(BusLogic_ProbeInfo_T));
                    727:              memcpy(ProbeInfo1, ProbeInfo2, sizeof(BusLogic_ProbeInfo_T));
                    728:              memcpy(ProbeInfo2, &TempProbeInfo, sizeof(BusLogic_ProbeInfo_T));
                    729:              LastInterchange = j;
                    730:            }
                    731:        }
                    732:     }
                    733: }
                    734: 
                    735: 
                    736: /*
                    737:   BusLogic_InitializeMultiMasterProbeInfo initializes the list of I/O Address
                    738:   and Bus Probe Information to be checked for potential BusLogic MultiMaster
                    739:   SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
                    740:   machines as well as from the list of standard BusLogic MultiMaster ISA
                    741:   I/O Addresses.  It returns the number of PCI MultiMaster Host Adapters found.
                    742: */
                    743: 
                    744: static int BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T
                    745:                                                   *PrototypeHostAdapter)
                    746: {
                    747:   BusLogic_ProbeInfo_T *PrimaryProbeInfo =
                    748:     &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount];
                    749:   int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1;
                    750:   int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0;
                    751:   boolean ForceBusDeviceScanningOrder = false;
                    752:   boolean ForceBusDeviceScanningOrderChecked = false;
                    753:   boolean StandardAddressSeen[6];
                    754:   unsigned char Bus, DeviceFunction;
                    755:   unsigned int BaseAddress0, BaseAddress1;
                    756:   unsigned char IRQ_Channel;
                    757:   BusLogic_IO_Address_T IO_Address;
                    758:   BusLogic_PCI_Address_T PCI_Address;
                    759:   unsigned short Index = 0;
                    760:   int i;
                    761:   if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return 0;
                    762:   BusLogic_ProbeInfoCount++;
                    763:   for (i = 0; i < 6; i++)
                    764:     StandardAddressSeen[i] = false;
                    765:   /*
                    766:     Iterate over the MultiMaster PCI Host Adapters.  For each enumerated host
                    767:     adapter, determine whether its ISA Compatible I/O Port is enabled and if
                    768:     so, whether it is assigned the Primary I/O Address.  A host adapter that is
                    769:     assigned the Primary I/O Address will always be the preferred boot device.
                    770:     The MultiMaster BIOS will first recognize a host adapter at the Primary I/O
                    771:     Address, then any other PCI host adapters, and finally any host adapters
                    772:     located at the remaining standard ISA I/O Addresses.  When a PCI host
                    773:     adapter is found with its ISA Compatible I/O Port enabled, a command is
                    774:     issued to disable the ISA Compatible I/O Port, and it is noted that the
                    775:     particular standard ISA I/O Address need not be probed.
                    776:   */
                    777:   PrimaryProbeInfo->IO_Address = 0;
                    778:   while (pcibios_find_device(PCI_VENDOR_ID_BUSLOGIC,
                    779:                             PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
                    780:                             Index++, &Bus, &DeviceFunction) == 0)
                    781:     if (pcibios_read_config_dword(Bus, DeviceFunction,
                    782:                                  PCI_BASE_ADDRESS_0, &BaseAddress0) == 0 &&
                    783:        pcibios_read_config_dword(Bus, DeviceFunction,
                    784:                                  PCI_BASE_ADDRESS_1, &BaseAddress1) == 0 &&
                    785:        pcibios_read_config_byte(Bus, DeviceFunction,
                    786:                                 PCI_INTERRUPT_LINE, &IRQ_Channel) == 0)
                    787:       {
                    788:        BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
                    789:        BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
                    790:        BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
                    791:        unsigned char Device = DeviceFunction >> 3;
                    792:        IO_Address = BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
                    793:        PCI_Address = BaseAddress1 & PCI_BASE_ADDRESS_MEM_MASK;
                    794:        if ((BaseAddress0 & PCI_BASE_ADDRESS_SPACE)
                    795:            != PCI_BASE_ADDRESS_SPACE_IO)
                    796:          {
                    797:            BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
                    798:                           "MultiMaster Host Adapter\n", NULL, BaseAddress0);
                    799:            BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
                    800:                           NULL, Bus, Device, IO_Address);
                    801:            continue;
                    802:          }
                    803:        if ((BaseAddress1 & PCI_BASE_ADDRESS_SPACE)
                    804:            != PCI_BASE_ADDRESS_SPACE_MEMORY)
                    805:          {
                    806:            BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
                    807:                           "MultiMaster Host Adapter\n", NULL, BaseAddress1);
                    808:            BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n",
                    809:                           NULL, Bus, Device, PCI_Address);
                    810:            continue;
                    811:          }
                    812:        if (IRQ_Channel == 0 || IRQ_Channel >= NR_IRQS)
                    813:          {
                    814:            BusLogic_Error("BusLogic: IRQ Channel %d illegal for "
                    815:                           "MultiMaster Host Adapter\n", NULL, IRQ_Channel);
                    816:            BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
                    817:                           NULL, Bus, Device, IO_Address);
                    818:            continue;
                    819:          }
                    820:        if (BusLogic_GlobalOptions.TraceProbe)
                    821:          {
                    822:            BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter "
                    823:                            "detected at\n", NULL);
                    824:            BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
                    825:                            "0x%X PCI Address 0x%X\n", NULL,
                    826:                            Bus, Device, IO_Address, PCI_Address);
                    827:          }
                    828:        /*
                    829:          Issue the Inquire PCI Host Adapter Information command to determine
                    830:          the ISA Compatible I/O Port.  If the ISA Compatible I/O Port is
                    831:          known and enabled, note that the particular Standard ISA I/O
                    832:          Address should not be probed.
                    833:        */
                    834:        HostAdapter->IO_Address = IO_Address;
                    835:        BusLogic_InterruptReset(HostAdapter);
                    836:        if (BusLogic_Command(HostAdapter,
                    837:                             BusLogic_InquirePCIHostAdapterInformation,
                    838:                             NULL, 0, &PCIHostAdapterInformation,
                    839:                             sizeof(PCIHostAdapterInformation))
                    840:            == sizeof(PCIHostAdapterInformation))
                    841:          {
                    842:            if (PCIHostAdapterInformation.ISACompatibleIOPort < 6)
                    843:              StandardAddressSeen[PCIHostAdapterInformation
                    844:                                  .ISACompatibleIOPort] = true;
                    845:          }
                    846:        else PCIHostAdapterInformation.ISACompatibleIOPort =
                    847:               BusLogic_IO_Disable;
                    848:        /*
                    849:          Issue the Modify I/O Address command to disable the ISA Compatible
                    850:          I/O Port.
                    851:        */
                    852:        ModifyIOAddressRequest = BusLogic_IO_Disable;
                    853:        BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress,
                    854:                         &ModifyIOAddressRequest,
                    855:                         sizeof(ModifyIOAddressRequest), NULL, 0);
                    856:        /*
                    857:          For the first MultiMaster Host Adapter enumerated, issue the Fetch
                    858:          Host Adapter Local RAM command to read byte 45 of the AutoSCSI area,
                    859:          for the setting of the "Use Bus And Device # For PCI Scanning Seq."
                    860:          option.  Issue the Inquire Board ID command since this option is
                    861:          only valid for the BT-948/958/958D.
                    862:        */
                    863:        if (!ForceBusDeviceScanningOrderChecked)
                    864:          {
                    865:            BusLogic_FetchHostAdapterLocalRAMRequest_T
                    866:              FetchHostAdapterLocalRAMRequest;
                    867:            BusLogic_AutoSCSIByte45_T AutoSCSIByte45;
                    868:            BusLogic_BoardID_T BoardID;
                    869:            FetchHostAdapterLocalRAMRequest.ByteOffset =
                    870:              BusLogic_AutoSCSI_BaseOffset + 45;
                    871:            FetchHostAdapterLocalRAMRequest.ByteCount =
                    872:              sizeof(AutoSCSIByte45);
                    873:            BusLogic_Command(HostAdapter,
                    874:                             BusLogic_FetchHostAdapterLocalRAM,
                    875:                             &FetchHostAdapterLocalRAMRequest,
                    876:                             sizeof(FetchHostAdapterLocalRAMRequest),
                    877:                             &AutoSCSIByte45, sizeof(AutoSCSIByte45));
                    878:            BusLogic_Command(HostAdapter, BusLogic_InquireBoardID,
                    879:                             NULL, 0, &BoardID, sizeof(BoardID));
                    880:            if (BoardID.FirmwareVersion1stDigit == '5')
                    881:              ForceBusDeviceScanningOrder =
                    882:                AutoSCSIByte45.ForceBusDeviceScanningOrder;
                    883:            ForceBusDeviceScanningOrderChecked = true;
                    884:          }
                    885:        /*
                    886:          Determine whether this MultiMaster Host Adapter has its ISA
                    887:          Compatible I/O Port enabled and is assigned the Primary I/O Address.
                    888:          If it does, then it is the Primary MultiMaster Host Adapter and must
                    889:          be recognized first.  If it does not, then it is added to the list
                    890:          for probing after any Primary MultiMaster Host Adapter is probed.
                    891:        */
                    892:        if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330)
                    893:          {
                    894:            PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
                    895:            PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
                    896:            PrimaryProbeInfo->IO_Address = IO_Address;
                    897:            PrimaryProbeInfo->PCI_Address = PCI_Address;
                    898:            PrimaryProbeInfo->Bus = Bus;
                    899:            PrimaryProbeInfo->Device = Device;
                    900:            PrimaryProbeInfo->IRQ_Channel = IRQ_Channel;
                    901:            PCIMultiMasterCount++;
                    902:          }
                    903:        else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
                    904:          {
                    905:            BusLogic_ProbeInfo_T *ProbeInfo =
                    906:              &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
                    907:            ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
                    908:            ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
                    909:            ProbeInfo->IO_Address = IO_Address;
                    910:            ProbeInfo->PCI_Address = PCI_Address;
                    911:            ProbeInfo->Bus = Bus;
                    912:            ProbeInfo->Device = Device;
                    913:            ProbeInfo->IRQ_Channel = IRQ_Channel;
                    914:            NonPrimaryPCIMultiMasterCount++;
                    915:            PCIMultiMasterCount++;
                    916:          }
                    917:        else BusLogic_Warning("BusLogic: Too many Host Adapters "
                    918:                              "detected\n", NULL);
                    919:       }
                    920:   /*
                    921:     If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option is ON
                    922:     for the first enumerated MultiMaster Host Adapter, and if that host adapter
                    923:     is a BT-948/958/958D, then the MultiMaster BIOS will recognize MultiMaster
                    924:     Host Adapters in the order of increasing PCI Bus and Device Number.  In
                    925:     that case, sort the probe information into the same order the BIOS uses.
                    926:     If this option is OFF, then the MultiMaster BIOS will recognize MultiMaster
                    927:     Host Adapters in the order they are enumerated by the PCI BIOS, and hence
                    928:     no sorting is necessary.
                    929:   */
                    930:   if (ForceBusDeviceScanningOrder)
                    931:     BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[
                    932:                              NonPrimaryPCIMultiMasterIndex],
                    933:                           NonPrimaryPCIMultiMasterCount);
                    934:   /*
                    935:     If no PCI MultiMaster Host Adapter is assigned the Primary I/O Address,
                    936:     then the Primary I/O Address must be probed explicitly before any PCI
                    937:     host adapters are probed.
                    938:   */
                    939:   if (!BusLogic_ProbeOptions.NoProbeISA)
                    940:     if (PrimaryProbeInfo->IO_Address == 0 &&
                    941:        (BusLogic_ProbeOptions.LimitedProbeISA
                    942:         ? BusLogic_ProbeOptions.Probe330
                    943:         : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0))
                    944:       {
                    945:        PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
                    946:        PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
                    947:        PrimaryProbeInfo->IO_Address = 0x330;
                    948:       }
                    949:   /*
                    950:     Append the list of standard BusLogic MultiMaster ISA I/O Addresses,
                    951:     omitting the Primary I/O Address which has already been handled.
                    952:   */
                    953:   if (!BusLogic_ProbeOptions.NoProbeISA)
                    954:     {
                    955:       if (!StandardAddressSeen[1] &&
                    956:          (BusLogic_ProbeOptions.LimitedProbeISA
                    957:           ? BusLogic_ProbeOptions.Probe334
                    958:           : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0))
                    959:        BusLogic_AppendProbeAddressISA(0x334);
                    960:       if (!StandardAddressSeen[2] &&
                    961:          (BusLogic_ProbeOptions.LimitedProbeISA
                    962:           ? BusLogic_ProbeOptions.Probe230
                    963:           : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0))
                    964:        BusLogic_AppendProbeAddressISA(0x230);
                    965:       if (!StandardAddressSeen[3] &&
                    966:          (BusLogic_ProbeOptions.LimitedProbeISA
                    967:           ? BusLogic_ProbeOptions.Probe234
                    968:           : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0))
                    969:        BusLogic_AppendProbeAddressISA(0x234);
                    970:       if (!StandardAddressSeen[4] &&
                    971:          (BusLogic_ProbeOptions.LimitedProbeISA
                    972:           ? BusLogic_ProbeOptions.Probe130
                    973:           : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0))
                    974:        BusLogic_AppendProbeAddressISA(0x130);
                    975:       if (!StandardAddressSeen[5] &&
                    976:          (BusLogic_ProbeOptions.LimitedProbeISA
                    977:           ? BusLogic_ProbeOptions.Probe134
                    978:           : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0))
                    979:        BusLogic_AppendProbeAddressISA(0x134);
                    980:     }
                    981:   /*
                    982:     Iterate over the older non-compliant MultiMaster PCI Host Adapters,
                    983:     noting the PCI bus location and assigned IRQ Channel.
                    984:   */
                    985:   Index = 0;
                    986:   while (pcibios_find_device(PCI_VENDOR_ID_BUSLOGIC,
                    987:                             PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
                    988:                             Index++, &Bus, &DeviceFunction) == 0)
                    989:     if (pcibios_read_config_dword(Bus, DeviceFunction,
                    990:                                  PCI_BASE_ADDRESS_0, &BaseAddress0) == 0 &&
                    991:        pcibios_read_config_byte(Bus, DeviceFunction,
                    992:                                 PCI_INTERRUPT_LINE, &IRQ_Channel) == 0)
                    993:       {
                    994:        unsigned char Device = DeviceFunction >> 3;
                    995:        IO_Address = BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
                    996:        if (IO_Address == 0 || IRQ_Channel == 0 || IRQ_Channel >= NR_IRQS)
                    997:          continue;
                    998:        for (i = 0; i < BusLogic_ProbeInfoCount; i++)
                    999:          {
                   1000:            BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[i];
                   1001:            if (ProbeInfo->IO_Address == IO_Address &&
                   1002:                ProbeInfo->HostAdapterType == BusLogic_MultiMaster)
                   1003:              {
                   1004:                ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
                   1005:                ProbeInfo->PCI_Address = 0;
                   1006:                ProbeInfo->Bus = Bus;
                   1007:                ProbeInfo->Device = Device;
                   1008:                ProbeInfo->IRQ_Channel = IRQ_Channel;
                   1009:                break;
                   1010:              }
                   1011:          }
                   1012:       }
                   1013:   return PCIMultiMasterCount;
                   1014: }
                   1015: 
                   1016: 
                   1017: /*
                   1018:   BusLogic_InitializeFlashPointProbeInfo initializes the list of I/O Address
                   1019:   and Bus Probe Information to be checked for potential BusLogic FlashPoint
                   1020:   Host Adapters by interrogating the PCI Configuration Space.  It returns the
                   1021:   number of FlashPoint Host Adapters found.
                   1022: */
                   1023: 
                   1024: static int BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T
                   1025:                                                  *PrototypeHostAdapter)
                   1026: {
                   1027:   int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0;
                   1028:   unsigned char Bus, DeviceFunction;
                   1029:   unsigned int BaseAddress0, BaseAddress1;
                   1030:   unsigned char IRQ_Channel;
                   1031:   BusLogic_IO_Address_T IO_Address;
                   1032:   BusLogic_PCI_Address_T PCI_Address;
                   1033:   unsigned short Index = 0;
                   1034:   /*
                   1035:     Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
                   1036:   */
                   1037:   while (pcibios_find_device(PCI_VENDOR_ID_BUSLOGIC,
                   1038:                             PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
                   1039:                             Index++, &Bus, &DeviceFunction) == 0)
                   1040:     if (pcibios_read_config_dword(Bus, DeviceFunction,
                   1041:                                  PCI_BASE_ADDRESS_0, &BaseAddress0) == 0 &&
                   1042:        pcibios_read_config_dword(Bus, DeviceFunction,
                   1043:                                  PCI_BASE_ADDRESS_1, &BaseAddress1) == 0 &&
                   1044:        pcibios_read_config_byte(Bus, DeviceFunction,
                   1045:                                 PCI_INTERRUPT_LINE, &IRQ_Channel) == 0)
                   1046:       {
                   1047:        unsigned char Device = DeviceFunction >> 3;
                   1048:        IO_Address = BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
                   1049:        PCI_Address = BaseAddress1 & PCI_BASE_ADDRESS_MEM_MASK;
                   1050: #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
                   1051:        if ((BaseAddress0 & PCI_BASE_ADDRESS_SPACE)
                   1052:            != PCI_BASE_ADDRESS_SPACE_IO)
                   1053:          {
                   1054:            BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
                   1055:                           "FlashPoint Host Adapter\n", NULL, BaseAddress0);
                   1056:            BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
                   1057:                           NULL, Bus, Device, IO_Address);
                   1058:            continue;
                   1059:          }
                   1060:        if ((BaseAddress1 & PCI_BASE_ADDRESS_SPACE)
                   1061:            != PCI_BASE_ADDRESS_SPACE_MEMORY)
                   1062:          {
                   1063:            BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
                   1064:                           "FlashPoint Host Adapter\n", NULL, BaseAddress1);
                   1065:            BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n",
                   1066:                           NULL, Bus, Device, PCI_Address);
                   1067:            continue;
                   1068:          }
                   1069:        if (IRQ_Channel == 0 || IRQ_Channel >= NR_IRQS)
                   1070:          {
                   1071:            BusLogic_Error("BusLogic: IRQ Channel %d illegal for "
                   1072:                           "FlashPoint Host Adapter\n", NULL, IRQ_Channel);
                   1073:            BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
                   1074:                           NULL, Bus, Device, IO_Address);
                   1075:            continue;
                   1076:          }
                   1077:        if (BusLogic_GlobalOptions.TraceProbe)
                   1078:          {
                   1079:            BusLogic_Notice("BusLogic: FlashPoint Host Adapter "
                   1080:                            "detected at\n", NULL);
                   1081:            BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
                   1082:                            "0x%X PCI Address 0x%X\n", NULL,
                   1083:                            Bus, Device, IO_Address, PCI_Address);
                   1084:          }
                   1085:        if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
                   1086:          {
                   1087:            BusLogic_ProbeInfo_T *ProbeInfo =
                   1088:              &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
                   1089:            ProbeInfo->HostAdapterType = BusLogic_FlashPoint;
                   1090:            ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
                   1091:            ProbeInfo->IO_Address = IO_Address;
                   1092:            ProbeInfo->PCI_Address = PCI_Address;
                   1093:            ProbeInfo->Bus = Bus;
                   1094:            ProbeInfo->Device = Device;
                   1095:            ProbeInfo->IRQ_Channel = IRQ_Channel;
                   1096:            FlashPointCount++;
                   1097:          }
                   1098:        else BusLogic_Warning("BusLogic: Too many Host Adapters "
                   1099:                              "detected\n", NULL);
                   1100: #else
                   1101:        BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
                   1102:                       "PCI Bus %d Device %d\n", NULL, Bus, Device);
                   1103:        BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, "
                   1104:                       "but FlashPoint\n", NULL, IO_Address, PCI_Address);
                   1105:        BusLogic_Error("BusLogic: support was omitted in this kernel "
                   1106:                       "configuration.\n", NULL);
                   1107: #endif
                   1108:       }
                   1109:   /*
                   1110:     The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
                   1111:     increasing PCI Bus and Device Number, so sort the probe information into
                   1112:     the same order the BIOS uses.
                   1113:   */
                   1114:   BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex],
                   1115:                         FlashPointCount);
                   1116:   return FlashPointCount;
                   1117: }
                   1118: 
                   1119: 
                   1120: /*
                   1121:   BusLogic_InitializeProbeInfoList initializes the list of I/O Address and Bus
                   1122:   Probe Information to be checked for potential BusLogic SCSI Host Adapters by
                   1123:   interrogating the PCI Configuration Space on PCI machines as well as from the
                   1124:   list of standard BusLogic MultiMaster ISA I/O Addresses.  By default, if both
                   1125:   FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
                   1126:   probe for FlashPoint Host Adapters first unless the BIOS primary disk is
                   1127:   controlled by the first PCI MultiMaster Host Adapter, in which case
                   1128:   MultiMaster Host Adapters will be probed first.  The BusLogic Driver Options
                   1129:   specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
                   1130:   a particular probe order.
                   1131: */
                   1132: 
                   1133: static void BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T
                   1134:                                             *PrototypeHostAdapter)
                   1135: {
                   1136:   /*
                   1137:     If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
                   1138:     Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
                   1139:   */
                   1140:   if (!BusLogic_ProbeOptions.NoProbePCI && pcibios_present())
                   1141:     {
                   1142:       if (BusLogic_ProbeOptions.MultiMasterFirst)
                   1143:        {
                   1144:          BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
                   1145:          BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
                   1146:        }
                   1147:       else if (BusLogic_ProbeOptions.FlashPointFirst)
                   1148:        {
                   1149:          BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
                   1150:          BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
                   1151:        }
                   1152:       else
                   1153:        {
                   1154:          int FlashPointCount =
                   1155:            BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
                   1156:          int PCIMultiMasterCount =
                   1157:            BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
                   1158:          if (FlashPointCount > 0 && PCIMultiMasterCount > 0)
                   1159:            {
                   1160:              BusLogic_ProbeInfo_T *ProbeInfo =
                   1161:                &BusLogic_ProbeInfoList[FlashPointCount];
                   1162:              BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
                   1163:              BusLogic_FetchHostAdapterLocalRAMRequest_T
                   1164:                FetchHostAdapterLocalRAMRequest;
                   1165:              BusLogic_BIOSDriveMapByte_T Drive0MapByte;
                   1166:              while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus)
                   1167:                ProbeInfo++;
                   1168:              HostAdapter->IO_Address = ProbeInfo->IO_Address;
                   1169:              FetchHostAdapterLocalRAMRequest.ByteOffset =
                   1170:                BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0;
                   1171:              FetchHostAdapterLocalRAMRequest.ByteCount =
                   1172:                sizeof(Drive0MapByte);
                   1173:              BusLogic_Command(HostAdapter,
                   1174:                               BusLogic_FetchHostAdapterLocalRAM,
                   1175:                               &FetchHostAdapterLocalRAMRequest,
                   1176:                               sizeof(FetchHostAdapterLocalRAMRequest),
                   1177:                               &Drive0MapByte, sizeof(Drive0MapByte));
                   1178:              /*
                   1179:                If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0
                   1180:                is controlled by this PCI MultiMaster Host Adapter, then
                   1181:                reverse the probe order so that MultiMaster Host Adapters are
                   1182:                probed before FlashPoint Host Adapters.
                   1183:              */
                   1184:              if (Drive0MapByte.DiskGeometry !=
                   1185:                  BusLogic_BIOS_Disk_Not_Installed)
                   1186:                {
                   1187:                  BusLogic_ProbeInfo_T
                   1188:                    SavedProbeInfo[BusLogic_MaxHostAdapters];
                   1189:                  int MultiMasterCount =
                   1190:                    BusLogic_ProbeInfoCount - FlashPointCount;
                   1191:                  memcpy(SavedProbeInfo,
                   1192:                         BusLogic_ProbeInfoList,
                   1193:                         BusLogic_ProbeInfoCount
                   1194:                         * sizeof(BusLogic_ProbeInfo_T));
                   1195:                  memcpy(&BusLogic_ProbeInfoList[0],
                   1196:                         &SavedProbeInfo[FlashPointCount],
                   1197:                         MultiMasterCount * sizeof(BusLogic_ProbeInfo_T));
                   1198:                  memcpy(&BusLogic_ProbeInfoList[MultiMasterCount],
                   1199:                         &SavedProbeInfo[0],
                   1200:                         FlashPointCount * sizeof(BusLogic_ProbeInfo_T));
                   1201:                }
                   1202:            }
                   1203:        }
                   1204:     }
                   1205:   else BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);
                   1206: }
                   1207: 
                   1208: 
                   1209: #endif  /* CONFIG_PCI */
                   1210: 
                   1211: 
                   1212: /*
                   1213:   BusLogic_Failure prints a standardized error message, and then returns false.
                   1214: */
                   1215: 
                   1216: static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter,
                   1217:                                char *ErrorMessage)
                   1218: {
                   1219:   BusLogic_AnnounceDriver(HostAdapter);
                   1220:   if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus)
                   1221:     {
                   1222:       BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n",
                   1223:                     HostAdapter);
                   1224:       BusLogic_Error("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n",
                   1225:                     HostAdapter, HostAdapter->Bus, HostAdapter->Device,
                   1226:                     HostAdapter->IO_Address, HostAdapter->PCI_Address);
                   1227:     }
                   1228:   else BusLogic_Error("While configuring BusLogic Host Adapter at "
                   1229:                      "I/O Address 0x%X:\n", HostAdapter,
                   1230:                      HostAdapter->IO_Address);
                   1231:   BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage);
                   1232:   if (BusLogic_CommandFailureReason != NULL)
                   1233:     BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter,
                   1234:                   BusLogic_CommandFailureReason);
                   1235:   return false;
                   1236: }
                   1237: 
                   1238: 
                   1239: /*
                   1240:   BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
                   1241: */
                   1242: 
                   1243: static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
                   1244: {
                   1245:   BusLogic_StatusRegister_T StatusRegister;
                   1246:   BusLogic_InterruptRegister_T InterruptRegister;
                   1247:   BusLogic_GeometryRegister_T GeometryRegister;
                   1248:   /*
                   1249:     FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
                   1250:   */
                   1251:   if (BusLogic_FlashPointHostAdapterP(HostAdapter))
                   1252:     {
                   1253:       FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
                   1254:       FlashPointInfo->BaseAddress =
                   1255:        (BusLogic_Base_Address_T) HostAdapter->IO_Address;
                   1256:       FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
                   1257:       FlashPointInfo->Present = false;
                   1258:       if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 &&
                   1259:            FlashPointInfo->Present))
                   1260:        {
                   1261:          BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
                   1262:                         "PCI Bus %d Device %d\n", HostAdapter,
                   1263:                         HostAdapter->Bus, HostAdapter->Device);
                   1264:          BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, "
                   1265:                         "but FlashPoint\n", HostAdapter,
                   1266:                         HostAdapter->IO_Address, HostAdapter->PCI_Address);
                   1267:          BusLogic_Error("BusLogic: Probe Function failed to validate it.\n",
                   1268:                         HostAdapter);
                   1269:          return false;
                   1270:        }
                   1271:       if (BusLogic_GlobalOptions.TraceProbe)
                   1272:        BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n",
                   1273:                        HostAdapter, HostAdapter->IO_Address);
                   1274:       /*
                   1275:        Indicate the Host Adapter Probe completed successfully.
                   1276:       */
                   1277:       return true;
                   1278:     }
                   1279:   /*
                   1280:     Read the Status, Interrupt, and Geometry Registers to test if there are I/O
                   1281:     ports that respond, and to check the values to determine if they are from a
                   1282:     BusLogic Host Adapter.  A nonexistent I/O port will return 0xFF, in which
                   1283:     case there is definitely no BusLogic Host Adapter at this base I/O Address.
                   1284:     The test here is a subset of that used by the BusLogic Host Adapter BIOS.
                   1285:   */
                   1286:   StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
                   1287:   InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
                   1288:   GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
                   1289:   if (BusLogic_GlobalOptions.TraceProbe)
                   1290:     BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, "
                   1291:                    "Geometry 0x%02X\n", HostAdapter,
                   1292:                    HostAdapter->IO_Address, StatusRegister.All,
                   1293:                    InterruptRegister.All, GeometryRegister.All);
                   1294:   if (StatusRegister.All == 0 ||
                   1295:       StatusRegister.Bits.DiagnosticActive ||
                   1296:       StatusRegister.Bits.CommandParameterRegisterBusy ||
                   1297:       StatusRegister.Bits.Reserved ||
                   1298:       StatusRegister.Bits.CommandInvalid ||
                   1299:       InterruptRegister.Bits.Reserved != 0)
                   1300:     return false;
                   1301:   /*
                   1302:     Check the undocumented Geometry Register to test if there is an I/O port
                   1303:     that responded.  Adaptec Host Adapters do not implement the Geometry
                   1304:     Register, so this test helps serve to avoid incorrectly recognizing an
                   1305:     Adaptec 1542A or 1542B as a BusLogic.  Unfortunately, the Adaptec 1542C
                   1306:     series does respond to the Geometry Register I/O port, but it will be
                   1307:     rejected later when the Inquire Extended Setup Information command is
                   1308:     issued in BusLogic_CheckHostAdapter.  The AMI FastDisk Host Adapter is a
                   1309:     BusLogic clone that implements the same interface as earlier BusLogic
                   1310:     Host Adapters, including the undocumented commands, and is therefore
                   1311:     supported by this driver.  However, the AMI FastDisk always returns 0x00
                   1312:     upon reading the Geometry Register, so the extended translation option
                   1313:     should always be left disabled on the AMI FastDisk.
                   1314:   */
                   1315:   if (GeometryRegister.All == 0xFF) return false;
                   1316:   /*
                   1317:     Indicate the Host Adapter Probe completed successfully.
                   1318:   */
                   1319:   return true;
                   1320: }
                   1321: 
                   1322: 
                   1323: /*
                   1324:   BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter
                   1325:   and waits for Host Adapter Diagnostics to complete.  If HardReset is true, a
                   1326:   Hard Reset is performed which also initiates a SCSI Bus Reset.  Otherwise, a
                   1327:   Soft Reset is performed which only resets the Host Adapter without forcing a
                   1328:   SCSI Bus Reset.
                   1329: */
                   1330: 
                   1331: static boolean BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T
                   1332:                                                   *HostAdapter,
                   1333:                                                 boolean HardReset)
                   1334: {
                   1335:   BusLogic_StatusRegister_T StatusRegister;
                   1336:   int TimeoutCounter;
                   1337:   /*
                   1338:     FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager.
                   1339:   */
                   1340:   if (BusLogic_FlashPointHostAdapterP(HostAdapter))
                   1341:     {
                   1342:       FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
                   1343:       FlashPointInfo->HostSoftReset = !HardReset;
                   1344:       FlashPointInfo->ReportDataUnderrun = true;
                   1345:       HostAdapter->CardHandle =
                   1346:        FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
                   1347:       if (HostAdapter->CardHandle == FlashPoint_BadCardHandle) return false;
                   1348:       /*
                   1349:        Indicate the Host Adapter Hard Reset completed successfully.
                   1350:       */
                   1351:       return true;
                   1352:     }
                   1353:   /*
                   1354:     Issue a Hard Reset or Soft Reset Command to the Host Adapter.  The Host
                   1355:     Adapter should respond by setting Diagnostic Active in the Status Register.
                   1356:   */
                   1357:   if (HardReset)
                   1358:     BusLogic_HardReset(HostAdapter);
                   1359:   else BusLogic_SoftReset(HostAdapter);
                   1360:   /*
                   1361:     Wait until Diagnostic Active is set in the Status Register.
                   1362:   */
                   1363:   TimeoutCounter = 5*10000;
                   1364:   while (--TimeoutCounter >= 0)
                   1365:     {
                   1366:       StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
                   1367:       if (StatusRegister.Bits.DiagnosticActive) break;
                   1368:       udelay(100);
                   1369:     }
                   1370:   if (BusLogic_GlobalOptions.TraceHardwareReset)
                   1371:     BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, "
                   1372:                    "Status 0x%02X\n", HostAdapter,
                   1373:                    HostAdapter->IO_Address, StatusRegister.All);
                   1374:   if (TimeoutCounter < 0) return false;
                   1375:   /*
                   1376:     Wait 100 microseconds to allow completion of any initial diagnostic
                   1377:     activity which might leave the contents of the Status Register
                   1378:     unpredictable.
                   1379:   */
                   1380:   udelay(100);
                   1381:   /*
                   1382:     Wait until Diagnostic Active is reset in the Status Register.
                   1383:   */
                   1384:   TimeoutCounter = 10*10000;
                   1385:   while (--TimeoutCounter >= 0)
                   1386:     {
                   1387:       StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
                   1388:       if (!StatusRegister.Bits.DiagnosticActive) break;
                   1389:       udelay(100);
                   1390:     }
                   1391:   if (BusLogic_GlobalOptions.TraceHardwareReset)
                   1392:     BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, "
                   1393:                    "Status 0x%02X\n", HostAdapter,
                   1394:                    HostAdapter->IO_Address, StatusRegister.All);
                   1395:   if (TimeoutCounter < 0) return false;
                   1396:   /*
                   1397:     Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
                   1398:     or Data In Register Ready bits is set in the Status Register.
                   1399:   */
                   1400:   TimeoutCounter = 10000;
                   1401:   while (--TimeoutCounter >= 0)
                   1402:     {
                   1403:       StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
                   1404:       if (StatusRegister.Bits.DiagnosticFailure ||
                   1405:          StatusRegister.Bits.HostAdapterReady ||
                   1406:          StatusRegister.Bits.DataInRegisterReady)
                   1407:        break;
                   1408:       udelay(100);
                   1409:     }
                   1410:   if (BusLogic_GlobalOptions.TraceHardwareReset)
                   1411:     BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, "
                   1412:                    "Status 0x%02X\n", HostAdapter,
                   1413:                    HostAdapter->IO_Address, StatusRegister.All);
                   1414:   if (TimeoutCounter < 0) return false;
                   1415:   /*
                   1416:     If Diagnostic Failure is set or Host Adapter Ready is reset, then an
                   1417:     error occurred during the Host Adapter diagnostics.  If Data In Register
                   1418:     Ready is set, then there is an Error Code available.
                   1419:   */
                   1420:   if (StatusRegister.Bits.DiagnosticFailure ||
                   1421:       !StatusRegister.Bits.HostAdapterReady)
                   1422:     {
                   1423:       BusLogic_CommandFailureReason = NULL;
                   1424:       BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
                   1425:       BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n",
                   1426:                     HostAdapter, StatusRegister.All);
                   1427:       if (StatusRegister.Bits.DataInRegisterReady)
                   1428:        {
                   1429:          unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
                   1430:          BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n",
                   1431:                         HostAdapter, ErrorCode);
                   1432:        }
                   1433:       return false;
                   1434:     }
                   1435:   /*
                   1436:     Indicate the Host Adapter Hard Reset completed successfully.
                   1437:   */
                   1438:   return true;
                   1439: }
                   1440: 
                   1441: 
                   1442: /*
                   1443:   BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
                   1444:   Host Adapter.
                   1445: */
                   1446: 
                   1447: static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
                   1448: {
                   1449:   BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
                   1450:   BusLogic_RequestedReplyLength_T RequestedReplyLength;
                   1451:   boolean Result = true;
                   1452:   /*
                   1453:     FlashPoint Host Adapters do not require this protection.
                   1454:   */
                   1455:   if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
                   1456:   /*
                   1457:     Issue the Inquire Extended Setup Information command.  Only genuine
                   1458:     BusLogic Host Adapters and true clones support this command.  Adaptec 1542C
                   1459:     series Host Adapters that respond to the Geometry Register I/O port will
                   1460:     fail this command.
                   1461:   */
                   1462:   RequestedReplyLength = sizeof(ExtendedSetupInformation);
                   1463:   if (BusLogic_Command(HostAdapter,
                   1464:                       BusLogic_InquireExtendedSetupInformation,
                   1465:                       &RequestedReplyLength,
                   1466:                       sizeof(RequestedReplyLength),
                   1467:                       &ExtendedSetupInformation,
                   1468:                       sizeof(ExtendedSetupInformation))
                   1469:       != sizeof(ExtendedSetupInformation))
                   1470:     Result = false;
                   1471:   /*
                   1472:     Provide tracing information if requested and return.
                   1473:   */
                   1474:   if (BusLogic_GlobalOptions.TraceProbe)
                   1475:     BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter,
                   1476:                    HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
                   1477:   return Result;
                   1478: }
                   1479: 
                   1480: 
                   1481: /*
                   1482:   BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
                   1483:   from Host Adapter and initializes the Host Adapter structure.
                   1484: */
                   1485: 
                   1486: static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T
                   1487:                                                     *HostAdapter)
                   1488: {
                   1489:   BusLogic_BoardID_T BoardID;
                   1490:   BusLogic_Configuration_T Configuration;
                   1491:   BusLogic_SetupInformation_T SetupInformation;
                   1492:   BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
                   1493:   BusLogic_HostAdapterModelNumber_T HostAdapterModelNumber;
                   1494:   BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
                   1495:   BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
                   1496:   BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
                   1497:   BusLogic_FetchHostAdapterLocalRAMRequest_T FetchHostAdapterLocalRAMRequest;
                   1498:   BusLogic_AutoSCSIData_T AutoSCSIData;
                   1499:   BusLogic_GeometryRegister_T GeometryRegister;
                   1500:   BusLogic_RequestedReplyLength_T RequestedReplyLength;
                   1501:   unsigned char *TargetPointer, Character;
                   1502:   int TargetID, i;
                   1503:   /*
                   1504:     Configuration Information for FlashPoint Host Adapters is provided in the
                   1505:     FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function.
                   1506:     Initialize fields in the Host Adapter structure from the FlashPoint_Info
                   1507:     structure.
                   1508:   */
                   1509:   if (BusLogic_FlashPointHostAdapterP(HostAdapter))
                   1510:     {
                   1511:       FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
                   1512:       TargetPointer = HostAdapter->ModelName;
                   1513:       *TargetPointer++ = 'B';
                   1514:       *TargetPointer++ = 'T';
                   1515:       *TargetPointer++ = '-';
                   1516:       for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++)
                   1517:        *TargetPointer++ = FlashPointInfo->ModelNumber[i];
                   1518:       *TargetPointer++ = '\0';
                   1519:       strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion);
                   1520:       HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID;
                   1521:       HostAdapter->ExtendedTranslationEnabled =
                   1522:        FlashPointInfo->ExtendedTranslationEnabled;
                   1523:       HostAdapter->ParityCheckingEnabled =
                   1524:        FlashPointInfo->ParityCheckingEnabled;
                   1525:       HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset;
                   1526:       HostAdapter->LevelSensitiveInterrupt = true;
                   1527:       HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI;
                   1528:       HostAdapter->HostDifferentialSCSI = false;
                   1529:       HostAdapter->HostSupportsSCAM = true;
                   1530:       HostAdapter->HostUltraSCSI = true;
                   1531:       HostAdapter->ExtendedLUNSupport = true;
                   1532:       HostAdapter->TerminationInfoValid = true;
                   1533:       HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated;
                   1534:       HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated;
                   1535:       HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled;
                   1536:       HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2;
                   1537:       HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
                   1538:       HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
                   1539:       HostAdapter->MaxLogicalUnits = 32;
                   1540:       HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
                   1541:       HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
                   1542:       HostAdapter->DriverQueueDepth = 255;
                   1543:       HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
                   1544:       HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
                   1545:       HostAdapter->FastPermitted = FlashPointInfo->FastPermitted;
                   1546:       HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted;
                   1547:       HostAdapter->WidePermitted = FlashPointInfo->WidePermitted;
                   1548:       HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted;
                   1549:       HostAdapter->TaggedQueuingPermitted = 0xFFFF;
                   1550:       goto Common;
                   1551:     }
                   1552:   /*
                   1553:     Issue the Inquire Board ID command.
                   1554:   */
                   1555:   if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0,
                   1556:                       &BoardID, sizeof(BoardID)) != sizeof(BoardID))
                   1557:     return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
                   1558:   /*
                   1559:     Issue the Inquire Configuration command.
                   1560:   */
                   1561:   if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0,
                   1562:                       &Configuration, sizeof(Configuration))
                   1563:       != sizeof(Configuration))
                   1564:     return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
                   1565:   /*
                   1566:     Issue the Inquire Setup Information command.
                   1567:   */
                   1568:   RequestedReplyLength = sizeof(SetupInformation);
                   1569:   if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
                   1570:                       &RequestedReplyLength, sizeof(RequestedReplyLength),
                   1571:                       &SetupInformation, sizeof(SetupInformation))
                   1572:       != sizeof(SetupInformation))
                   1573:     return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
                   1574:   /*
                   1575:     Issue the Inquire Extended Setup Information command.
                   1576:   */
                   1577:   RequestedReplyLength = sizeof(ExtendedSetupInformation);
                   1578:   if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation,
                   1579:                       &RequestedReplyLength, sizeof(RequestedReplyLength),
                   1580:                       &ExtendedSetupInformation,
                   1581:                       sizeof(ExtendedSetupInformation))
                   1582:       != sizeof(ExtendedSetupInformation))
                   1583:     return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
                   1584:   /*
                   1585:     Issue the Inquire Firmware Version 3rd Digit command.
                   1586:   */
                   1587:   FirmwareVersion3rdDigit = '\0';
                   1588:   if (BoardID.FirmwareVersion1stDigit > '0')
                   1589:     if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit,
                   1590:                         NULL, 0, &FirmwareVersion3rdDigit,
                   1591:                         sizeof(FirmwareVersion3rdDigit))
                   1592:        != sizeof(FirmwareVersion3rdDigit))
                   1593:       return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
                   1594:   /*
                   1595:     Issue the Inquire Host Adapter Model Number command.
                   1596:   */
                   1597:   if (ExtendedSetupInformation.BusType == 'A' &&
                   1598:       BoardID.FirmwareVersion1stDigit == '2')
                   1599:     /* BusLogic BT-542B ISA 2.xx */
                   1600:     strcpy(HostAdapterModelNumber, "542B");
                   1601:   else if (ExtendedSetupInformation.BusType == 'E' &&
                   1602:           BoardID.FirmwareVersion1stDigit == '2' &&
                   1603:           (BoardID.FirmwareVersion2ndDigit <= '1' ||
                   1604:            (BoardID.FirmwareVersion2ndDigit == '2' &&
                   1605:             FirmwareVersion3rdDigit == '0')))
                   1606:     /* BusLogic BT-742A EISA 2.1x or 2.20 */
                   1607:     strcpy(HostAdapterModelNumber, "742A");
                   1608:   else if (ExtendedSetupInformation.BusType == 'E' &&
                   1609:           BoardID.FirmwareVersion1stDigit == '0')
                   1610:     /* AMI FastDisk EISA Series 441 0.x */
                   1611:     strcpy(HostAdapterModelNumber, "747A");
                   1612:   else
                   1613:     {
                   1614:       RequestedReplyLength = sizeof(HostAdapterModelNumber);
                   1615:       if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber,
                   1616:                           &RequestedReplyLength, sizeof(RequestedReplyLength),
                   1617:                           &HostAdapterModelNumber,
                   1618:                           sizeof(HostAdapterModelNumber))
                   1619:          != sizeof(HostAdapterModelNumber))
                   1620:        return BusLogic_Failure(HostAdapter,
                   1621:                                "INQUIRE HOST ADAPTER MODEL NUMBER");
                   1622:     }
                   1623:   /*
                   1624:     BusLogic MultiMaster Host Adapters can be identified by their model number
                   1625:     and the major version number of their firmware as follows:
                   1626: 
                   1627:     5.xx       BusLogic "W" Series Host Adapters:
                   1628:                  BT-948/958/958D
                   1629:     4.xx       BusLogic "C" Series Host Adapters:
                   1630:                  BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
                   1631:     3.xx       BusLogic "S" Series Host Adapters:
                   1632:                  BT-747S/747D/757S/757D/445S/545S/542D
                   1633:                  BT-542B/742A (revision H)
                   1634:     2.xx       BusLogic "A" Series Host Adapters:
                   1635:                  BT-542B/742A (revision G and below)
                   1636:     0.xx       AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
                   1637:   */
                   1638:   /*
                   1639:     Save the Model Name and Host Adapter Name in the Host Adapter structure.
                   1640:   */
                   1641:   TargetPointer = HostAdapter->ModelName;
                   1642:   *TargetPointer++ = 'B';
                   1643:   *TargetPointer++ = 'T';
                   1644:   *TargetPointer++ = '-';
                   1645:   for (i = 0; i < sizeof(HostAdapterModelNumber); i++)
                   1646:     {
                   1647:       Character = HostAdapterModelNumber[i];
                   1648:       if (Character == ' ' || Character == '\0') break;
                   1649:       *TargetPointer++ = Character;
                   1650:     }
                   1651:   *TargetPointer++ = '\0';
                   1652:   /*
                   1653:     Save the Firmware Version in the Host Adapter structure.
                   1654:   */
                   1655:   TargetPointer = HostAdapter->FirmwareVersion;
                   1656:   *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
                   1657:   *TargetPointer++ = '.';
                   1658:   *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
                   1659:   if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
                   1660:     *TargetPointer++ = FirmwareVersion3rdDigit;
                   1661:   *TargetPointer = '\0';
                   1662:   /*
                   1663:     Issue the Inquire Firmware Version Letter command.
                   1664:   */
                   1665:   if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0)
                   1666:     {
                   1667:       if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter,
                   1668:                           NULL, 0, &FirmwareVersionLetter,
                   1669:                           sizeof(FirmwareVersionLetter))
                   1670:          != sizeof(FirmwareVersionLetter))
                   1671:        return BusLogic_Failure(HostAdapter,
                   1672:                                "INQUIRE FIRMWARE VERSION LETTER");
                   1673:       if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
                   1674:        *TargetPointer++ = FirmwareVersionLetter;
                   1675:       *TargetPointer = '\0';
                   1676:     }
                   1677:   /*
                   1678:     Save the Host Adapter SCSI ID in the Host Adapter structure.
                   1679:   */
                   1680:   HostAdapter->SCSI_ID = Configuration.HostAdapterID;
                   1681:   /*
                   1682:     Determine the Bus Type and save it in the Host Adapter structure, determine
                   1683:     and save the IRQ Channel if necessary, and determine and save the DMA
                   1684:     Channel for ISA Host Adapters.
                   1685:   */
                   1686:   HostAdapter->HostAdapterBusType =
                   1687:     BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4'];
                   1688:   if (HostAdapter->IRQ_Channel == 0)
                   1689:     {
                   1690:       if (Configuration.IRQ_Channel9)
                   1691:        HostAdapter->IRQ_Channel = 9;
                   1692:       else if (Configuration.IRQ_Channel10)
                   1693:        HostAdapter->IRQ_Channel = 10;
                   1694:       else if (Configuration.IRQ_Channel11)
                   1695:        HostAdapter->IRQ_Channel = 11;
                   1696:       else if (Configuration.IRQ_Channel12)
                   1697:        HostAdapter->IRQ_Channel = 12;
                   1698:       else if (Configuration.IRQ_Channel14)
                   1699:        HostAdapter->IRQ_Channel = 14;
                   1700:       else if (Configuration.IRQ_Channel15)
                   1701:        HostAdapter->IRQ_Channel = 15;
                   1702:     }
                   1703:   if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus)
                   1704:     {
                   1705:       if (Configuration.DMA_Channel5)
                   1706:        HostAdapter->DMA_Channel = 5;
                   1707:       else if (Configuration.DMA_Channel6)
                   1708:        HostAdapter->DMA_Channel = 6;
                   1709:       else if (Configuration.DMA_Channel7)
                   1710:        HostAdapter->DMA_Channel = 7;
                   1711:     }
                   1712:   /*
                   1713:     Determine whether Extended Translation is enabled and save it in
                   1714:     the Host Adapter structure.
                   1715:   */
                   1716:   GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
                   1717:   HostAdapter->ExtendedTranslationEnabled =
                   1718:     GeometryRegister.Bits.ExtendedTranslationEnabled;
                   1719:   /*
                   1720:     Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
                   1721:     SCSI flag, Differential SCSI flag, SCAM Supported flag, and
                   1722:     Ultra SCSI flag in the Host Adapter structure.
                   1723:   */
                   1724:   HostAdapter->HostAdapterScatterGatherLimit =
                   1725:     ExtendedSetupInformation.ScatterGatherLimit;
                   1726:   HostAdapter->DriverScatterGatherLimit =
                   1727:     HostAdapter->HostAdapterScatterGatherLimit;
                   1728:   if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
                   1729:     HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
                   1730:   if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt)
                   1731:     HostAdapter->LevelSensitiveInterrupt = true;
                   1732:   HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
                   1733:   HostAdapter->HostDifferentialSCSI =
                   1734:     ExtendedSetupInformation.HostDifferentialSCSI;
                   1735:   HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM;
                   1736:   HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
                   1737:   /*
                   1738:     Determine whether Extended LUN Format CCBs are supported and save the
                   1739:     information in the Host Adapter structure.
                   1740:   */
                   1741:   if (HostAdapter->FirmwareVersion[0] == '5' ||
                   1742:       (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
                   1743:     HostAdapter->ExtendedLUNSupport = true;
                   1744:   /*
                   1745:     Issue the Inquire PCI Host Adapter Information command to read the
                   1746:     Termination Information from "W" series MultiMaster Host Adapters.
                   1747:   */
                   1748:   if (HostAdapter->FirmwareVersion[0] == '5')
                   1749:     {
                   1750:       if (BusLogic_Command(HostAdapter,
                   1751:                           BusLogic_InquirePCIHostAdapterInformation,
                   1752:                           NULL, 0, &PCIHostAdapterInformation,
                   1753:                           sizeof(PCIHostAdapterInformation))
                   1754:          != sizeof(PCIHostAdapterInformation))
                   1755:        return BusLogic_Failure(HostAdapter,
                   1756:                                "INQUIRE PCI HOST ADAPTER INFORMATION");
                   1757:       /*
                   1758:        Save the Termination Information in the Host Adapter structure.
                   1759:       */
                   1760:       if (PCIHostAdapterInformation.GenericInfoValid)
                   1761:        {
                   1762:          HostAdapter->TerminationInfoValid = true;
                   1763:          HostAdapter->LowByteTerminated =
                   1764:            PCIHostAdapterInformation.LowByteTerminated;
                   1765:          HostAdapter->HighByteTerminated =
                   1766:            PCIHostAdapterInformation.HighByteTerminated;
                   1767:        }
                   1768:     }
                   1769:   /*
                   1770:     Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data
                   1771:     from "W" and "C" series MultiMaster Host Adapters.
                   1772:   */
                   1773:   if (HostAdapter->FirmwareVersion[0] >= '4')
                   1774:     {
                   1775:       FetchHostAdapterLocalRAMRequest.ByteOffset =
                   1776:        BusLogic_AutoSCSI_BaseOffset;
                   1777:       FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
                   1778:       if (BusLogic_Command(HostAdapter,
                   1779:                           BusLogic_FetchHostAdapterLocalRAM,
                   1780:                           &FetchHostAdapterLocalRAMRequest,
                   1781:                           sizeof(FetchHostAdapterLocalRAMRequest),
                   1782:                           &AutoSCSIData, sizeof(AutoSCSIData))
                   1783:          != sizeof(AutoSCSIData))
                   1784:        return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
                   1785:       /*
                   1786:        Save the Parity Checking Enabled, Bus Reset Enabled, and Termination
                   1787:        Information in the Host Adapter structure.
                   1788:       */
                   1789:       HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
                   1790:       HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
                   1791:       if (HostAdapter->FirmwareVersion[0] == '4')
                   1792:        {
                   1793:          HostAdapter->TerminationInfoValid = true;
                   1794:          HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated;
                   1795:          HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated;
                   1796:        }
                   1797:       /*
                   1798:        Save the Wide Permitted, Fast Permitted, Synchronous Permitted,
                   1799:        Disconnect Permitted, Ultra Permitted, and SCAM Information in the
                   1800:        Host Adapter structure.
                   1801:       */
                   1802:       HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
                   1803:       HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
                   1804:       HostAdapter->SynchronousPermitted =
                   1805:        AutoSCSIData.SynchronousPermitted;
                   1806:       HostAdapter->DisconnectPermitted =
                   1807:        AutoSCSIData.DisconnectPermitted;
                   1808:       if (HostAdapter->HostUltraSCSI)
                   1809:        HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
                   1810:       if (HostAdapter->HostSupportsSCAM)
                   1811:        {
                   1812:          HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
                   1813:          HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
                   1814:        }
                   1815:     }
                   1816:   /*
                   1817:     Initialize fields in the Host Adapter structure for "S" and "A" series
                   1818:     MultiMaster Host Adapters.
                   1819:   */
                   1820:   if (HostAdapter->FirmwareVersion[0] < '4')
                   1821:     {
                   1822:       if (SetupInformation.SynchronousInitiationEnabled)
                   1823:        {
                   1824:          HostAdapter->SynchronousPermitted = 0xFF;
                   1825:          if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)
                   1826:            {
                   1827:              if (ExtendedSetupInformation.Misc.FastOnEISA)
                   1828:                HostAdapter->FastPermitted = 0xFF;
                   1829:              if (strcmp(HostAdapter->ModelName, "BT-757") == 0)
                   1830:                HostAdapter->WidePermitted = 0xFF;
                   1831:            }
                   1832:        }
                   1833:       HostAdapter->DisconnectPermitted = 0xFF;
                   1834:       HostAdapter->ParityCheckingEnabled =
                   1835:        SetupInformation.ParityCheckingEnabled;
                   1836:       HostAdapter->BusResetEnabled = true;
                   1837:     }
                   1838:   /*
                   1839:     Determine the maximum number of Target IDs and Logical Units supported by
                   1840:     this driver for Wide and Narrow Host Adapters.
                   1841:   */
                   1842:   HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
                   1843:   HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
                   1844:   /*
                   1845:     Select appropriate values for the Mailbox Count, Driver Queue Depth,
                   1846:     Initial CCBs, and Incremental CCBs variables based on whether or not Strict
                   1847:     Round Robin Mode is supported.  If Strict Round Robin Mode is supported,
                   1848:     then there is no performance degradation in using the maximum possible
                   1849:     number of Outgoing and Incoming Mailboxes and allowing the Tagged and
                   1850:     Untagged Queue Depths to determine the actual utilization.  If Strict Round
                   1851:     Robin Mode is not supported, then the Host Adapter must scan all the
                   1852:     Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can
                   1853:     cause a substantial performance penalty.  The host adapters actually have
                   1854:     room to store the following number of CCBs internally; that is, they can
                   1855:     internally queue and manage this many active commands on the SCSI bus
                   1856:     simultaneously.  Performance measurements demonstrate that the Driver Queue
                   1857:     Depth should be set to the Mailbox Count, rather than the Host Adapter
                   1858:     Queue Depth (internal CCB capacity), as it is more efficient to have the
                   1859:     queued commands waiting in Outgoing Mailboxes if necessary than to block
                   1860:     the process in the higher levels of the SCSI Subsystem.
                   1861: 
                   1862:        192       BT-948/958/958D
                   1863:        100       BT-946C/956C/956CD/747C/757C/757CD/445C
                   1864:         50       BT-545C/540CF
                   1865:         30       BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
                   1866:   */
                   1867:   if (HostAdapter->FirmwareVersion[0] == '5')
                   1868:     HostAdapter->HostAdapterQueueDepth = 192;
                   1869:   else if (HostAdapter->FirmwareVersion[0] == '4')
                   1870:     HostAdapter->HostAdapterQueueDepth =
                   1871:       (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50);
                   1872:   else HostAdapter->HostAdapterQueueDepth = 30;
                   1873:   if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
                   1874:     {
                   1875:       HostAdapter->StrictRoundRobinModeSupport = true;
                   1876:       HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
                   1877:     }
                   1878:   else
                   1879:     {
                   1880:       HostAdapter->StrictRoundRobinModeSupport = false;
                   1881:       HostAdapter->MailboxCount = 32;
                   1882:     }
                   1883:   HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
                   1884:   HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
                   1885:   HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
                   1886:   /*
                   1887:     Tagged Queuing support is available and operates properly on all "W" series
                   1888:     MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with
                   1889:     firmware version 4.22 and above, and on "S" series MultiMaster Host
                   1890:     Adapters with firmware version 3.35 and above.
                   1891:   */
                   1892:   HostAdapter->TaggedQueuingPermitted = 0;
                   1893:   switch (HostAdapter->FirmwareVersion[0])
                   1894:     {
                   1895:     case '5':
                   1896:       HostAdapter->TaggedQueuingPermitted = 0xFFFF;
                   1897:       break;
                   1898:     case '4':
                   1899:       if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
                   1900:        HostAdapter->TaggedQueuingPermitted = 0xFFFF;
                   1901:       break;
                   1902:     case '3':
                   1903:       if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
                   1904:        HostAdapter->TaggedQueuingPermitted = 0xFFFF;
                   1905:       break;
                   1906:     }
                   1907:   /*
                   1908:     Determine the Host Adapter BIOS Address if the BIOS is enabled and
                   1909:     save it in the Host Adapter structure.  The BIOS is disabled if the
                   1910:     BIOS_Address is 0.
                   1911:   */
                   1912:   HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
                   1913:   /*
                   1914:     ISA Host Adapters require Bounce Buffers if there is more than 16MB memory.
                   1915:   */
                   1916:   if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus &&
                   1917:       (void *) high_memory > (void *) MAX_DMA_ADDRESS)
                   1918:     HostAdapter->BounceBuffersRequired = true;
                   1919:   /*
                   1920:     BusLogic BT-445S Host Adapters prior to board revision E have a hardware
                   1921:     bug whereby when the BIOS is enabled, transfers to/from the same address
                   1922:     range the BIOS occupies modulo 16MB are handled incorrectly.  Only properly
                   1923:     functioning BT-445S Host Adapters have firmware version 3.37, so require
                   1924:     that ISA Bounce Buffers be used for the buggy BT-445S models if there is
                   1925:     more than 16MB memory.
                   1926:   */
                   1927:   if (HostAdapter->BIOS_Address > 0 &&
                   1928:       strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
                   1929:       strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 &&
                   1930:       (void *) high_memory > (void *) MAX_DMA_ADDRESS)
                   1931:     HostAdapter->BounceBuffersRequired = true;
                   1932:   /*
                   1933:     Initialize parameters common to MultiMaster and FlashPoint Host Adapters.
                   1934:   */
                   1935: Common:
                   1936:   /*
                   1937:     Initialize the Host Adapter Full Model Name from the Model Name.
                   1938:   */
                   1939:   strcpy(HostAdapter->FullModelName, "BusLogic ");
                   1940:   strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
                   1941:   /*
                   1942:     Select an appropriate value for the Tagged Queue Depth either from a
                   1943:     BusLogic Driver Options specification, or based on whether this Host
                   1944:     Adapter requires that ISA Bounce Buffers be used.  The Tagged Queue Depth
                   1945:     is left at 0 for automatic determination in BusLogic_SelectQueueDepths.
                   1946:     Initialize the Untagged Queue Depth.
                   1947:   */
                   1948:   for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
                   1949:     {
                   1950:       unsigned char QueueDepth = 0;
                   1951:       if (HostAdapter->DriverOptions != NULL &&
                   1952:          HostAdapter->DriverOptions->QueueDepth[TargetID] > 0)
                   1953:        QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID];
                   1954:       else if (HostAdapter->BounceBuffersRequired)
                   1955:        QueueDepth = BusLogic_TaggedQueueDepthBB;
                   1956:       HostAdapter->QueueDepth[TargetID] = QueueDepth;
                   1957:     }
                   1958:   if (HostAdapter->BounceBuffersRequired)
                   1959:     HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB;
                   1960:   else HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
                   1961:   if (HostAdapter->DriverOptions != NULL)
                   1962:     HostAdapter->CommonQueueDepth =
                   1963:       HostAdapter->DriverOptions->CommonQueueDepth;
                   1964:   if (HostAdapter->CommonQueueDepth > 0 &&
                   1965:       HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth)
                   1966:     HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth;
                   1967:   /*
                   1968:     Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
                   1969:     Therefore, mask the Tagged Queuing Permitted Default bits with the
                   1970:     Disconnect/Reconnect Permitted bits.
                   1971:   */
                   1972:   HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
                   1973:   /*
                   1974:     Combine the default Tagged Queuing Permitted bits with any BusLogic Driver
                   1975:     Options Tagged Queuing specification.
                   1976:   */
                   1977:   if (HostAdapter->DriverOptions != NULL)
                   1978:     HostAdapter->TaggedQueuingPermitted =
                   1979:       (HostAdapter->DriverOptions->TaggedQueuingPermitted &
                   1980:        HostAdapter->DriverOptions->TaggedQueuingPermittedMask) |
                   1981:       (HostAdapter->TaggedQueuingPermitted &
                   1982:        ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask);
                   1983:   /*
                   1984:     Select appropriate values for the Error Recovery Strategy array
                   1985:     either from a BusLogic Driver Options specification, or using
                   1986:     BusLogic_ErrorRecovery_Default.
                   1987:   */
                   1988:   for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
                   1989:     if (HostAdapter->DriverOptions != NULL)
                   1990:       HostAdapter->ErrorRecoveryStrategy[TargetID] =
                   1991:        HostAdapter->DriverOptions->ErrorRecoveryStrategy[TargetID];
                   1992:     else HostAdapter->ErrorRecoveryStrategy[TargetID] =
                   1993:           BusLogic_ErrorRecovery_Default;
                   1994:   /*
                   1995:     Select an appropriate value for Bus Settle Time either from a BusLogic
                   1996:     Driver Options specification, or from BusLogic_DefaultBusSettleTime.
                   1997:   */
                   1998:   if (HostAdapter->DriverOptions != NULL &&
                   1999:       HostAdapter->DriverOptions->BusSettleTime > 0)
                   2000:     HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime;
                   2001:   else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
                   2002:   /*
                   2003:     Indicate reading the Host Adapter Configuration completed successfully.
                   2004:   */
                   2005:   return true;
                   2006: }
                   2007: 
                   2008: 
                   2009: /*
                   2010:   BusLogic_ReportHostAdapterConfiguration reports the configuration of
                   2011:   Host Adapter.
                   2012: */
                   2013: 
                   2014: static boolean BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T
                   2015:                                                       *HostAdapter)
                   2016: {
                   2017:   unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
                   2018:   unsigned short SynchronousPermitted, FastPermitted;
                   2019:   unsigned short UltraPermitted, WidePermitted;
                   2020:   unsigned short DisconnectPermitted, TaggedQueuingPermitted;
                   2021:   boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth;
                   2022:   boolean CommonErrorRecovery;
                   2023:   char SynchronousString[BusLogic_MaxTargetDevices+1];
                   2024:   char WideString[BusLogic_MaxTargetDevices+1];
                   2025:   char DisconnectString[BusLogic_MaxTargetDevices+1];
                   2026:   char TaggedQueuingString[BusLogic_MaxTargetDevices+1];
                   2027:   char ErrorRecoveryString[BusLogic_MaxTargetDevices+1];
                   2028:   char *SynchronousMessage = SynchronousString;
                   2029:   char *WideMessage = WideString;
                   2030:   char *DisconnectMessage = DisconnectString;
                   2031:   char *TaggedQueuingMessage = TaggedQueuingString;
                   2032:   char *ErrorRecoveryMessage = ErrorRecoveryString;
                   2033:   int TargetID;
                   2034:   BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
                   2035:                HostAdapter, HostAdapter->ModelName,
                   2036:                BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType],
                   2037:                (HostAdapter->HostWideSCSI ? " Wide" : ""),
                   2038:                (HostAdapter->HostDifferentialSCSI ? " Differential" : ""),
                   2039:                (HostAdapter->HostUltraSCSI ? " Ultra" : ""));
                   2040:   BusLogic_Info("  Firmware Version: %s, I/O Address: 0x%X, "
                   2041:                "IRQ Channel: %d/%s\n", HostAdapter,
                   2042:                HostAdapter->FirmwareVersion,
                   2043:                HostAdapter->IO_Address, HostAdapter->IRQ_Channel,
                   2044:                (HostAdapter->LevelSensitiveInterrupt ? "Level" : "Edge"));
                   2045:   if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus)
                   2046:     {
                   2047:       BusLogic_Info("  DMA Channel: ", HostAdapter);
                   2048:       if (HostAdapter->DMA_Channel > 0)
                   2049:        BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel);
                   2050:       else BusLogic_Info("None, ", HostAdapter);
                   2051:       if (HostAdapter->BIOS_Address > 0)
                   2052:        BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter,
                   2053:                      HostAdapter->BIOS_Address);
                   2054:       else BusLogic_Info("BIOS Address: None, ", HostAdapter);
                   2055:     }
                   2056:   else
                   2057:     {
                   2058:       BusLogic_Info("  PCI Bus: %d, Device: %d, Address: ",
                   2059:                    HostAdapter, HostAdapter->Bus, HostAdapter->Device);
                   2060:       if (HostAdapter->PCI_Address > 0)
                   2061:        BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address);
                   2062:       else BusLogic_Info("Unassigned, ", HostAdapter);
                   2063:     }
                   2064:   BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter,
                   2065:                HostAdapter->SCSI_ID);
                   2066:   BusLogic_Info("  Parity Checking: %s, Extended Translation: %s\n",
                   2067:                HostAdapter,
                   2068:                (HostAdapter->ParityCheckingEnabled
                   2069:                 ? "Enabled" : "Disabled"),
                   2070:                (HostAdapter->ExtendedTranslationEnabled
                   2071:                 ? "Enabled" : "Disabled"));
                   2072:   AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID);
                   2073:   SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask;
                   2074:   FastPermitted = HostAdapter->FastPermitted & AllTargetsMask;
                   2075:   UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask;
                   2076:   if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
                   2077:        (HostAdapter->FirmwareVersion[0] >= '4' ||
                   2078:        HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) ||
                   2079:       BusLogic_FlashPointHostAdapterP(HostAdapter))
                   2080:     {
                   2081:       CommonSynchronousNegotiation = false;
                   2082:       if (SynchronousPermitted == 0)
                   2083:        {
                   2084:          SynchronousMessage = "Disabled";
                   2085:          CommonSynchronousNegotiation = true;
                   2086:        }
                   2087:       else if (SynchronousPermitted == AllTargetsMask)
                   2088:        {
                   2089:          if (FastPermitted == 0)
                   2090:            {
                   2091:              SynchronousMessage = "Slow";
                   2092:              CommonSynchronousNegotiation = true;
                   2093:            }
                   2094:          else if (FastPermitted == AllTargetsMask)
                   2095:            {
                   2096:              if (UltraPermitted == 0)
                   2097:                {
                   2098:                  SynchronousMessage = "Fast";
                   2099:                  CommonSynchronousNegotiation = true;
                   2100:                }
                   2101:              else if (UltraPermitted == AllTargetsMask)
                   2102:                {
                   2103:                  SynchronousMessage = "Ultra";
                   2104:                  CommonSynchronousNegotiation = true;
                   2105:                }
                   2106:            }
                   2107:        }
                   2108:       if (!CommonSynchronousNegotiation)
                   2109:        {
                   2110:          for (TargetID = 0;
                   2111:               TargetID < HostAdapter->MaxTargetDevices;
                   2112:               TargetID++)
                   2113:            SynchronousString[TargetID] =
                   2114:              ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' :
                   2115:               (!(FastPermitted & (1 << TargetID)) ? 'S' :
                   2116:                (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U')));
                   2117:          SynchronousString[HostAdapter->SCSI_ID] = '#';
                   2118:          SynchronousString[HostAdapter->MaxTargetDevices] = '\0';
                   2119:        }
                   2120:     }
                   2121:   else SynchronousMessage =
                   2122:         (SynchronousPermitted == 0 ? "Disabled" : "Enabled");
                   2123:   WidePermitted = HostAdapter->WidePermitted & AllTargetsMask;
                   2124:   if (WidePermitted == 0)
                   2125:     WideMessage = "Disabled";
                   2126:   else if (WidePermitted == AllTargetsMask)
                   2127:     WideMessage = "Enabled";
                   2128:   else
                   2129:     {
                   2130:       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2131:         WideString[TargetID] =
                   2132:           ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N');
                   2133:       WideString[HostAdapter->SCSI_ID] = '#';
                   2134:       WideString[HostAdapter->MaxTargetDevices] = '\0';
                   2135:     }
                   2136:   DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
                   2137:   if (DisconnectPermitted == 0)
                   2138:     DisconnectMessage = "Disabled";
                   2139:   else if (DisconnectPermitted == AllTargetsMask)
                   2140:     DisconnectMessage = "Enabled";
                   2141:   else
                   2142:     {
                   2143:       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2144:        DisconnectString[TargetID] =
                   2145:          ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
                   2146:       DisconnectString[HostAdapter->SCSI_ID] = '#';
                   2147:       DisconnectString[HostAdapter->MaxTargetDevices] = '\0';
                   2148:     }
                   2149:   TaggedQueuingPermitted =
                   2150:     HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
                   2151:   if (TaggedQueuingPermitted == 0)
                   2152:     TaggedQueuingMessage = "Disabled";
                   2153:   else if (TaggedQueuingPermitted == AllTargetsMask)
                   2154:     TaggedQueuingMessage = "Enabled";
                   2155:   else
                   2156:     {
                   2157:       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2158:        TaggedQueuingString[TargetID] =
                   2159:          ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
                   2160:       TaggedQueuingString[HostAdapter->SCSI_ID] = '#';
                   2161:       TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0';
                   2162:     }
                   2163:   BusLogic_Info("  Synchronous Negotiation: %s, Wide Negotiation: %s\n",
                   2164:                HostAdapter, SynchronousMessage, WideMessage);
                   2165:   BusLogic_Info("  Disconnect/Reconnect: %s, Tagged Queuing: %s\n",
                   2166:                HostAdapter, DisconnectMessage, TaggedQueuingMessage);
                   2167:   if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
                   2168:     {
                   2169:       BusLogic_Info("  Scatter/Gather Limit: %d of %d segments, "
                   2170:                    "Mailboxes: %d\n", HostAdapter,
                   2171:                    HostAdapter->DriverScatterGatherLimit,
                   2172:                    HostAdapter->HostAdapterScatterGatherLimit,
                   2173:                    HostAdapter->MailboxCount);
                   2174:       BusLogic_Info("  Driver Queue Depth: %d, "
                   2175:                    "Host Adapter Queue Depth: %d\n",
                   2176:                    HostAdapter, HostAdapter->DriverQueueDepth,
                   2177:                    HostAdapter->HostAdapterQueueDepth);
                   2178:     }
                   2179:   else BusLogic_Info("  Driver Queue Depth: %d, "
                   2180:                     "Scatter/Gather Limit: %d segments\n",
                   2181:                     HostAdapter, HostAdapter->DriverQueueDepth,
                   2182:                     HostAdapter->DriverScatterGatherLimit);
                   2183:   BusLogic_Info("  Tagged Queue Depth: ", HostAdapter);
                   2184:   CommonTaggedQueueDepth = true;
                   2185:   for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2186:     if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0])
                   2187:       {
                   2188:        CommonTaggedQueueDepth = false;
                   2189:        break;
                   2190:       }
                   2191:   if (CommonTaggedQueueDepth)
                   2192:     {
                   2193:       if (HostAdapter->QueueDepth[0] > 0)
                   2194:        BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]);
                   2195:       else BusLogic_Info("Automatic", HostAdapter);
                   2196:     }
                   2197:   else BusLogic_Info("Individual", HostAdapter);
                   2198:   BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter,
                   2199:                HostAdapter->UntaggedQueueDepth);
                   2200:   CommonErrorRecovery = true;
                   2201:   for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2202:     if (HostAdapter->ErrorRecoveryStrategy[TargetID] !=
                   2203:        HostAdapter->ErrorRecoveryStrategy[0])
                   2204:       {
                   2205:        CommonErrorRecovery = false;
                   2206:        break;
                   2207:       }
                   2208:   if (CommonErrorRecovery)
                   2209:     ErrorRecoveryMessage =
                   2210:       BusLogic_ErrorRecoveryStrategyNames[
                   2211:        HostAdapter->ErrorRecoveryStrategy[0]];
                   2212:   else
                   2213:     {
                   2214:       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2215:        ErrorRecoveryString[TargetID] =
                   2216:          BusLogic_ErrorRecoveryStrategyLetters[
                   2217:            HostAdapter->ErrorRecoveryStrategy[TargetID]];
                   2218:       ErrorRecoveryString[HostAdapter->SCSI_ID] = '#';
                   2219:       ErrorRecoveryString[HostAdapter->MaxTargetDevices] = '\0';
                   2220:     }
                   2221:   BusLogic_Info("  Error Recovery Strategy: %s, SCSI Bus Reset: %s\n",
                   2222:                HostAdapter, ErrorRecoveryMessage,
                   2223:                (HostAdapter->BusResetEnabled ? "Enabled" : "Disabled"));
                   2224:   if (HostAdapter->TerminationInfoValid)
                   2225:     {
                   2226:       if (HostAdapter->HostWideSCSI)
                   2227:        BusLogic_Info("  SCSI Bus Termination: %s", HostAdapter,
                   2228:                      (HostAdapter->LowByteTerminated
                   2229:                       ? (HostAdapter->HighByteTerminated
                   2230:                          ? "Both Enabled" : "Low Enabled")
                   2231:                       : (HostAdapter->HighByteTerminated
                   2232:                          ? "High Enabled" : "Both Disabled")));
                   2233:       else BusLogic_Info("  SCSI Bus Termination: %s", HostAdapter,
                   2234:                         (HostAdapter->LowByteTerminated ?
                   2235:                          "Enabled" : "Disabled"));
                   2236:       if (HostAdapter->HostSupportsSCAM)
                   2237:        BusLogic_Info(", SCAM: %s", HostAdapter,
                   2238:                      (HostAdapter->SCAM_Enabled
                   2239:                       ? (HostAdapter->SCAM_Level2
                   2240:                          ? "Enabled, Level 2" : "Enabled, Level 1")
                   2241:                       : "Disabled"));
                   2242:       BusLogic_Info("\n", HostAdapter);
                   2243:     }
                   2244:   /*
                   2245:     Indicate reporting the Host Adapter configuration completed successfully.
                   2246:   */
                   2247:   return true;
                   2248: }
                   2249: 
                   2250: 
                   2251: /*
                   2252:   BusLogic_AcquireResources acquires the system resources necessary to use
                   2253:   Host Adapter.
                   2254: */
                   2255: 
                   2256: static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter)
                   2257: {
                   2258:   if (HostAdapter->IRQ_Channel == 0)
                   2259:     {
                   2260:       BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
                   2261:                     HostAdapter);
                   2262:       return false;
                   2263:     }
                   2264:   /*
                   2265:     Acquire shared access to the IRQ Channel.
                   2266:   */
                   2267:   if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
                   2268:                  SA_INTERRUPT | SA_SHIRQ,
                   2269:                  HostAdapter->FullModelName, HostAdapter) < 0)
                   2270:     {
                   2271:       BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
                   2272:                     HostAdapter, HostAdapter->IRQ_Channel);
                   2273:       return false;
                   2274:     }
                   2275:   HostAdapter->IRQ_ChannelAcquired = true;
                   2276:   /*
                   2277:     Acquire exclusive access to the DMA Channel.
                   2278:   */
                   2279:   if (HostAdapter->DMA_Channel > 0)
                   2280:     {
                   2281:       if (request_dma(HostAdapter->DMA_Channel,
                   2282:                      HostAdapter->FullModelName) < 0)
                   2283:        {
                   2284:          BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
                   2285:                         HostAdapter, HostAdapter->DMA_Channel);
                   2286:          return false;
                   2287:        }
                   2288:       set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
                   2289:       enable_dma(HostAdapter->DMA_Channel);
                   2290:       HostAdapter->DMA_ChannelAcquired = true;
                   2291:     }
                   2292:   /*
                   2293:     Indicate the System Resource Acquisition completed successfully,
                   2294:   */
                   2295:   return true;
                   2296: }
                   2297: 
                   2298: 
                   2299: /*
                   2300:   BusLogic_ReleaseResources releases any system resources previously acquired
                   2301:   by BusLogic_AcquireResources.
                   2302: */
                   2303: 
                   2304: static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
                   2305: {
                   2306:   /*
                   2307:     Release shared access to the IRQ Channel.
                   2308:   */
                   2309:   if (HostAdapter->IRQ_ChannelAcquired)
                   2310:     free_irq(HostAdapter->IRQ_Channel, HostAdapter);
                   2311:   /*
                   2312:     Release exclusive access to the DMA Channel.
                   2313:   */
                   2314:   if (HostAdapter->DMA_ChannelAcquired)
                   2315:     free_dma(HostAdapter->DMA_Channel);
                   2316: }
                   2317: 
                   2318: 
                   2319: /*
                   2320:   BusLogic_InitializeHostAdapter initializes Host Adapter.  This is the only
                   2321:   function called during SCSI Host Adapter detection which modifies the state
                   2322:   of the Host Adapter from its initial power on or hard reset state.
                   2323: */
                   2324: 
                   2325: static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T
                   2326:                                              *HostAdapter)
                   2327: {
                   2328:   BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
                   2329:   BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
                   2330:   BusLogic_SetCCBFormatRequest_T SetCCBFormatRequest;
                   2331:   int TargetID;
                   2332:   /*
                   2333:     Initialize the pointers to the first and last CCBs that are queued for
                   2334:     completion processing.
                   2335:   */
                   2336:   HostAdapter->FirstCompletedCCB = NULL;
                   2337:   HostAdapter->LastCompletedCCB = NULL;
                   2338:   /*
                   2339:     Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
                   2340:     Command Successful Flag, Active Commands, and Commands Since Reset
                   2341:     for each Target Device.
                   2342:   */
                   2343:   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2344:     {
                   2345:       HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
                   2346:       HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
                   2347:       HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
                   2348:       HostAdapter->ActiveCommands[TargetID] = 0;
                   2349:       HostAdapter->CommandsSinceReset[TargetID] = 0;
                   2350:     }
                   2351:   /*
                   2352:     FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
                   2353:   */
                   2354:   if (BusLogic_FlashPointHostAdapterP(HostAdapter)) goto Done;
                   2355:   /*
                   2356:     Initialize the Outgoing and Incoming Mailbox pointers.
                   2357:   */
                   2358:   HostAdapter->FirstOutgoingMailbox =
                   2359:     (BusLogic_OutgoingMailbox_T *) HostAdapter->MailboxSpace;
                   2360:   HostAdapter->LastOutgoingMailbox =
                   2361:     HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
                   2362:   HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
                   2363:   HostAdapter->FirstIncomingMailbox =
                   2364:     (BusLogic_IncomingMailbox_T *) (HostAdapter->LastOutgoingMailbox + 1);
                   2365:   HostAdapter->LastIncomingMailbox =
                   2366:     HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
                   2367:   HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
                   2368:   /*
                   2369:     Initialize the Outgoing and Incoming Mailbox structures.
                   2370:   */
                   2371:   memset(HostAdapter->FirstOutgoingMailbox, 0,
                   2372:         HostAdapter->MailboxCount * sizeof(BusLogic_OutgoingMailbox_T));
                   2373:   memset(HostAdapter->FirstIncomingMailbox, 0,
                   2374:         HostAdapter->MailboxCount * sizeof(BusLogic_IncomingMailbox_T));
                   2375:   /*
                   2376:     Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
                   2377:   */
                   2378:   ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
                   2379:   ExtendedMailboxRequest.BaseMailboxAddress =
                   2380:     Virtual_to_Bus(HostAdapter->FirstOutgoingMailbox);
                   2381:   if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox,
                   2382:                       &ExtendedMailboxRequest,
                   2383:                       sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
                   2384:     return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
                   2385:   /*
                   2386:     Enable Strict Round Robin Mode if supported by the Host Adapter.  In
                   2387:     Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
                   2388:     Mailbox for each new command, rather than scanning through all the
                   2389:     Outgoing Mailboxes to find any that have new commands in them.  Strict
                   2390:     Round Robin Mode is significantly more efficient.
                   2391:   */
                   2392:   if (HostAdapter->StrictRoundRobinModeSupport)
                   2393:     {
                   2394:       RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
                   2395:       if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
                   2396:                           &RoundRobinModeRequest,
                   2397:                           sizeof(RoundRobinModeRequest), NULL, 0) < 0)
                   2398:        return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
                   2399:     }
                   2400:   /*
                   2401:     For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB
                   2402:     Format command to allow 32 Logical Units per Target Device.
                   2403:   */
                   2404:   if (HostAdapter->ExtendedLUNSupport)
                   2405:     {
                   2406:       SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
                   2407:       if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat,
                   2408:                           &SetCCBFormatRequest, sizeof(SetCCBFormatRequest),
                   2409:                           NULL, 0) < 0)
                   2410:        return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
                   2411:     }
                   2412:   /*
                   2413:     Announce Successful Initialization.
                   2414:   */
                   2415: Done:
                   2416:   if (!HostAdapter->HostAdapterInitialized)
                   2417:     {
                   2418:       BusLogic_Info("*** %s Initialized Successfully ***\n",
                   2419:                    HostAdapter, HostAdapter->FullModelName);
                   2420:       BusLogic_Info("\n", HostAdapter);
                   2421:     }
                   2422:   else BusLogic_Warning("*** %s Initialized Successfully ***\n",
                   2423:                        HostAdapter, HostAdapter->FullModelName);
                   2424:   HostAdapter->HostAdapterInitialized = true;
                   2425:   /*
                   2426:     Indicate the Host Adapter Initialization completed successfully.
                   2427:   */
                   2428:   return true;
                   2429: }
                   2430: 
                   2431: 
                   2432: /*
                   2433:   BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
                   2434:   through Host Adapter.
                   2435: */
                   2436: 
                   2437: static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T
                   2438:                                            *HostAdapter)
                   2439: {
                   2440:   BusLogic_InstalledDevices_T InstalledDevices;
                   2441:   BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
                   2442:   BusLogic_SetupInformation_T SetupInformation;
                   2443:   BusLogic_SynchronousPeriod_T SynchronousPeriod;
                   2444:   BusLogic_RequestedReplyLength_T RequestedReplyLength;
                   2445:   int TargetID;
                   2446:   /*
                   2447:     Wait a few seconds between the Host Adapter Hard Reset which initiates
                   2448:     a SCSI Bus Reset and issuing any SCSI Commands.  Some SCSI devices get
                   2449:     confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
                   2450:   */
                   2451:   BusLogic_Delay(HostAdapter->BusSettleTime);
                   2452:   /*
                   2453:     FlashPoint Host Adapters do not provide for Target Device Inquiry.
                   2454:   */
                   2455:   if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
                   2456:   /*
                   2457:     Inhibit the Target Device Inquiry if requested.
                   2458:   */
                   2459:   if (HostAdapter->DriverOptions != NULL &&
                   2460:       HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
                   2461:     return true;
                   2462:   /*
                   2463:     Issue the Inquire Target Devices command for host adapters with firmware
                   2464:     version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
                   2465:     for older host adapters.  This is necessary to force Synchronous Transfer
                   2466:     Negotiation so that the Inquire Setup Information and Inquire Synchronous
                   2467:     Period commands will return valid data.  The Inquire Target Devices command
                   2468:     is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
                   2469:     Logical Unit 0 of each Target Device.
                   2470:   */
                   2471:   if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0)
                   2472:     {
                   2473:       if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0,
                   2474:                           &InstalledDevices, sizeof(InstalledDevices))
                   2475:          != sizeof(InstalledDevices))
                   2476:        return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
                   2477:       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2478:        HostAdapter->TargetFlags[TargetID].TargetExists =
                   2479:          (InstalledDevices & (1 << TargetID) ? true : false);
                   2480:     }
                   2481:   else
                   2482:     {
                   2483:       if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7,
                   2484:                           NULL, 0, &InstalledDevicesID0to7,
                   2485:                           sizeof(InstalledDevicesID0to7))
                   2486:          != sizeof(InstalledDevicesID0to7))
                   2487:        return BusLogic_Failure(HostAdapter,
                   2488:                                "INQUIRE INSTALLED DEVICES ID 0 TO 7");
                   2489:       for (TargetID = 0; TargetID < 8; TargetID++)
                   2490:        HostAdapter->TargetFlags[TargetID].TargetExists =
                   2491:          (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
                   2492:     }
                   2493:   /*
                   2494:     Issue the Inquire Setup Information command.
                   2495:   */
                   2496:   RequestedReplyLength = sizeof(SetupInformation);
                   2497:   if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
                   2498:                       &RequestedReplyLength, sizeof(RequestedReplyLength),
                   2499:                       &SetupInformation, sizeof(SetupInformation))
                   2500:       != sizeof(SetupInformation))
                   2501:     return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
                   2502:   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2503:       HostAdapter->SynchronousOffset[TargetID] =
                   2504:        (TargetID < 8
                   2505:         ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset
                   2506:         : SetupInformation.SynchronousValuesID8to15[TargetID-8].Offset);
                   2507:   if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0)
                   2508:     for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2509:       HostAdapter->TargetFlags[TargetID].WideTransfersActive =
                   2510:        (TargetID < 8
                   2511:         ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
                   2512:            ? true : false)
                   2513:         : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID-8))
                   2514:            ? true : false));
                   2515:   /*
                   2516:     Issue the Inquire Synchronous Period command.
                   2517:   */
                   2518:   if (HostAdapter->FirmwareVersion[0] >= '3')
                   2519:     {
                   2520:       RequestedReplyLength = sizeof(SynchronousPeriod);
                   2521:       if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod,
                   2522:                           &RequestedReplyLength, sizeof(RequestedReplyLength),
                   2523:                           &SynchronousPeriod, sizeof(SynchronousPeriod))
                   2524:          != sizeof(SynchronousPeriod))
                   2525:        return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
                   2526:       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2527:        HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
                   2528:     }
                   2529:   else
                   2530:     for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2531:       if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
                   2532:        HostAdapter->SynchronousPeriod[TargetID] =
                   2533:          20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
                   2534:                                   .TransferPeriod;
                   2535:   /*
                   2536:     Indicate the Target Device Inquiry completed successfully.
                   2537:   */
                   2538:   return true;
                   2539: }
                   2540: 
                   2541: 
                   2542: /*
                   2543:   BusLogic_ReportTargetDeviceInfo reports about the Target Devices accessible
                   2544:   through Host Adapter.
                   2545: */
                   2546: 
                   2547: static void BusLogic_ReportTargetDeviceInfo(BusLogic_HostAdapter_T
                   2548:                                            *HostAdapter)
                   2549: {
                   2550:   int TargetID;
                   2551:   /*
                   2552:     Inhibit the Target Device Inquiry and Reporting if requested.
                   2553:   */
                   2554:   if (BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
                   2555:       HostAdapter->DriverOptions != NULL &&
                   2556:       HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
                   2557:     return;
                   2558:   /*
                   2559:     Report on the Target Devices found.
                   2560:   */
                   2561:   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2562:     {
                   2563:       BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
                   2564:       if (TargetFlags->TargetExists && !TargetFlags->TargetInfoReported)
                   2565:        {
                   2566:          int SynchronousTransferRate = 0;
                   2567:          if (BusLogic_FlashPointHostAdapterP(HostAdapter))
                   2568:            {
                   2569:              boolean WideTransfersActive;
                   2570:              FlashPoint_InquireTargetInfo(
                   2571:                HostAdapter->CardHandle, TargetID,
                   2572:                &HostAdapter->SynchronousPeriod[TargetID],
                   2573:                &HostAdapter->SynchronousOffset[TargetID],
                   2574:                &WideTransfersActive);
                   2575:              TargetFlags->WideTransfersActive = WideTransfersActive;
                   2576:            }
                   2577:          else if (TargetFlags->WideTransfersSupported &&
                   2578:                   (HostAdapter->WidePermitted & (1 << TargetID)) &&
                   2579:                   strcmp(HostAdapter->FirmwareVersion, "5.06L") < 0)
                   2580:            TargetFlags->WideTransfersActive = true;
                   2581:          if (HostAdapter->SynchronousPeriod[TargetID] > 0)
                   2582:            SynchronousTransferRate =
                   2583:              100000 / HostAdapter->SynchronousPeriod[TargetID];
                   2584:          if (TargetFlags->WideTransfersActive)
                   2585:            SynchronousTransferRate <<= 1;
                   2586:          if (SynchronousTransferRate >= 9950)
                   2587:            {
                   2588:              SynchronousTransferRate = (SynchronousTransferRate + 50) / 100;
                   2589:              BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
                   2590:                            "%d.%01d MB/sec, offset %d\n",
                   2591:                            HostAdapter, TargetID,
                   2592:                            HostAdapter->QueueDepth[TargetID],
                   2593:                            (TargetFlags->WideTransfersActive ? "Wide " : ""),
                   2594:                            SynchronousTransferRate / 10,
                   2595:                            SynchronousTransferRate % 10,
                   2596:                            HostAdapter->SynchronousOffset[TargetID]);
                   2597:            }
                   2598:          else if (SynchronousTransferRate > 0)
                   2599:            {
                   2600:              SynchronousTransferRate = (SynchronousTransferRate + 5) / 10;
                   2601:              BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
                   2602:                            "%d.%02d MB/sec, offset %d\n",
                   2603:                            HostAdapter, TargetID,
                   2604:                            HostAdapter->QueueDepth[TargetID],
                   2605:                            (TargetFlags->WideTransfersActive ? "Wide " : ""),
                   2606:                            SynchronousTransferRate / 100,
                   2607:                            SynchronousTransferRate % 100,
                   2608:                            HostAdapter->SynchronousOffset[TargetID]);
                   2609:            }
                   2610:          else BusLogic_Info("Target %d: Queue Depth %d, Asynchronous\n",
                   2611:                             HostAdapter, TargetID,
                   2612:                             HostAdapter->QueueDepth[TargetID]);
                   2613:          TargetFlags->TargetInfoReported = true;
                   2614:        }
                   2615:     }
                   2616: }
                   2617: 
                   2618: 
                   2619: /*
                   2620:   BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
                   2621:   structure.  The base, io_port, n_io_ports, irq, and dma_channel fields in the
                   2622:   SCSI Host structure are intentionally left uninitialized, as this driver
                   2623:   handles acquisition and release of these resources explicitly, as well as
                   2624:   ensuring exclusive access to the Host Adapter hardware and data structures
                   2625:   through explicit acquisition and release of the Host Adapter's Lock.
                   2626: */
                   2627: 
                   2628: static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T
                   2629:                                               *HostAdapter,
                   2630:                                             SCSI_Host_T *Host)
                   2631: {
                   2632:   Host->max_id = HostAdapter->MaxTargetDevices;
                   2633:   Host->max_lun = HostAdapter->MaxLogicalUnits;
                   2634:   Host->max_channel = 0;
                   2635:   Host->unique_id = HostAdapter->IO_Address;
                   2636:   Host->this_id = HostAdapter->SCSI_ID;
                   2637:   Host->can_queue = HostAdapter->DriverQueueDepth;
                   2638:   Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
                   2639:   Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
                   2640:   Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
                   2641: }
                   2642: 
                   2643: 
                   2644: /*
                   2645:   BusLogic_SelectQueueDepths selects Queue Depths for each Target Device based
                   2646:   on the Host Adapter's Total Queue Depth and the number, type, speed, and
                   2647:   capabilities of the Target Devices.  When called for the last Host Adapter,
                   2648:   it reports on the Target Device Information for all BusLogic Host Adapters
                   2649:   since all the Target Devices have now been probed.
                   2650: */
                   2651: 
                   2652: static void BusLogic_SelectQueueDepths(SCSI_Host_T *Host,
                   2653:                                       SCSI_Device_T *DeviceList)
                   2654: {
                   2655:   BusLogic_HostAdapter_T *HostAdapter =
                   2656:     (BusLogic_HostAdapter_T *) Host->hostdata;
                   2657:   int TaggedDeviceCount = 0, AutomaticTaggedDeviceCount = 0;
                   2658:   int UntaggedDeviceCount = 0, AutomaticTaggedQueueDepth = 0;
                   2659:   int AllocatedQueueDepth = 0;
                   2660:   SCSI_Device_T *Device;
                   2661:   int TargetID;
                   2662:   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2663:     if (HostAdapter->TargetFlags[TargetID].TargetExists)
                   2664:       {
                   2665:        int QueueDepth = HostAdapter->QueueDepth[TargetID];
                   2666:        if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported &&
                   2667:            (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
                   2668:          {
                   2669:            TaggedDeviceCount++;
                   2670:            if (QueueDepth == 0) AutomaticTaggedDeviceCount++;
                   2671:          }
                   2672:        else
                   2673:          {
                   2674:            UntaggedDeviceCount++;
                   2675:            if (QueueDepth == 0 ||
                   2676:                QueueDepth > HostAdapter->UntaggedQueueDepth)
                   2677:              {
                   2678:                QueueDepth = HostAdapter->UntaggedQueueDepth;
                   2679:                HostAdapter->QueueDepth[TargetID] = QueueDepth;
                   2680:              }
                   2681:          }
                   2682:        AllocatedQueueDepth += QueueDepth;
                   2683:        if (QueueDepth == 1)
                   2684:          HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
                   2685:       }
                   2686:   HostAdapter->TargetDeviceCount = TaggedDeviceCount + UntaggedDeviceCount;
                   2687:   if (AutomaticTaggedDeviceCount > 0)
                   2688:     {
                   2689:       AutomaticTaggedQueueDepth =
                   2690:        (HostAdapter->HostAdapterQueueDepth - AllocatedQueueDepth)
                   2691:        / AutomaticTaggedDeviceCount;
                   2692:       if (AutomaticTaggedQueueDepth > BusLogic_MaxAutomaticTaggedQueueDepth)
                   2693:        AutomaticTaggedQueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
                   2694:       if (AutomaticTaggedQueueDepth < BusLogic_MinAutomaticTaggedQueueDepth)
                   2695:        AutomaticTaggedQueueDepth = BusLogic_MinAutomaticTaggedQueueDepth;
                   2696:       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   2697:        if (HostAdapter->TargetFlags[TargetID].TargetExists &&
                   2698:            HostAdapter->QueueDepth[TargetID] == 0)
                   2699:          {
                   2700:            AllocatedQueueDepth += AutomaticTaggedQueueDepth;
                   2701:            HostAdapter->QueueDepth[TargetID] = AutomaticTaggedQueueDepth;
                   2702:          }
                   2703:     }
                   2704:   for (Device = DeviceList; Device != NULL; Device = Device->next)
                   2705:     if (Device->host == Host)
                   2706:       Device->queue_depth = HostAdapter->QueueDepth[Device->id];
                   2707:   /* Allocate an extra CCB for each Target Device for a Bus Device Reset. */
                   2708:   AllocatedQueueDepth += HostAdapter->TargetDeviceCount;
                   2709:   if (AllocatedQueueDepth > HostAdapter->DriverQueueDepth)
                   2710:     AllocatedQueueDepth = HostAdapter->DriverQueueDepth;
                   2711:   BusLogic_CreateAdditionalCCBs(HostAdapter,
                   2712:                                AllocatedQueueDepth
                   2713:                                - HostAdapter->AllocatedCCBs,
                   2714:                                false);
                   2715:   if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
                   2716:     for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
                   2717:         HostAdapter != NULL;
                   2718:         HostAdapter = HostAdapter->Next)
                   2719:       BusLogic_ReportTargetDeviceInfo(HostAdapter);
                   2720: }
                   2721: 
                   2722: 
                   2723: /*
                   2724:   BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
                   2725:   I/O Addresses where they may be located, initializing, registering, and
                   2726:   reporting the configuration of each BusLogic Host Adapter it finds.  It
                   2727:   returns the number of BusLogic Host Adapters successfully initialized and
                   2728:   registered.
                   2729: */
                   2730: 
                   2731: int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)
                   2732: {
                   2733:   int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
                   2734:   BusLogic_HostAdapter_T *PrototypeHostAdapter;
                   2735:   if (BusLogic_ProbeOptions.NoProbe) return 0;
                   2736:   BusLogic_ProbeInfoList = (BusLogic_ProbeInfo_T *)
                   2737:     kmalloc(BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T),
                   2738:            GFP_ATOMIC);
                   2739:   if (BusLogic_ProbeInfoList == NULL)
                   2740:     {
                   2741:       BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
                   2742:       return 0;
                   2743:     }
                   2744:   memset(BusLogic_ProbeInfoList, 0,
                   2745:         BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T));
                   2746:   PrototypeHostAdapter = (BusLogic_HostAdapter_T *)
                   2747:     kmalloc(sizeof(BusLogic_HostAdapter_T), GFP_ATOMIC);
                   2748:   if (PrototypeHostAdapter == NULL)
                   2749:     {
                   2750:       kfree(BusLogic_ProbeInfoList);
                   2751:       BusLogic_Error("BusLogic: Unable to allocate Prototype "
                   2752:                     "Host Adapter\n", NULL);
                   2753:       return 0;
                   2754:     }
                   2755:   memset(PrototypeHostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
                   2756:   if (BusLogic_Options != NULL)
                   2757:     BusLogic_ParseDriverOptions(BusLogic_Options);
                   2758:   BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
                   2759:   for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++)
                   2760:     {
                   2761:       BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
                   2762:       BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
                   2763:       SCSI_Host_T *Host;
                   2764:       if (ProbeInfo->IO_Address == 0) continue;
                   2765:       memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
                   2766:       HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
                   2767:       HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
                   2768:       HostAdapter->IO_Address = ProbeInfo->IO_Address;
                   2769:       HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
                   2770:       HostAdapter->Bus = ProbeInfo->Bus;
                   2771:       HostAdapter->Device = ProbeInfo->Device;
                   2772:       HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
                   2773:       HostAdapter->AddressCount =
                   2774:        BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
                   2775:       /*
                   2776:        Probe the Host Adapter.  If unsuccessful, abort further initialization.
                   2777:       */
                   2778:       if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
                   2779:       /*
                   2780:        Hard Reset the Host Adapter.  If unsuccessful, abort further
                   2781:        initialization.
                   2782:       */
                   2783:       if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) continue;
                   2784:       /*
                   2785:        Check the Host Adapter.  If unsuccessful, abort further initialization.
                   2786:       */
                   2787:       if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
                   2788:       /*
                   2789:        Initialize the Driver Options field if provided.
                   2790:       */
                   2791:       if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
                   2792:        HostAdapter->DriverOptions =
                   2793:          &BusLogic_DriverOptions[DriverOptionsIndex++];
                   2794:       /*
                   2795:        Announce the Driver Version and Date, Author's Name, Copyright Notice,
                   2796:        and Electronic Mail Address.
                   2797:       */
                   2798:       BusLogic_AnnounceDriver(HostAdapter);
                   2799:       /*
                   2800:        Register usage of the I/O Address range.  From this point onward, any
                   2801:        failure will be assumed to be due to a problem with the Host Adapter,
                   2802:        rather than due to having mistakenly identified this port as belonging
                   2803:        to a BusLogic Host Adapter.  The I/O Address range will not be
                   2804:        released, thereby preventing it from being incorrectly identified as
                   2805:        any other type of Host Adapter.
                   2806:       */
                   2807:       request_region(HostAdapter->IO_Address, HostAdapter->AddressCount,
                   2808:                     "BusLogic");
                   2809:       /*
                   2810:        Register the SCSI Host structure.
                   2811:       */
                   2812:       Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T));
                   2813:       HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata;
                   2814:       memcpy(HostAdapter, PrototypeHostAdapter, sizeof(BusLogic_HostAdapter_T));
                   2815:       HostAdapter->SCSI_Host = Host;
                   2816:       HostAdapter->HostNumber = Host->host_no;
                   2817:       Host->select_queue_depths = BusLogic_SelectQueueDepths;
                   2818:       /*
                   2819:        Add Host Adapter to the end of the list of registered BusLogic
                   2820:        Host Adapters.
                   2821:       */
                   2822:       BusLogic_RegisterHostAdapter(HostAdapter);
                   2823:       /*
                   2824:        Read the Host Adapter Configuration, Configure the Host Adapter,
                   2825:        Acquire the System Resources necessary to use the Host Adapter, then
                   2826:        Create the Initial CCBs, Initialize the Host Adapter, and finally
                   2827:        perform Target Device Inquiry.
                   2828:       */
                   2829:       if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
                   2830:          BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
                   2831:          BusLogic_AcquireResources(HostAdapter) &&
                   2832:          BusLogic_CreateInitialCCBs(HostAdapter) &&
                   2833:          BusLogic_InitializeHostAdapter(HostAdapter) &&
                   2834:          BusLogic_TargetDeviceInquiry(HostAdapter))
                   2835:        {
                   2836:          /*
                   2837:            Initialization has been completed successfully.  Release and
                   2838:            re-register usage of the I/O Address range so that the Model
                   2839:            Name of the Host Adapter will appear, and initialize the SCSI
                   2840:            Host structure.
                   2841:          */
                   2842:          release_region(HostAdapter->IO_Address,
                   2843:                         HostAdapter->AddressCount);
                   2844:          request_region(HostAdapter->IO_Address,
                   2845:                         HostAdapter->AddressCount,
                   2846:                         HostAdapter->FullModelName);
                   2847:          BusLogic_InitializeHostStructure(HostAdapter, Host);
                   2848:          BusLogicHostAdapterCount++;
                   2849:        }
                   2850:       else
                   2851:        {
                   2852:          /*
                   2853:            An error occurred during Host Adapter Configuration Querying, Host
                   2854:            Adapter Configuration, Resource Acquisition, CCB Creation, Host
                   2855:            Adapter Initialization, or Target Device Inquiry, so remove Host
                   2856:            Adapter from the list of registered BusLogic Host Adapters, destroy
                   2857:            the CCBs, Release the System Resources, and Unregister the SCSI
                   2858:            Host.
                   2859:          */
                   2860:          BusLogic_DestroyCCBs(HostAdapter);
                   2861:          BusLogic_ReleaseResources(HostAdapter);
                   2862:          BusLogic_UnregisterHostAdapter(HostAdapter);
                   2863:          scsi_unregister(Host);
                   2864:        }
                   2865:     }
                   2866:   kfree(PrototypeHostAdapter);
                   2867:   kfree(BusLogic_ProbeInfoList);
                   2868:   BusLogic_ProbeInfoList = NULL;
                   2869:   return BusLogicHostAdapterCount;
                   2870: }
                   2871: 
                   2872: 
                   2873: /*
                   2874:   BusLogic_ReleaseHostAdapter releases all resources previously acquired to
                   2875:   support a specific Host Adapter, including the I/O Address range, and
                   2876:   unregisters the BusLogic Host Adapter.
                   2877: */
                   2878: 
                   2879: int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host)
                   2880: {
                   2881:   BusLogic_HostAdapter_T *HostAdapter =
                   2882:     (BusLogic_HostAdapter_T *) Host->hostdata;
                   2883:   /*
                   2884:     FlashPoint Host Adapters must first be released by the FlashPoint
                   2885:     SCCB Manager.
                   2886:   */
                   2887:   if (BusLogic_FlashPointHostAdapterP(HostAdapter))
                   2888:     FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
                   2889:   /*
                   2890:     Destroy the CCBs and release any system resources acquired to
                   2891:     support Host Adapter.
                   2892:   */
                   2893:   BusLogic_DestroyCCBs(HostAdapter);
                   2894:   BusLogic_ReleaseResources(HostAdapter);
                   2895:   /*
                   2896:     Release usage of the I/O Address range.
                   2897:   */
                   2898:   release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
                   2899:   /*
                   2900:     Remove Host Adapter from the list of registered BusLogic Host Adapters.
                   2901:   */
                   2902:   BusLogic_UnregisterHostAdapter(HostAdapter);
                   2903:   return 0;
                   2904: }
                   2905: 
                   2906: 
                   2907: /*
                   2908:   BusLogic_QueueCompletedCCB queues CCB for completion processing.
                   2909: */
                   2910: 
                   2911: static void BusLogic_QueueCompletedCCB(BusLogic_CCB_T *CCB)
                   2912: {
                   2913:   BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
                   2914:   CCB->Status = BusLogic_CCB_Completed;
                   2915:   CCB->Next = NULL;
                   2916:   if (HostAdapter->FirstCompletedCCB == NULL)
                   2917:     {
                   2918:       HostAdapter->FirstCompletedCCB = CCB;
                   2919:       HostAdapter->LastCompletedCCB = CCB;
                   2920:     }
                   2921:   else
                   2922:     {
                   2923:       HostAdapter->LastCompletedCCB->Next = CCB;
                   2924:       HostAdapter->LastCompletedCCB = CCB;
                   2925:     }
                   2926:   HostAdapter->ActiveCommands[CCB->TargetID]--;
                   2927: }
                   2928: 
                   2929: 
                   2930: /*
                   2931:   BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
                   2932:   the Host Adapter Status and Target Device Status.
                   2933: */
                   2934: 
                   2935: static int BusLogic_ComputeResultCode(BusLogic_HostAdapter_T *HostAdapter,
                   2936:                                      BusLogic_HostAdapterStatus_T
                   2937:                                        HostAdapterStatus,
                   2938:                                      BusLogic_TargetDeviceStatus_T
                   2939:                                        TargetDeviceStatus)
                   2940: {
                   2941:   int HostStatus;
                   2942:   switch (HostAdapterStatus)
                   2943:     {
                   2944:     case BusLogic_CommandCompletedNormally:
                   2945:     case BusLogic_LinkedCommandCompleted:
                   2946:     case BusLogic_LinkedCommandCompletedWithFlag:
                   2947:       HostStatus = DID_OK;
                   2948:       break;
                   2949:     case BusLogic_SCSISelectionTimeout:
                   2950:       HostStatus = DID_TIME_OUT;
                   2951:       break;
                   2952:     case BusLogic_InvalidOutgoingMailboxActionCode:
                   2953:     case BusLogic_InvalidCommandOperationCode:
                   2954:     case BusLogic_InvalidCommandParameter:
                   2955:       BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n",
                   2956:                       HostAdapter, HostAdapterStatus);
                   2957:     case BusLogic_DataUnderRun:
                   2958:     case BusLogic_DataOverRun:
                   2959:     case BusLogic_UnexpectedBusFree:
                   2960:     case BusLogic_LinkedCCBhasInvalidLUN:
                   2961:     case BusLogic_AutoRequestSenseFailed:
                   2962:     case BusLogic_TaggedQueuingMessageRejected:
                   2963:     case BusLogic_UnsupportedMessageReceived:
                   2964:     case BusLogic_HostAdapterHardwareFailed:
                   2965:     case BusLogic_TargetDeviceReconnectedImproperly:
                   2966:     case BusLogic_AbortQueueGenerated:
                   2967:     case BusLogic_HostAdapterSoftwareError:
                   2968:     case BusLogic_HostAdapterHardwareTimeoutError:
                   2969:     case BusLogic_SCSIParityErrorDetected:
                   2970:       HostStatus = DID_ERROR;
                   2971:       break;
                   2972:     case BusLogic_InvalidBusPhaseRequested:
                   2973:     case BusLogic_TargetFailedResponseToATN:
                   2974:     case BusLogic_HostAdapterAssertedRST:
                   2975:     case BusLogic_OtherDeviceAssertedRST:
                   2976:     case BusLogic_HostAdapterAssertedBusDeviceReset:
                   2977:       HostStatus = DID_RESET;
                   2978:       break;
                   2979:     default:
                   2980:       BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n",
                   2981:                       HostAdapter, HostAdapterStatus);
                   2982:       HostStatus = DID_ERROR;
                   2983:       break;
                   2984:     }
                   2985:   return (HostStatus << 16) | TargetDeviceStatus;
                   2986: }
                   2987: 
                   2988: 
                   2989: /*
                   2990:   BusLogic_ScanIncomingMailboxes scans the Incoming Mailboxes saving any
                   2991:   Incoming Mailbox entries for completion processing.
                   2992: */
                   2993: 
                   2994: static void BusLogic_ScanIncomingMailboxes(BusLogic_HostAdapter_T *HostAdapter)
                   2995: {
                   2996:   /*
                   2997:     Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving
                   2998:     any completed CCBs for further processing.  It is essential that for each
                   2999:     CCB and SCSI Command issued, command completion processing is performed
                   3000:     exactly once.  Therefore, only Incoming Mailboxes with completion code
                   3001:     Command Completed Without Error, Command Completed With Error, or Command
                   3002:     Aborted At Host Request are saved for completion processing.  When an
                   3003:     Incoming Mailbox has a completion code of Aborted Command Not Found, the
                   3004:     CCB had already completed or been aborted before the current Abort request
                   3005:     was processed, and so completion processing has already occurred and no
                   3006:     further action should be taken.
                   3007:   */
                   3008:   BusLogic_IncomingMailbox_T *NextIncomingMailbox =
                   3009:     HostAdapter->NextIncomingMailbox;
                   3010:   BusLogic_CompletionCode_T CompletionCode;
                   3011:   while ((CompletionCode = NextIncomingMailbox->CompletionCode) !=
                   3012:         BusLogic_IncomingMailboxFree)
                   3013:     {
                   3014:       BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
                   3015:        Bus_to_Virtual(NextIncomingMailbox->CCB);
                   3016:       if (CompletionCode != BusLogic_AbortedCommandNotFound)
                   3017:        {
                   3018:          if (CCB->Status == BusLogic_CCB_Active ||
                   3019:              CCB->Status == BusLogic_CCB_Reset)
                   3020:            {
                   3021:              /*
                   3022:                Save the Completion Code for this CCB and queue the CCB
                   3023:                for completion processing.
                   3024:              */
                   3025:              CCB->CompletionCode = CompletionCode;
                   3026:              BusLogic_QueueCompletedCCB(CCB);
                   3027:            }
                   3028:          else
                   3029:            {
                   3030:              /*
                   3031:                If a CCB ever appears in an Incoming Mailbox and is not marked
                   3032:                as status Active or Reset, then there is most likely a bug in
                   3033:                the Host Adapter firmware.
                   3034:              */
                   3035:              BusLogic_Warning("Illegal CCB #%ld status %d in "
                   3036:                               "Incoming Mailbox\n", HostAdapter,
                   3037:                               CCB->SerialNumber, CCB->Status);
                   3038:            }
                   3039:        }
                   3040:       NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
                   3041:       if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
                   3042:        NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
                   3043:     }
                   3044:   HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
                   3045: }
                   3046: 
                   3047: 
                   3048: /*
                   3049:   BusLogic_ProcessCompletedCCBs iterates over the completed CCBs for Host
                   3050:   Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
                   3051:   calling the SCSI Subsystem Completion Routines.  The Host Adapter's Lock
                   3052:   should already have been acquired by the caller.
                   3053: */
                   3054: 
                   3055: static void BusLogic_ProcessCompletedCCBs(BusLogic_HostAdapter_T *HostAdapter)
                   3056: {
                   3057:   if (HostAdapter->ProcessCompletedCCBsActive) return;
                   3058:   HostAdapter->ProcessCompletedCCBsActive = true;
                   3059:   while (HostAdapter->FirstCompletedCCB != NULL)
                   3060:     {
                   3061:       BusLogic_CCB_T *CCB = HostAdapter->FirstCompletedCCB;
                   3062:       SCSI_Command_T *Command = CCB->Command;
                   3063:       HostAdapter->FirstCompletedCCB = CCB->Next;
                   3064:       if (HostAdapter->FirstCompletedCCB == NULL)
                   3065:        HostAdapter->LastCompletedCCB = NULL;
                   3066:       /*
                   3067:        Process the Completed CCB.
                   3068:       */
                   3069:       if (CCB->Opcode == BusLogic_BusDeviceReset)
                   3070:        {
                   3071:          int TargetID = CCB->TargetID;
                   3072:          BusLogic_Warning("Bus Device Reset CCB #%ld to Target "
                   3073:                           "%d Completed\n", HostAdapter,
                   3074:                           CCB->SerialNumber, TargetID);
                   3075:          BusLogic_IncrementErrorCounter(
                   3076:            &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
                   3077:          HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
                   3078:          HostAdapter->CommandsSinceReset[TargetID] = 0;
                   3079:          HostAdapter->LastResetCompleted[TargetID] = jiffies;
                   3080:          /*
                   3081:            Place CCB back on the Host Adapter's free list.
                   3082:          */
                   3083:          BusLogic_DeallocateCCB(CCB);
                   3084:          /*
                   3085:            Bus Device Reset CCBs have the Command field non-NULL only when a
                   3086:            Bus Device Reset was requested for a Command that did not have a
                   3087:            currently active CCB in the Host Adapter (i.e., a Synchronous
                   3088:            Bus Device Reset), and hence would not have its Completion Routine
                   3089:            called otherwise.
                   3090:          */
                   3091:          while (Command != NULL)
                   3092:            {
                   3093:              SCSI_Command_T *NextCommand = Command->reset_chain;
                   3094:              Command->reset_chain = NULL;
                   3095:              Command->result = DID_RESET << 16;
                   3096:              Command->scsi_done(Command);
                   3097:              Command = NextCommand;
                   3098:            }
                   3099:          /*
                   3100:            Iterate over the CCBs for this Host Adapter performing completion
                   3101:            processing for any CCBs marked as Reset for this Target.
                   3102:          */
                   3103:          for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
                   3104:            if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID)
                   3105:              {
                   3106:                Command = CCB->Command;
                   3107:                BusLogic_DeallocateCCB(CCB);
                   3108:                HostAdapter->ActiveCommands[TargetID]--;
                   3109:                Command->result = DID_RESET << 16;
                   3110:                Command->scsi_done(Command);
                   3111:              }
                   3112:          HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
                   3113:        }
                   3114:       else
                   3115:        {
                   3116:          /*
                   3117:            Translate the Completion Code, Host Adapter Status, and Target
                   3118:            Device Status into a SCSI Subsystem Result Code.
                   3119:          */
                   3120:          switch (CCB->CompletionCode)
                   3121:            {
                   3122:            case BusLogic_IncomingMailboxFree:
                   3123:            case BusLogic_AbortedCommandNotFound:
                   3124:            case BusLogic_InvalidCCB:
                   3125:              BusLogic_Warning("CCB #%ld to Target %d Impossible State\n",
                   3126:                               HostAdapter, CCB->SerialNumber, CCB->TargetID);
                   3127:              break;
                   3128:            case BusLogic_CommandCompletedWithoutError:
                   3129:              HostAdapter->TargetStatistics[CCB->TargetID]
                   3130:                           .CommandsCompleted++;
                   3131:              HostAdapter->TargetFlags[CCB->TargetID]
                   3132:                           .CommandSuccessfulFlag = true;
                   3133:              Command->result = DID_OK << 16;
                   3134:              break;
                   3135:            case BusLogic_CommandAbortedAtHostRequest:
                   3136:              BusLogic_Warning("CCB #%ld to Target %d Aborted\n",
                   3137:                               HostAdapter, CCB->SerialNumber, CCB->TargetID);
                   3138:              BusLogic_IncrementErrorCounter(
                   3139:                &HostAdapter->TargetStatistics[CCB->TargetID]
                   3140:                              .CommandAbortsCompleted);
                   3141:              Command->result = DID_ABORT << 16;
                   3142:              break;
                   3143:            case BusLogic_CommandCompletedWithError:
                   3144:              Command->result =
                   3145:                BusLogic_ComputeResultCode(HostAdapter,
                   3146:                                           CCB->HostAdapterStatus,
                   3147:                                           CCB->TargetDeviceStatus);
                   3148:              if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
                   3149:                {
                   3150:                  HostAdapter->TargetStatistics[CCB->TargetID]
                   3151:                               .CommandsCompleted++;
                   3152:                  if (BusLogic_GlobalOptions.TraceErrors)
                   3153:                    {
                   3154:                      int i;
                   3155:                      BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
                   3156:                                      "Adapter Status %02X "
                   3157:                                      "Target Status %02X\n",
                   3158:                                      HostAdapter, CCB->SerialNumber,
                   3159:                                      CCB->TargetID, Command->result,
                   3160:                                      CCB->HostAdapterStatus,
                   3161:                                      CCB->TargetDeviceStatus);
                   3162:                      BusLogic_Notice("CDB   ", HostAdapter);
                   3163:                      for (i = 0; i < CCB->CDB_Length; i++)
                   3164:                        BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
                   3165:                      BusLogic_Notice("\n", HostAdapter);
                   3166:                      BusLogic_Notice("Sense ", HostAdapter);
                   3167:                      for (i = 0; i < CCB->SenseDataLength; i++)
                   3168:                        BusLogic_Notice(" %02X", HostAdapter,
                   3169:                                        Command->sense_buffer[i]);
                   3170:                      BusLogic_Notice("\n", HostAdapter);
                   3171:                    }
                   3172:                }
                   3173:              break;
                   3174:            }
                   3175:          /*
                   3176:            When an INQUIRY command completes normally, save the
                   3177:            CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
                   3178:            Wide Data Transfers Supported) bits.
                   3179:          */
                   3180:          if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 &&
                   3181:              CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally)
                   3182:            {
                   3183:              BusLogic_TargetFlags_T *TargetFlags =
                   3184:                &HostAdapter->TargetFlags[CCB->TargetID];
                   3185:              SCSI_Inquiry_T *InquiryResult =
                   3186:                (SCSI_Inquiry_T *) Command->request_buffer;
                   3187:              TargetFlags->TargetExists = true;
                   3188:              TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
                   3189:              TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
                   3190:            }
                   3191:          /*
                   3192:            Place CCB back on the Host Adapter's free list.
                   3193:          */
                   3194:          BusLogic_DeallocateCCB(CCB);
                   3195:          /*
                   3196:            Call the SCSI Command Completion Routine.
                   3197:          */
                   3198:          Command->scsi_done(Command);
                   3199:        }
                   3200:     }
                   3201:   HostAdapter->ProcessCompletedCCBsActive = false;
                   3202: }
                   3203: 
                   3204: 
                   3205: /*
                   3206:   BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
                   3207:   Adapters.
                   3208: */
                   3209: 
                   3210: static void BusLogic_InterruptHandler(int IRQ_Channel,
                   3211:                                      void *DeviceIdentifier,
                   3212:                                      Registers_T *InterruptRegisters)
                   3213: {
                   3214:   BusLogic_HostAdapter_T *HostAdapter =
                   3215:     (BusLogic_HostAdapter_T *) DeviceIdentifier;
                   3216:   ProcessorFlags_T ProcessorFlags;
                   3217:   /*
                   3218:     Acquire exclusive access to Host Adapter.
                   3219:   */
                   3220:   BusLogic_AcquireHostAdapterLockIH(HostAdapter, &ProcessorFlags);
                   3221:   /*
                   3222:     Handle Interrupts appropriately for each Host Adapter type.
                   3223:   */
                   3224:   if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
                   3225:     {
                   3226:       BusLogic_InterruptRegister_T InterruptRegister;
                   3227:       /*
                   3228:        Read the Host Adapter Interrupt Register.
                   3229:       */
                   3230:       InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
                   3231:       if (InterruptRegister.Bits.InterruptValid)
                   3232:        {
                   3233:          /*
                   3234:            Acknowledge the interrupt and reset the Host Adapter
                   3235:            Interrupt Register.
                   3236:          */
                   3237:          BusLogic_InterruptReset(HostAdapter);
                   3238:          /*
                   3239:            Process valid External SCSI Bus Reset and Incoming Mailbox
                   3240:            Loaded Interrupts.  Command Complete Interrupts are noted,
                   3241:            and Outgoing Mailbox Available Interrupts are ignored, as
                   3242:            they are never enabled.
                   3243:          */
                   3244:          if (InterruptRegister.Bits.ExternalBusReset)
                   3245:            HostAdapter->HostAdapterExternalReset = true;
                   3246:          else if (InterruptRegister.Bits.IncomingMailboxLoaded)
                   3247:            BusLogic_ScanIncomingMailboxes(HostAdapter);
                   3248:          else if (InterruptRegister.Bits.CommandComplete)
                   3249:            HostAdapter->HostAdapterCommandCompleted = true;
                   3250:        }
                   3251:     }
                   3252:   else
                   3253:     {
                   3254:       /*
                   3255:        Check if there is a pending interrupt for this Host Adapter.
                   3256:       */
                   3257:       if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
                   3258:        switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle))
                   3259:          {
                   3260:          case FlashPoint_NormalInterrupt:
                   3261:            break;
                   3262:          case FlashPoint_ExternalBusReset:
                   3263:            HostAdapter->HostAdapterExternalReset = true;
                   3264:            break;
                   3265:          case FlashPoint_InternalError:
                   3266:            BusLogic_Warning("Internal FlashPoint Error detected"
                   3267:                             " - Resetting Host Adapter\n", HostAdapter);
                   3268:            HostAdapter->HostAdapterInternalError = true;
                   3269:            break;
                   3270:          }
                   3271:     }
                   3272:   /*
                   3273:     Process any completed CCBs.
                   3274:   */
                   3275:   if (HostAdapter->FirstCompletedCCB != NULL)
                   3276:     BusLogic_ProcessCompletedCCBs(HostAdapter);
                   3277:   /*
                   3278:     Reset the Host Adapter if requested.
                   3279:   */
                   3280:   if (HostAdapter->HostAdapterExternalReset ||
                   3281:       HostAdapter->HostAdapterInternalError)
                   3282:     {
                   3283:       BusLogic_ResetHostAdapter(HostAdapter, NULL, 0);
                   3284:       HostAdapter->HostAdapterExternalReset = false;
                   3285:       HostAdapter->HostAdapterInternalError = false;
                   3286:       scsi_mark_host_reset(HostAdapter->SCSI_Host);
                   3287:     }
                   3288:   /*
                   3289:     Release exclusive access to Host Adapter.
                   3290:   */
                   3291:   BusLogic_ReleaseHostAdapterLockIH(HostAdapter, &ProcessorFlags);
                   3292: }
                   3293: 
                   3294: 
                   3295: /*
                   3296:   BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
                   3297:   Mailbox for execution by Host Adapter.  The Host Adapter's Lock should
                   3298:   already have been acquired by the caller.
                   3299: */
                   3300: 
                   3301: static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T
                   3302:                                               *HostAdapter,
                   3303:                                             BusLogic_ActionCode_T ActionCode,
                   3304:                                             BusLogic_CCB_T *CCB)
                   3305: {
                   3306:   BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
                   3307:   NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
                   3308:   if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
                   3309:     {
                   3310:       CCB->Status = BusLogic_CCB_Active;
                   3311:       /*
                   3312:        The CCB field must be written before the Action Code field since
                   3313:        the Host Adapter is operating asynchronously and the locking code
                   3314:        does not protect against simultaneous access by the Host Adapter.
                   3315:       */
                   3316:       NextOutgoingMailbox->CCB = Virtual_to_Bus(CCB);
                   3317:       NextOutgoingMailbox->ActionCode = ActionCode;
                   3318:       BusLogic_StartMailboxCommand(HostAdapter);
                   3319:       if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
                   3320:        NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
                   3321:       HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
                   3322:       if (ActionCode == BusLogic_MailboxStartCommand)
                   3323:        {
                   3324:          HostAdapter->ActiveCommands[CCB->TargetID]++;
                   3325:          if (CCB->Opcode != BusLogic_BusDeviceReset)
                   3326:            HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
                   3327:        }
                   3328:       return true;
                   3329:     }
                   3330:   return false;
                   3331: }
                   3332: 
                   3333: 
                   3334: /*
                   3335:   BusLogic_QueueCommand creates a CCB for Command and places it into an
                   3336:   Outgoing Mailbox for execution by the associated Host Adapter.
                   3337: */
                   3338: 
                   3339: int BusLogic_QueueCommand(SCSI_Command_T *Command,
                   3340:                          void (*CompletionRoutine)(SCSI_Command_T *))
                   3341: {
                   3342:   BusLogic_HostAdapter_T *HostAdapter =
                   3343:     (BusLogic_HostAdapter_T *) Command->host->hostdata;
                   3344:   BusLogic_TargetFlags_T *TargetFlags =
                   3345:     &HostAdapter->TargetFlags[Command->target];
                   3346:   BusLogic_TargetStatistics_T *TargetStatistics =
                   3347:     HostAdapter->TargetStatistics;
                   3348:   unsigned char *CDB = Command->cmnd;
                   3349:   int CDB_Length = Command->cmd_len;
                   3350:   int TargetID = Command->target;
                   3351:   int LogicalUnit = Command->lun;
                   3352:   void *BufferPointer = Command->request_buffer;
                   3353:   int BufferLength = Command->request_bufflen;
                   3354:   int SegmentCount = Command->use_sg;
                   3355:   ProcessorFlags_T ProcessorFlags;
                   3356:   BusLogic_CCB_T *CCB;
                   3357:   /*
                   3358:     SCSI REQUEST_SENSE commands will be executed automatically by the Host
                   3359:     Adapter for any errors, so they should not be executed explicitly unless
                   3360:     the Sense Data is zero indicating that no error occurred.
                   3361:   */
                   3362:   if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
                   3363:     {
                   3364:       Command->result = DID_OK << 16;
                   3365:       CompletionRoutine(Command);
                   3366:       return 0;
                   3367:     }
                   3368:   /*
                   3369:     Acquire exclusive access to Host Adapter.
                   3370:   */
                   3371:   BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
                   3372:   /*
                   3373:     Allocate a CCB from the Host Adapter's free list.  In the unlikely event
                   3374:     that there are none available and memory allocation fails, wait 1 second
                   3375:     and try again.  If that fails, the Host Adapter is probably hung so signal
                   3376:     an error as a Host Adapter Hard Reset should be initiated soon.
                   3377:   */
                   3378:   CCB = BusLogic_AllocateCCB(HostAdapter);
                   3379:   if (CCB == NULL)
                   3380:     {
                   3381:       BusLogic_Delay(1);
                   3382:       CCB = BusLogic_AllocateCCB(HostAdapter);
                   3383:       if (CCB == NULL)
                   3384:        {
                   3385:          Command->result = DID_ERROR << 16;
                   3386:          CompletionRoutine(Command);
                   3387:          goto Done;
                   3388:        }
                   3389:     }
                   3390:   /*
                   3391:     Initialize the fields in the BusLogic Command Control Block (CCB).
                   3392:   */
                   3393:   if (SegmentCount == 0)
                   3394:     {
                   3395:       CCB->Opcode = BusLogic_InitiatorCCB;
                   3396:       CCB->DataLength = BufferLength;
                   3397:       CCB->DataPointer = Virtual_to_Bus(BufferPointer);
                   3398:     }
                   3399:   else
                   3400:     {
                   3401:       SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
                   3402:       int Segment;
                   3403:       CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
                   3404:       CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
                   3405:       if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
                   3406:        CCB->DataPointer = Virtual_to_Bus(CCB->ScatterGatherList);
                   3407:       else CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
                   3408:       for (Segment = 0; Segment < SegmentCount; Segment++)
                   3409:        {
                   3410:          CCB->ScatterGatherList[Segment].SegmentByteCount =
                   3411:            ScatterList[Segment].length;
                   3412:          CCB->ScatterGatherList[Segment].SegmentDataPointer =
                   3413:            Virtual_to_Bus(ScatterList[Segment].address);
                   3414:        }
                   3415:     }
                   3416:   switch (CDB[0])
                   3417:     {
                   3418:     case READ_6:
                   3419:     case READ_10:
                   3420:       CCB->DataDirection = BusLogic_DataInLengthChecked;
                   3421:       TargetStatistics[TargetID].ReadCommands++;
                   3422:       BusLogic_IncrementByteCounter(
                   3423:        &TargetStatistics[TargetID].TotalBytesRead, BufferLength);
                   3424:       BusLogic_IncrementSizeBucket(
                   3425:        TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
                   3426:       break;
                   3427:     case WRITE_6:
                   3428:     case WRITE_10:
                   3429:       CCB->DataDirection = BusLogic_DataOutLengthChecked;
                   3430:       TargetStatistics[TargetID].WriteCommands++;
                   3431:       BusLogic_IncrementByteCounter(
                   3432:        &TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
                   3433:       BusLogic_IncrementSizeBucket(
                   3434:        TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
                   3435:       break;
                   3436:     default:
                   3437:       CCB->DataDirection = BusLogic_UncheckedDataTransfer;
                   3438:       break;
                   3439:     }
                   3440:   CCB->CDB_Length = CDB_Length;
                   3441:   CCB->SenseDataLength = sizeof(Command->sense_buffer);
                   3442:   CCB->HostAdapterStatus = 0;
                   3443:   CCB->TargetDeviceStatus = 0;
                   3444:   CCB->TargetID = TargetID;
                   3445:   CCB->LogicalUnit = LogicalUnit;
                   3446:   CCB->TagEnable = false;
                   3447:   CCB->LegacyTagEnable = false;
                   3448:   /*
                   3449:     BusLogic recommends that after a Reset the first couple of commands that
                   3450:     are sent to a Target Device be sent in a non Tagged Queue fashion so that
                   3451:     the Host Adapter and Target Device can establish Synchronous and Wide
                   3452:     Transfer before Queue Tag messages can interfere with the Synchronous and
                   3453:     Wide Negotiation messages.  By waiting to enable Tagged Queuing until after
                   3454:     the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is
                   3455:     assured that after a Reset any pending commands are requeued before Tagged
                   3456:     Queuing is enabled and that the Tagged Queuing message will not occur while
                   3457:     the partition table is being printed.  In addition, some devices do not
                   3458:     properly handle the transition from non-tagged to tagged commands, so it is
                   3459:     necessary to wait until there are no pending commands for a target device
                   3460:     before queuing tagged commands.
                   3461:   */
                   3462:   if (HostAdapter->CommandsSinceReset[TargetID]++ >=
                   3463:        BusLogic_MaxTaggedQueueDepth &&
                   3464:       !TargetFlags->TaggedQueuingActive &&
                   3465:       HostAdapter->ActiveCommands[TargetID] == 0 &&
                   3466:       TargetFlags->TaggedQueuingSupported &&
                   3467:       (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
                   3468:     {
                   3469:       TargetFlags->TaggedQueuingActive = true;
                   3470:       BusLogic_Notice("Tagged Queuing now active for Target %d\n",
                   3471:                      HostAdapter, TargetID);
                   3472:     }
                   3473:   if (TargetFlags->TaggedQueuingActive)
                   3474:     {
                   3475:       BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
                   3476:       /*
                   3477:        When using Tagged Queuing with Simple Queue Tags, it appears that disk
                   3478:        drive controllers do not guarantee that a queued command will not
                   3479:        remain in a disconnected state indefinitely if commands that read or
                   3480:        write nearer the head position continue to arrive without interruption.
                   3481:        Therefore, for each Target Device this driver keeps track of the last
                   3482:        time either the queue was empty or an Ordered Queue Tag was issued.  If
                   3483:        more than 4 seconds (one fifth of the 20 second disk timeout) have
                   3484:        elapsed since this last sequence point, this command will be issued
                   3485:        with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
                   3486:        the Target Device to complete all previously queued commands before
                   3487:        this command may be executed.
                   3488:       */
                   3489:       if (HostAdapter->ActiveCommands[TargetID] == 0)
                   3490:        HostAdapter->LastSequencePoint[TargetID] = jiffies;
                   3491:       else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 4*HZ)
                   3492:        {
                   3493:          HostAdapter->LastSequencePoint[TargetID] = jiffies;
                   3494:          QueueTag = BusLogic_OrderedQueueTag;
                   3495:        }
                   3496:       if (HostAdapter->ExtendedLUNSupport)
                   3497:        {
                   3498:          CCB->TagEnable = true;
                   3499:          CCB->QueueTag = QueueTag;
                   3500:        }
                   3501:       else
                   3502:        {
                   3503:          CCB->LegacyTagEnable = true;
                   3504:          CCB->LegacyQueueTag = QueueTag;
                   3505:        }
                   3506:     }
                   3507:   memcpy(CCB->CDB, CDB, CDB_Length);
                   3508:   CCB->SenseDataPointer = Virtual_to_Bus(&Command->sense_buffer);
                   3509:   CCB->Command = Command;
                   3510:   Command->scsi_done = CompletionRoutine;
                   3511:   if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
                   3512:     {
                   3513:       /*
                   3514:        Place the CCB in an Outgoing Mailbox.  The higher levels of the SCSI
                   3515:        Subsystem should not attempt to queue more commands than can be placed
                   3516:        in Outgoing Mailboxes, so there should always be one free.  In the
                   3517:        unlikely event that there are none available, wait 1 second and try
                   3518:        again.  If that fails, the Host Adapter is probably hung so signal an
                   3519:        error as a Host Adapter Hard Reset should be initiated soon.
                   3520:       */
                   3521:       if (!BusLogic_WriteOutgoingMailbox(
                   3522:             HostAdapter, BusLogic_MailboxStartCommand, CCB))
                   3523:        {
                   3524:          BusLogic_Warning("Unable to write Outgoing Mailbox - "
                   3525:                           "Pausing for 1 second\n", HostAdapter);
                   3526:          BusLogic_Delay(1);
                   3527:          if (!BusLogic_WriteOutgoingMailbox(
                   3528:                 HostAdapter, BusLogic_MailboxStartCommand, CCB))
                   3529:            {
                   3530:              BusLogic_Warning("Still unable to write Outgoing Mailbox - "
                   3531:                               "Host Adapter Dead?\n", HostAdapter);
                   3532:              BusLogic_DeallocateCCB(CCB);
                   3533:              Command->result = DID_ERROR << 16;
                   3534:              Command->scsi_done(Command);
                   3535:            }
                   3536:        }
                   3537:     }
                   3538:   else
                   3539:     {
                   3540:       /*
                   3541:        Call the FlashPoint SCCB Manager to start execution of the CCB.
                   3542:       */
                   3543:       CCB->Status = BusLogic_CCB_Active;
                   3544:       HostAdapter->ActiveCommands[TargetID]++;
                   3545:       TargetStatistics[TargetID].CommandsAttempted++;
                   3546:       FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
                   3547:       /*
                   3548:        The Command may have already completed and BusLogic_QueueCompletedCCB
                   3549:        been called, or it may still be pending.
                   3550:       */
                   3551:       if (CCB->Status == BusLogic_CCB_Completed)
                   3552:        BusLogic_ProcessCompletedCCBs(HostAdapter);
                   3553:     }
                   3554:   /*
                   3555:     Release exclusive access to Host Adapter.
                   3556:   */
                   3557: Done:
                   3558:   BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
                   3559:   return 0;
                   3560: }
                   3561: 
                   3562: 
                   3563: /*
                   3564:   BusLogic_AbortCommand aborts Command if possible.
                   3565: */
                   3566: 
                   3567: int BusLogic_AbortCommand(SCSI_Command_T *Command)
                   3568: {
                   3569:   BusLogic_HostAdapter_T *HostAdapter =
                   3570:     (BusLogic_HostAdapter_T *) Command->host->hostdata;
                   3571:   int TargetID = Command->target;
                   3572:   ProcessorFlags_T ProcessorFlags;
                   3573:   BusLogic_CCB_T *CCB;
                   3574:   int Result;
                   3575:   BusLogic_IncrementErrorCounter(
                   3576:     &HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
                   3577:   /*
                   3578:     Acquire exclusive access to Host Adapter.
                   3579:   */
                   3580:   BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
                   3581:   /*
                   3582:     If this Command has already completed, then no Abort is necessary.
                   3583:   */
                   3584:   if (Command->serial_number != Command->serial_number_at_timeout)
                   3585:     {
                   3586:       BusLogic_Warning("Unable to Abort Command to Target %d - "
                   3587:                       "Already Completed\n", HostAdapter, TargetID);
                   3588:       Result = SCSI_ABORT_NOT_RUNNING;
                   3589:       goto Done;
                   3590:     }
                   3591:   /*
                   3592:     Attempt to find an Active CCB for this Command.  If no Active CCB for this
                   3593:     Command is found, then no Abort is necessary.
                   3594:   */
                   3595:   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
                   3596:     if (CCB->Command == Command) break;
                   3597:   if (CCB == NULL)
                   3598:     {
                   3599:       BusLogic_Warning("Unable to Abort Command to Target %d - "
                   3600:                       "No CCB Found\n", HostAdapter, TargetID);
                   3601:       Result = SCSI_ABORT_NOT_RUNNING;
                   3602:       goto Done;
                   3603:     }
                   3604:   else if (CCB->Status == BusLogic_CCB_Completed)
                   3605:     {
                   3606:       BusLogic_Warning("Unable to Abort Command to Target %d - "
                   3607:                       "CCB Completed\n", HostAdapter, TargetID);
                   3608:       Result = SCSI_ABORT_NOT_RUNNING;
                   3609:       goto Done;
                   3610:     }
                   3611:   else if (CCB->Status == BusLogic_CCB_Reset)
                   3612:     {
                   3613:       BusLogic_Warning("Unable to Abort Command to Target %d - "
                   3614:                       "CCB Reset\n", HostAdapter, TargetID);
                   3615:       Result = SCSI_ABORT_PENDING;
                   3616:       goto Done;
                   3617:     }
                   3618:   if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
                   3619:     {
                   3620:       /*
                   3621:        Attempt to Abort this CCB.  MultiMaster Firmware versions prior to 5.xx
                   3622:        do not generate Abort Tag messages, but only generate the non-tagged
                   3623:        Abort message.  Since non-tagged commands are not sent by the Host
                   3624:        Adapter until the queue of outstanding tagged commands has completed,
                   3625:        and the Abort message is treated as a non-tagged command, it is
                   3626:        effectively impossible to abort commands when Tagged Queuing is active.
                   3627:        Firmware version 5.xx does generate Abort Tag messages, so it is
                   3628:        possible to abort commands when Tagged Queuing is active.
                   3629:       */
                   3630:       if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
                   3631:          HostAdapter->FirmwareVersion[0] < '5')
                   3632:        {
                   3633:          BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
                   3634:                           "Abort Tag Not Supported\n",
                   3635:                           HostAdapter, CCB->SerialNumber, TargetID);
                   3636:          Result = SCSI_ABORT_SNOOZE;
                   3637:        }
                   3638:       else if (BusLogic_WriteOutgoingMailbox(
                   3639:                 HostAdapter, BusLogic_MailboxAbortCommand, CCB))
                   3640:        {
                   3641:          BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
                   3642:                           HostAdapter, CCB->SerialNumber, TargetID);
                   3643:          BusLogic_IncrementErrorCounter(
                   3644:            &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
                   3645:          Result = SCSI_ABORT_PENDING;
                   3646:        }
                   3647:       else
                   3648:        {
                   3649:          BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
                   3650:                           "No Outgoing Mailboxes\n",
                   3651:                            HostAdapter, CCB->SerialNumber, TargetID);
                   3652:          Result = SCSI_ABORT_BUSY;
                   3653:        }
                   3654:     }
                   3655:   else
                   3656:     {
                   3657:       /*
                   3658:        Call the FlashPoint SCCB Manager to abort execution of the CCB.
                   3659:       */
                   3660:       BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
                   3661:                       HostAdapter, CCB->SerialNumber, TargetID);
                   3662:       BusLogic_IncrementErrorCounter(
                   3663:        &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
                   3664:       FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB);
                   3665:       /*
                   3666:        The Abort may have already been completed and
                   3667:        BusLogic_QueueCompletedCCB been called, or it
                   3668:        may still be pending.
                   3669:       */
                   3670:       Result = SCSI_ABORT_PENDING;
                   3671:       if (CCB->Status == BusLogic_CCB_Completed)
                   3672:        {
                   3673:          BusLogic_ProcessCompletedCCBs(HostAdapter);
                   3674:          Result = SCSI_ABORT_SUCCESS;
                   3675:        }
                   3676:     }
                   3677:   /*
                   3678:     Release exclusive access to Host Adapter.
                   3679:   */
                   3680: Done:
                   3681:   BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
                   3682:   return Result;
                   3683: }
                   3684: 
                   3685: 
                   3686: /*
                   3687:   BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
                   3688:   currently executing SCSI Commands as having been Reset.
                   3689: */
                   3690: 
                   3691: static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
                   3692:                                     SCSI_Command_T *Command,
                   3693:                                     unsigned int ResetFlags)
                   3694: {
                   3695:   ProcessorFlags_T ProcessorFlags;
                   3696:   BusLogic_CCB_T *CCB;
                   3697:   int TargetID, Result;
                   3698:   boolean HardReset;
                   3699:   if (HostAdapter->HostAdapterExternalReset)
                   3700:     {
                   3701:       BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
                   3702:       HardReset = false;
                   3703:     }
                   3704:   else if (HostAdapter->HostAdapterInternalError)
                   3705:     {
                   3706:       BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
                   3707:       HardReset = true;
                   3708:     }
                   3709:   else
                   3710:     {
                   3711:       BusLogic_IncrementErrorCounter(
                   3712:        &HostAdapter->TargetStatistics[Command->target]
                   3713:                      .HostAdapterResetsRequested);
                   3714:       HardReset = true;
                   3715:     }
                   3716:   /*
                   3717:     Acquire exclusive access to Host Adapter.
                   3718:   */
                   3719:   BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
                   3720:   /*
                   3721:     If this is an Asynchronous Reset and this Command has already completed,
                   3722:     then no Reset is necessary.
                   3723:   */
                   3724:   if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
                   3725:     {
                   3726:       TargetID = Command->target;
                   3727:       if (Command->serial_number != Command->serial_number_at_timeout)
                   3728:        {
                   3729:          BusLogic_Warning("Unable to Reset Command to Target %d - "
                   3730:                           "Already Completed or Reset\n",
                   3731:                           HostAdapter, TargetID);
                   3732:          Result = SCSI_RESET_NOT_RUNNING;
                   3733:          goto Done;
                   3734:       }
                   3735:       for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
                   3736:        if (CCB->Command == Command) break;
                   3737:       if (CCB == NULL)
                   3738:        {
                   3739:          BusLogic_Warning("Unable to Reset Command to Target %d - "
                   3740:                           "No CCB Found\n", HostAdapter, TargetID);
                   3741:          Result = SCSI_RESET_NOT_RUNNING;
                   3742:          goto Done;
                   3743:        }
                   3744:       else if (CCB->Status == BusLogic_CCB_Completed)
                   3745:        {
                   3746:          BusLogic_Warning("Unable to Reset Command to Target %d - "
                   3747:                           "CCB Completed\n", HostAdapter, TargetID);
                   3748:          Result = SCSI_RESET_NOT_RUNNING;
                   3749:          goto Done;
                   3750:        }
                   3751:       else if (CCB->Status == BusLogic_CCB_Reset &&
                   3752:               HostAdapter->BusDeviceResetPendingCCB[TargetID] == NULL)
                   3753:        {
                   3754:          BusLogic_Warning("Unable to Reset Command to Target %d - "
                   3755:                           "Reset Pending\n", HostAdapter, TargetID);
                   3756:          Result = SCSI_RESET_PENDING;
                   3757:          goto Done;
                   3758:        }
                   3759:     }
                   3760:   if (Command == NULL)
                   3761:     {
                   3762:       if (HostAdapter->HostAdapterInternalError)
                   3763:        BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n",
                   3764:                         HostAdapter, HostAdapter->FullModelName);
                   3765:       else BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n",
                   3766:                            HostAdapter, HostAdapter->FullModelName);
                   3767:     }
                   3768:   else
                   3769:     {
                   3770:       BusLogic_Warning("Resetting %s due to Target %d\n", HostAdapter,
                   3771:                       HostAdapter->FullModelName, Command->target);
                   3772:       BusLogic_IncrementErrorCounter(
                   3773:        &HostAdapter->TargetStatistics[Command->target]
                   3774:                      .HostAdapterResetsAttempted);
                   3775:     }
                   3776:   /*
                   3777:     Attempt to Reset and Reinitialize the Host Adapter.
                   3778:   */
                   3779:   if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) &&
                   3780:        BusLogic_InitializeHostAdapter(HostAdapter)))
                   3781:     {
                   3782:       BusLogic_Error("Resetting %s Failed\n", HostAdapter,
                   3783:                     HostAdapter->FullModelName);
                   3784:       Result = SCSI_RESET_ERROR;
                   3785:       goto Done;
                   3786:     }
                   3787:   if (Command != NULL)
                   3788:     BusLogic_IncrementErrorCounter(
                   3789:       &HostAdapter->TargetStatistics[Command->target]
                   3790:                    .HostAdapterResetsCompleted);
                   3791:   /*
                   3792:     Mark all currently executing CCBs as having been Reset.
                   3793:   */
                   3794:   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
                   3795:     if (CCB->Status == BusLogic_CCB_Active)
                   3796:       CCB->Status = BusLogic_CCB_Reset;
                   3797:   /*
                   3798:     Wait a few seconds between the Host Adapter Hard Reset which initiates
                   3799:     a SCSI Bus Reset and issuing any SCSI Commands.  Some SCSI devices get
                   3800:     confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
                   3801:     Note that a timer interrupt may occur here, but all active CCBs have
                   3802:     already been marked Reset and so a reentrant call will return Pending.
                   3803:   */
                   3804:   if (HardReset)
                   3805:     BusLogic_Delay(HostAdapter->BusSettleTime);
                   3806:   /*
                   3807:     If this is a Synchronous Reset, perform completion processing for
                   3808:     the Command being Reset.
                   3809:   */
                   3810:   if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
                   3811:     {
                   3812:       Command->result = DID_RESET << 16;
                   3813:       Command->scsi_done(Command);
                   3814:     }
                   3815:   /*
                   3816:     Perform completion processing for all CCBs marked as Reset.
                   3817:   */
                   3818:   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
                   3819:     if (CCB->Status == BusLogic_CCB_Reset)
                   3820:       {
                   3821:        Command = CCB->Command;
                   3822:        BusLogic_DeallocateCCB(CCB);
                   3823:        while (Command != NULL)
                   3824:          {
                   3825:            SCSI_Command_T *NextCommand = Command->reset_chain;
                   3826:            Command->reset_chain = NULL;
                   3827:            Command->result = DID_RESET << 16;
                   3828:            Command->scsi_done(Command);
                   3829:            Command = NextCommand;
                   3830:          }
                   3831:       }
                   3832:   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   3833:     {
                   3834:       HostAdapter->LastResetAttempted[TargetID] = jiffies;
                   3835:       HostAdapter->LastResetCompleted[TargetID] = jiffies;
                   3836:     }
                   3837:   Result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET;
                   3838:   /*
                   3839:     Release exclusive access to Host Adapter.
                   3840:   */
                   3841: Done:
                   3842:   BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
                   3843:   return Result;
                   3844: }
                   3845: 
                   3846: 
                   3847: /*
                   3848:   BusLogic_SendBusDeviceReset sends a Bus Device Reset to the Target
                   3849:   Device associated with Command.
                   3850: */
                   3851: 
                   3852: static int BusLogic_SendBusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
                   3853:                                       SCSI_Command_T *Command,
                   3854:                                       unsigned int ResetFlags)
                   3855: {
                   3856:   int TargetID = Command->target;
                   3857:   BusLogic_CCB_T *CCB, *XCCB;
                   3858:   ProcessorFlags_T ProcessorFlags;
                   3859:   int Result = -1;
                   3860:   BusLogic_IncrementErrorCounter(
                   3861:     &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsRequested);
                   3862:   /*
                   3863:     Acquire exclusive access to Host Adapter.
                   3864:   */
                   3865:   BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
                   3866:   /*
                   3867:     If this is an Asynchronous Reset and this Command has already completed,
                   3868:     then no Reset is necessary.
                   3869:   */
                   3870:   if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
                   3871:     {
                   3872:       if (Command->serial_number != Command->serial_number_at_timeout)
                   3873:        {
                   3874:          BusLogic_Warning("Unable to Reset Command to Target %d - "
                   3875:                           "Already Completed\n", HostAdapter, TargetID);
                   3876:          Result = SCSI_RESET_NOT_RUNNING;
                   3877:          goto Done;
                   3878:        }
                   3879:       for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
                   3880:        if (CCB->Command == Command) break;
                   3881:       if (CCB == NULL)
                   3882:        {
                   3883:          BusLogic_Warning("Unable to Reset Command to Target %d - "
                   3884:                           "No CCB Found\n", HostAdapter, TargetID);
                   3885:          Result = SCSI_RESET_NOT_RUNNING;
                   3886:          goto Done;
                   3887:        }
                   3888:       else if (CCB->Status == BusLogic_CCB_Completed)
                   3889:        {
                   3890:          BusLogic_Warning("Unable to Reset Command to Target %d - "
                   3891:                           "CCB Completed\n", HostAdapter, TargetID);
                   3892:          Result = SCSI_RESET_NOT_RUNNING;
                   3893:          goto Done;
                   3894:        }
                   3895:       else if (CCB->Status == BusLogic_CCB_Reset)
                   3896:        {
                   3897:          BusLogic_Warning("Unable to Reset Command to Target %d - "
                   3898:                           "Reset Pending\n", HostAdapter, TargetID);
                   3899:          Result = SCSI_RESET_PENDING;
                   3900:          goto Done;
                   3901:        }
                   3902:       else if (HostAdapter->BusDeviceResetPendingCCB[TargetID] != NULL)
                   3903:        {
                   3904:          BusLogic_Warning("Bus Device Reset already pending to Target %d\n",
                   3905:                           HostAdapter, TargetID);
                   3906:          goto Done;
                   3907:        }
                   3908:     }
                   3909:   /*
                   3910:     If this is a Synchronous Reset and a Bus Device Reset is already pending
                   3911:     for this Target Device, do not send a second one.  Add this Command to
                   3912:     the list of Commands for which completion processing must be performed
                   3913:     when the Bus Device Reset CCB completes.
                   3914:   */
                   3915:   if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
                   3916:     if ((CCB = HostAdapter->BusDeviceResetPendingCCB[TargetID]) != NULL)
                   3917:       {
                   3918:        Command->reset_chain = CCB->Command;
                   3919:        CCB->Command = Command;
                   3920:        BusLogic_Warning("Unable to Reset Command to Target %d - "
                   3921:                         "Reset Pending\n", HostAdapter, TargetID);
                   3922:        Result = SCSI_RESET_PENDING;
                   3923:        goto Done;
                   3924:       }
                   3925:   if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
                   3926:     {
                   3927:       /*
                   3928:        MultiMaster Firmware versions prior to 5.xx treat a Bus Device Reset as
                   3929:        a non-tagged command.  Since non-tagged commands are not sent by the
                   3930:        Host Adapter until the queue of outstanding tagged commands has
                   3931:        completed, it is effectively impossible to send a Bus Device Reset
                   3932:        while there are tagged commands outstanding.  Therefore, in that case a
                   3933:        full Host Adapter Hard Reset and SCSI Bus Reset must be done.
                   3934:       */
                   3935:       if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
                   3936:          HostAdapter->ActiveCommands[TargetID] > 0 &&
                   3937:          HostAdapter->FirmwareVersion[0] < '5')
                   3938:        goto Done;
                   3939:     }
                   3940:   /*
                   3941:     Allocate a CCB from the Host Adapter's free list.  In the unlikely event
                   3942:     that there are none available and memory allocation fails, attempt a full
                   3943:     Host Adapter Hard Reset and SCSI Bus Reset.
                   3944:   */
                   3945:   CCB = BusLogic_AllocateCCB(HostAdapter);
                   3946:   if (CCB == NULL) goto Done;
                   3947:   BusLogic_Warning("Sending Bus Device Reset CCB #%ld to Target %d\n",
                   3948:                   HostAdapter, CCB->SerialNumber, TargetID);
                   3949:   CCB->Opcode = BusLogic_BusDeviceReset;
                   3950:   CCB->TargetID = TargetID;
                   3951:   /*
                   3952:     For Synchronous Resets, arrange for the interrupt handler to perform
                   3953:     completion processing for the Command being Reset.
                   3954:   */
                   3955:   if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
                   3956:     {
                   3957:       Command->reset_chain = NULL;
                   3958:       CCB->Command = Command;
                   3959:     }
                   3960:   if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
                   3961:     {
                   3962:       /*
                   3963:        Attempt to write an Outgoing Mailbox with the Bus Device Reset CCB.
                   3964:        If sending a Bus Device Reset is impossible, attempt a full Host
                   3965:        Adapter Hard Reset and SCSI Bus Reset.
                   3966:       */
                   3967:       if (!(BusLogic_WriteOutgoingMailbox(
                   3968:              HostAdapter, BusLogic_MailboxStartCommand, CCB)))
                   3969:        {
                   3970:          BusLogic_Warning("Unable to write Outgoing Mailbox for "
                   3971:                           "Bus Device Reset\n", HostAdapter);
                   3972:          BusLogic_DeallocateCCB(CCB);
                   3973:          goto Done;
                   3974:        }
                   3975:     }
                   3976:   else
                   3977:     {
                   3978:       /*
                   3979:        Call the FlashPoint SCCB Manager to start execution of the CCB.
                   3980:       */
                   3981:       CCB->Status = BusLogic_CCB_Active;
                   3982:       HostAdapter->ActiveCommands[TargetID]++;
                   3983:       FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
                   3984:     }
                   3985:   /*
                   3986:     If there is a currently executing CCB in the Host Adapter for this Command
                   3987:     (i.e. this is an Asynchronous Reset), then an Incoming Mailbox entry may be
                   3988:     made with a completion code of BusLogic_HostAdapterAssertedBusDeviceReset.
                   3989:     If there is no active CCB for this Command (i.e. this is a Synchronous
                   3990:     Reset), then the Bus Device Reset CCB's Command field will have been set
                   3991:     to the Command so that the interrupt for the completion of the Bus Device
                   3992:     Reset can call the Completion Routine for the Command.  On successful
                   3993:     execution of a Bus Device Reset, older firmware versions did return the
                   3994:     pending CCBs with the appropriate completion code, but more recent firmware
                   3995:     versions only return the Bus Device Reset CCB itself.  This driver handles
                   3996:     both cases by marking all the currently executing CCBs to this Target
                   3997:     Device as Reset.  When the Bus Device Reset CCB is processed by the
                   3998:     interrupt handler, any remaining CCBs marked as Reset will have completion
                   3999:     processing performed.
                   4000:   */
                   4001:   BusLogic_IncrementErrorCounter(
                   4002:     &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsAttempted);
                   4003:   HostAdapter->BusDeviceResetPendingCCB[TargetID] = CCB;
                   4004:   HostAdapter->LastResetAttempted[TargetID] = jiffies;
                   4005:   for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll)
                   4006:     if (XCCB->Status == BusLogic_CCB_Active && XCCB->TargetID == TargetID)
                   4007:       XCCB->Status = BusLogic_CCB_Reset;
                   4008:   /*
                   4009:     FlashPoint Host Adapters may have already completed the Bus Device
                   4010:     Reset and BusLogic_QueueCompletedCCB been called, or it may still be
                   4011:     pending.
                   4012:   */
                   4013:   Result = SCSI_RESET_PENDING;
                   4014:   if (BusLogic_FlashPointHostAdapterP(HostAdapter))
                   4015:     if (CCB->Status == BusLogic_CCB_Completed)
                   4016:       {
                   4017:        BusLogic_ProcessCompletedCCBs(HostAdapter);
                   4018:        Result = SCSI_RESET_SUCCESS;
                   4019:       }
                   4020:   /*
                   4021:     If a Bus Device Reset was not possible for some reason, force a full
                   4022:     Host Adapter Hard Reset and SCSI Bus Reset.
                   4023:   */
                   4024: Done:
                   4025:   if (Result < 0)
                   4026:     Result = BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
                   4027:   /*
                   4028:     Release exclusive access to Host Adapter.
                   4029:   */
                   4030:   BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
                   4031:   return Result;
                   4032: }
                   4033: 
                   4034: 
                   4035: /*
                   4036:   BusLogic_ResetCommand takes appropriate action to reset Command.
                   4037: */
                   4038: 
                   4039: int BusLogic_ResetCommand(SCSI_Command_T *Command, unsigned int ResetFlags)
                   4040: {
                   4041:   BusLogic_HostAdapter_T *HostAdapter =
                   4042:     (BusLogic_HostAdapter_T *) Command->host->hostdata;
                   4043:   int TargetID = Command->target;
                   4044:   BusLogic_ErrorRecoveryStrategy_T
                   4045:     ErrorRecoveryStrategy = HostAdapter->ErrorRecoveryStrategy[TargetID];
                   4046:   /*
                   4047:     Disable Tagged Queuing if it is active for this Target Device and if
                   4048:     it has been less than 10 minutes since the last reset occurred, or since
                   4049:     the system was initialized if no prior resets have occurred.
                   4050:   */
                   4051:   if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
                   4052:       jiffies - HostAdapter->LastResetCompleted[TargetID] < 10*60*HZ)
                   4053:     {
                   4054:       HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
                   4055:       HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
                   4056:       BusLogic_Warning("Tagged Queuing now disabled for Target %d\n",
                   4057:                       HostAdapter, TargetID);
                   4058:     }
                   4059:   switch (ErrorRecoveryStrategy)
                   4060:     {
                   4061:     case BusLogic_ErrorRecovery_Default:
                   4062:       if (ResetFlags & SCSI_RESET_SUGGEST_HOST_RESET)
                   4063:        return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
                   4064:       else if (ResetFlags & SCSI_RESET_SUGGEST_BUS_RESET)
                   4065:        return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
                   4066:       /* Fall through to Bus Device Reset case. */
                   4067:     case BusLogic_ErrorRecovery_BusDeviceReset:
                   4068:       /*
                   4069:        The Bus Device Reset Error Recovery Strategy only graduates to a Hard
                   4070:        Reset when no commands have completed successfully since the last Bus
                   4071:        Device Reset and it has been at least 100 milliseconds.  This prevents
                   4072:        a sequence of commands that all timeout together from immediately
                   4073:        forcing a Hard Reset before the Bus Device Reset has had a chance to
                   4074:        clear the error condition.
                   4075:       */
                   4076:       if (HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag ||
                   4077:          jiffies - HostAdapter->LastResetAttempted[TargetID] < HZ/10)
                   4078:        {
                   4079:          HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
                   4080:          return BusLogic_SendBusDeviceReset(HostAdapter, Command, ResetFlags);
                   4081:        }
                   4082:       /* Fall through to Hard Reset case. */
                   4083:     case BusLogic_ErrorRecovery_HardReset:
                   4084:       return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
                   4085:     case BusLogic_ErrorRecovery_None:
                   4086:       BusLogic_Warning("Error Recovery for Target %d Suppressed\n",
                   4087:                       HostAdapter, TargetID);
                   4088:       break;
                   4089:     }
                   4090:   return SCSI_RESET_PUNT;
                   4091: }
                   4092: 
                   4093: 
                   4094: /*
                   4095:   BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
                   4096:   Parameters for Disk.  The default disk geometry is 64 heads, 32 sectors, and
                   4097:   the appropriate number of cylinders so as not to exceed drive capacity.  In
                   4098:   order for disks equal to or larger than 1 GB to be addressable by the BIOS
                   4099:   without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
                   4100:   may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
                   4101:   series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
                   4102:   series MultiMaster Host Adapters.  With Extended Translation enabled, drives
                   4103:   between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
                   4104:   heads and 32 sectors, and drives above 2 GB inclusive are given a disk
                   4105:   geometry of 255 heads and 63 sectors.  However, if the BIOS detects that the
                   4106:   Extended Translation setting does not match the geometry in the partition
                   4107:   table, then the translation inferred from the partition table will be used by
                   4108:   the BIOS, and a warning may be displayed.
                   4109: */
                   4110: 
                   4111: int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
                   4112:                                int *Parameters)
                   4113: {
                   4114:   BusLogic_HostAdapter_T *HostAdapter =
                   4115:     (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
                   4116:   BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
                   4117:   struct buffer_head *BufferHead;
                   4118:   if (HostAdapter->ExtendedTranslationEnabled &&
                   4119:       Disk->capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */)
                   4120:     {
                   4121:       if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
                   4122:        {
                   4123:          DiskParameters->Heads = 255;
                   4124:          DiskParameters->Sectors = 63;
                   4125:        }
                   4126:       else
                   4127:        {
                   4128:          DiskParameters->Heads = 128;
                   4129:          DiskParameters->Sectors = 32;
                   4130:        }
                   4131:     }
                   4132:   else
                   4133:     {
                   4134:       DiskParameters->Heads = 64;
                   4135:       DiskParameters->Sectors = 32;
                   4136:     }
                   4137:   DiskParameters->Cylinders =
                   4138:     Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
                   4139:   /*
                   4140:     Attempt to read the first 1024 bytes from the disk device.
                   4141:   */
                   4142:   BufferHead = bread(MKDEV(MAJOR(Device), MINOR(Device) & ~0x0F), 0, 1024);
                   4143:   if (BufferHead == NULL) return 0;
                   4144:   /*
                   4145:     If the boot sector partition table flag is valid, search for a partition
                   4146:     table entry whose end_head matches one of the standard BusLogic geometry
                   4147:     translations (64/32, 128/32, or 255/63).
                   4148:   */
                   4149:   if (*(unsigned short *) (BufferHead->b_data + 0x1FE) == 0xAA55)
                   4150:     {
                   4151:       PartitionTable_T *FirstPartitionEntry =
                   4152:        (PartitionTable_T *) (BufferHead->b_data + 0x1BE);
                   4153:       PartitionTable_T *PartitionEntry = FirstPartitionEntry;
                   4154:       int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
                   4155:       unsigned char PartitionEntryEndHead, PartitionEntryEndSector;
                   4156:       for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++)
                   4157:        {
                   4158:          PartitionEntryEndHead = PartitionEntry->end_head;
                   4159:          PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
                   4160:          if (PartitionEntryEndHead == 64-1)
                   4161:            {
                   4162:              DiskParameters->Heads = 64;
                   4163:              DiskParameters->Sectors = 32;
                   4164:              break;
                   4165:            }
                   4166:          else if (PartitionEntryEndHead == 128-1)
                   4167:            {
                   4168:              DiskParameters->Heads = 128;
                   4169:              DiskParameters->Sectors = 32;
                   4170:              break;
                   4171:            }
                   4172:          else if (PartitionEntryEndHead == 255-1)
                   4173:            {
                   4174:              DiskParameters->Heads = 255;
                   4175:              DiskParameters->Sectors = 63;
                   4176:              break;
                   4177:            }
                   4178:          PartitionEntry++;
                   4179:        }
                   4180:       if (PartitionNumber == 4)
                   4181:        {
                   4182:          PartitionEntryEndHead = FirstPartitionEntry->end_head;
                   4183:          PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
                   4184:        }
                   4185:       DiskParameters->Cylinders =
                   4186:        Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
                   4187:       if (PartitionNumber < 4 &&
                   4188:          PartitionEntryEndSector == DiskParameters->Sectors)
                   4189:        {
                   4190:          if (DiskParameters->Cylinders != SavedCylinders)
                   4191:            BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n",
                   4192:                             HostAdapter,
                   4193:                             DiskParameters->Heads, DiskParameters->Sectors);
                   4194:        }
                   4195:       else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0)
                   4196:        {
                   4197:          BusLogic_Warning("Warning: Partition Table appears to "
                   4198:                           "have Geometry %d/%d which is\n", HostAdapter,
                   4199:                           PartitionEntryEndHead + 1,
                   4200:                           PartitionEntryEndSector);
                   4201:          BusLogic_Warning("not compatible with current BusLogic "
                   4202:                           "Host Adapter Geometry %d/%d\n", HostAdapter,
                   4203:                           DiskParameters->Heads, DiskParameters->Sectors);
                   4204:        }
                   4205:     }
                   4206:   brelse(BufferHead);
                   4207:   return 0;
                   4208: }
                   4209: 
                   4210: 
                   4211: /*
                   4212:   BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
                   4213: */
                   4214: 
                   4215: int BusLogic_ProcDirectoryInfo(char *ProcBuffer, char **StartPointer,
                   4216:                               off_t Offset, int BytesAvailable,
                   4217:                               int HostNumber, int WriteFlag)
                   4218: {
                   4219:   BusLogic_HostAdapter_T *HostAdapter;
                   4220:   BusLogic_TargetStatistics_T *TargetStatistics;
                   4221:   int TargetID, Length;
                   4222:   char *Buffer;
                   4223:   for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
                   4224:        HostAdapter != NULL;
                   4225:        HostAdapter = HostAdapter->Next)
                   4226:     if (HostAdapter->HostNumber == HostNumber) break;
                   4227:   if (HostAdapter == NULL)
                   4228:     {
                   4229:       BusLogic_Error("Cannot find Host Adapter for SCSI Host %d\n",
                   4230:                     NULL, HostNumber);
                   4231:       return 0;
                   4232:     }
                   4233:   TargetStatistics = HostAdapter->TargetStatistics;
                   4234:   if (WriteFlag)
                   4235:     {
                   4236:       HostAdapter->ExternalHostAdapterResets = 0;
                   4237:       HostAdapter->HostAdapterInternalErrors = 0;
                   4238:       memset(TargetStatistics, 0,
                   4239:             BusLogic_MaxTargetDevices * sizeof(BusLogic_TargetStatistics_T));
                   4240:       return 0;
                   4241:     }
                   4242:   Buffer = HostAdapter->MessageBuffer;
                   4243:   Length = HostAdapter->MessageBufferLength;
                   4244:   Length += sprintf(&Buffer[Length], "\n\
                   4245: Current Driver Queue Depth:    %d\n\
                   4246: Currently Allocated CCBs:      %d\n",
                   4247:                    HostAdapter->DriverQueueDepth,
                   4248:                    HostAdapter->AllocatedCCBs);
                   4249:   Length += sprintf(&Buffer[Length], "\n\n\
                   4250:                           DATA TRANSFER STATISTICS\n\
                   4251: \n\
                   4252: Target Tagged Queuing  Queue Depth  Active  Attempted  Completed\n\
                   4253: ====== ==============  ===========  ======  =========  =========\n");
                   4254:   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   4255:     {
                   4256:       BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
                   4257:       if (!TargetFlags->TargetExists) continue;
                   4258:       Length +=
                   4259:        sprintf(&Buffer[Length], "  %2d %s", TargetID,
                   4260:                (TargetFlags->TaggedQueuingSupported
                   4261:                 ? (TargetFlags->TaggedQueuingActive
                   4262:                    ? "    Active"
                   4263:                    : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
                   4264:                       ? "  Permitted" : "   Disabled"))
                   4265:                 : "Not Supported"));
                   4266:       Length += sprintf(&Buffer[Length],
                   4267:                        "           %3d       %3u    %9u        %9u\n",
                   4268:                        HostAdapter->QueueDepth[TargetID],
                   4269:                        HostAdapter->ActiveCommands[TargetID],
                   4270:                        TargetStatistics[TargetID].CommandsAttempted,
                   4271:                        TargetStatistics[TargetID].CommandsCompleted);
                   4272:     }
                   4273:   Length += sprintf(&Buffer[Length], "\n\
                   4274: Target  Read Commands  Write Commands   Total Bytes Read    Total Bytes Written\n\
                   4275: ======  =============  ==============  ===================  ===================\n");
                   4276:   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   4277:     {
                   4278:       BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
                   4279:       if (!TargetFlags->TargetExists) continue;
                   4280:       Length +=
                   4281:        sprintf(&Buffer[Length], "  %2d   %9u    %9u", TargetID,
                   4282:                TargetStatistics[TargetID].ReadCommands,
                   4283:                TargetStatistics[TargetID].WriteCommands);
                   4284:       if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
                   4285:        Length +=
                   4286:          sprintf(&Buffer[Length], "     %9u%09u",
                   4287:                  TargetStatistics[TargetID].TotalBytesRead.Billions,
                   4288:                  TargetStatistics[TargetID].TotalBytesRead.Units);
                   4289:       else
                   4290:        Length +=
                   4291:          sprintf(&Buffer[Length], "            %9u",
                   4292:                  TargetStatistics[TargetID].TotalBytesRead.Units);
                   4293:       if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
                   4294:        Length +=
                   4295:          sprintf(&Buffer[Length], "   %9u%09u\n",
                   4296:                  TargetStatistics[TargetID].TotalBytesWritten.Billions,
                   4297:                  TargetStatistics[TargetID].TotalBytesWritten.Units);
                   4298:       else
                   4299:        Length +=
                   4300:          sprintf(&Buffer[Length], "         %9u\n",
                   4301:                  TargetStatistics[TargetID].TotalBytesWritten.Units);
                   4302:     }
                   4303:   Length += sprintf(&Buffer[Length], "\n\
                   4304: Target  Command    0-1KB      1-2KB      2-4KB      4-8KB     8-16KB\n\
                   4305: ======  =======  =========  =========  =========  =========  =========\n");
                   4306:   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   4307:     {
                   4308:       BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
                   4309:       if (!TargetFlags->TargetExists) continue;
                   4310:       Length +=
                   4311:        sprintf(&Buffer[Length],
                   4312:                "  %2d   Read    %9u  %9u  %9u  %9u  %9u\n", TargetID,
                   4313:                TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
                   4314:                TargetStatistics[TargetID].ReadCommandSizeBuckets[1],
                   4315:                TargetStatistics[TargetID].ReadCommandSizeBuckets[2],
                   4316:                TargetStatistics[TargetID].ReadCommandSizeBuckets[3],
                   4317:                TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
                   4318:       Length +=
                   4319:        sprintf(&Buffer[Length],
                   4320:                "  %2d   Write   %9u  %9u  %9u  %9u  %9u\n", TargetID,
                   4321:                TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
                   4322:                TargetStatistics[TargetID].WriteCommandSizeBuckets[1],
                   4323:                TargetStatistics[TargetID].WriteCommandSizeBuckets[2],
                   4324:                TargetStatistics[TargetID].WriteCommandSizeBuckets[3],
                   4325:                TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
                   4326:     }
                   4327:   Length += sprintf(&Buffer[Length], "\n\
                   4328: Target  Command   16-32KB    32-64KB   64-128KB   128-256KB   256KB+\n\
                   4329: ======  =======  =========  =========  =========  =========  =========\n");
                   4330:   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   4331:     {
                   4332:       BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
                   4333:       if (!TargetFlags->TargetExists) continue;
                   4334:       Length +=
                   4335:        sprintf(&Buffer[Length],
                   4336:                "  %2d   Read    %9u  %9u  %9u  %9u  %9u\n", TargetID,
                   4337:                TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
                   4338:                TargetStatistics[TargetID].ReadCommandSizeBuckets[6],
                   4339:                TargetStatistics[TargetID].ReadCommandSizeBuckets[7],
                   4340:                TargetStatistics[TargetID].ReadCommandSizeBuckets[8],
                   4341:                TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
                   4342:       Length +=
                   4343:        sprintf(&Buffer[Length],
                   4344:                "  %2d   Write   %9u  %9u  %9u  %9u  %9u\n", TargetID,
                   4345:                TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
                   4346:                TargetStatistics[TargetID].WriteCommandSizeBuckets[6],
                   4347:                TargetStatistics[TargetID].WriteCommandSizeBuckets[7],
                   4348:                TargetStatistics[TargetID].WriteCommandSizeBuckets[8],
                   4349:                TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
                   4350:     }
                   4351:   Length += sprintf(&Buffer[Length], "\n\n\
                   4352:                           ERROR RECOVERY STATISTICS\n\
                   4353: \n\
                   4354:          Command Aborts      Bus Device Resets   Host Adapter Resets\n\
                   4355: Target Requested Completed  Requested Completed  Requested Completed\n\
                   4356:   ID   \\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////\n\
                   4357: ======  ===== ===== =====    ===== ===== =====    ===== ===== =====\n");
                   4358:   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
                   4359:     {
                   4360:       BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
                   4361:       if (!TargetFlags->TargetExists) continue;
                   4362:       Length +=
                   4363:        sprintf(&Buffer[Length], "\
                   4364:   %2d   %5d %5d %5d    %5d %5d %5d        %5d %5d %5d\n", TargetID,
                   4365:                TargetStatistics[TargetID].CommandAbortsRequested,
                   4366:                TargetStatistics[TargetID].CommandAbortsAttempted,
                   4367:                TargetStatistics[TargetID].CommandAbortsCompleted,
                   4368:                TargetStatistics[TargetID].BusDeviceResetsRequested,
                   4369:                TargetStatistics[TargetID].BusDeviceResetsAttempted,
                   4370:                TargetStatistics[TargetID].BusDeviceResetsCompleted,
                   4371:                TargetStatistics[TargetID].HostAdapterResetsRequested,
                   4372:                TargetStatistics[TargetID].HostAdapterResetsAttempted,
                   4373:                TargetStatistics[TargetID].HostAdapterResetsCompleted);
                   4374:     }
                   4375:   Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n",
                   4376:                    HostAdapter->ExternalHostAdapterResets);
                   4377:   Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n",
                   4378:                    HostAdapter->HostAdapterInternalErrors);
                   4379:   if (Length >= BusLogic_MessageBufferSize)
                   4380:     BusLogic_Error("Message Buffer length %d exceeds size %d\n",
                   4381:                   HostAdapter, Length, BusLogic_MessageBufferSize);
                   4382:   if ((Length -= Offset) <= 0) return 0;
                   4383:   if (Length >= BytesAvailable) Length = BytesAvailable;
                   4384:   *StartPointer = &HostAdapter->MessageBuffer[Offset];
                   4385:   return Length;
                   4386: }
                   4387: 
                   4388: 
                   4389: /*
                   4390:   BusLogic_Message prints Driver Messages.
                   4391: */
                   4392: 
                   4393: static void BusLogic_Message(BusLogic_MessageLevel_T MessageLevel,
                   4394:                             char *Format,
                   4395:                             BusLogic_HostAdapter_T *HostAdapter,
                   4396:                             ...)
                   4397: {
                   4398:   static char Buffer[BusLogic_LineBufferSize];
                   4399:   static boolean BeginningOfLine = true;
                   4400:   va_list Arguments;
                   4401:   int Length = 0;
                   4402:   va_start(Arguments, HostAdapter);
                   4403:   Length = vsprintf(Buffer, Format, Arguments);
                   4404:   va_end(Arguments);
                   4405:   if (MessageLevel == BusLogic_AnnounceLevel)
                   4406:     {
                   4407:       static int AnnouncementLines = 0;
                   4408:       strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
                   4409:             Buffer);
                   4410:       HostAdapter->MessageBufferLength += Length;
                   4411:       if (++AnnouncementLines <= 2)
                   4412:        printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
                   4413:     }
                   4414:   else if (MessageLevel == BusLogic_InfoLevel)
                   4415:     {
                   4416:       strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
                   4417:             Buffer);
                   4418:       HostAdapter->MessageBufferLength += Length;
                   4419:       if (BeginningOfLine)
                   4420:        {
                   4421:          if (Buffer[0] != '\n' || Length > 1)
                   4422:            printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
                   4423:                   HostAdapter->HostNumber, Buffer);
                   4424:        }
                   4425:       else printk("%s", Buffer);
                   4426:     }
                   4427:   else
                   4428:     {
                   4429:       if (BeginningOfLine)
                   4430:        {
                   4431:          if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
                   4432:            printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
                   4433:                   HostAdapter->HostNumber, Buffer);
                   4434:          else printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
                   4435:        }
                   4436:       else printk("%s", Buffer);
                   4437:     }
                   4438:   BeginningOfLine = (Buffer[Length-1] == '\n');
                   4439: }
                   4440: 
                   4441: 
                   4442: /*
                   4443:   BusLogic_ParseKeyword parses an individual option keyword.  It returns true
                   4444:   and updates the pointer if the keyword is recognized and false otherwise.
                   4445: */
                   4446: 
                   4447: static boolean BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
                   4448: {
                   4449:   char *Pointer = *StringPointer;
                   4450:   while (*Keyword != '\0')
                   4451:     {
                   4452:       char StringChar = *Pointer++;
                   4453:       char KeywordChar = *Keyword++;
                   4454:       if (StringChar >= 'A' && StringChar <= 'Z')
                   4455:        StringChar += 'a' - 'Z';
                   4456:       if (KeywordChar >= 'A' && KeywordChar <= 'Z')
                   4457:        KeywordChar += 'a' - 'Z';
                   4458:       if (StringChar != KeywordChar) return false;
                   4459:     }
                   4460:   *StringPointer = Pointer;
                   4461:   return true;
                   4462: }
                   4463: 
                   4464: 
                   4465: /*
                   4466:   BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options
                   4467:   specifications.
                   4468: 
                   4469:   BusLogic Driver Options may be specified either via the Linux Kernel Command
                   4470:   Line or via the Loadable Kernel Module Installation Facility.  Driver Options
                   4471:   for multiple host adapters may be specified either by separating the option
                   4472:   strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
                   4473:   command line.  Individual option specifications for a single host adapter are
                   4474:   separated by commas.  The Probing and Debugging Options apply to all host
                   4475:   adapters whereas the remaining options apply individually only to the
                   4476:   selected host adapter.
                   4477: 
                   4478:   The BusLogic Driver Probing Options comprise the following:
                   4479: 
                   4480:   IO:<integer>
                   4481: 
                   4482:     The "IO:" option specifies an ISA I/O Address to be probed for a non-PCI
                   4483:     MultiMaster Host Adapter.  If neither "IO:" nor "NoProbeISA" options are
                   4484:     specified, then the standard list of BusLogic MultiMaster ISA I/O Addresses
                   4485:     will be probed (0x330, 0x334, 0x230, 0x234, 0x130, and 0x134).  Multiple
                   4486:     "IO:" options may be specified to precisely determine the I/O Addresses to
                   4487:     be probed, but the probe order will always follow the standard list.
                   4488: 
                   4489:   NoProbe
                   4490: 
                   4491:     The "NoProbe" option disables all probing and therefore no BusLogic Host
                   4492:     Adapters will be detected.
                   4493: 
                   4494:   NoProbeISA
                   4495: 
                   4496:     The "NoProbeISA" option disables probing of the standard BusLogic ISA I/O
                   4497:     Addresses and therefore only PCI MultiMaster and FlashPoint Host Adapters
                   4498:     will be detected.
                   4499: 
                   4500:   NoProbePCI
                   4501: 
                   4502:     The "NoProbePCI" options disables the interrogation of PCI Configuration
                   4503:     Space and therefore only ISA Multimaster Host Adapters will be detected, as
                   4504:     well as PCI Multimaster Host Adapters that have their ISA Compatible I/O
                   4505:     Port set to "Primary" or "Alternate".
                   4506: 
                   4507:   NoSortPCI
                   4508: 
                   4509:     The "NoSortPCI" option forces PCI MultiMaster Host Adapters to be
                   4510:     enumerated in the order provided by the PCI BIOS, ignoring any setting of
                   4511:     the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option.
                   4512: 
                   4513:   MultiMasterFirst
                   4514: 
                   4515:     The "MultiMasterFirst" option forces MultiMaster Host Adapters to be probed
                   4516:     before FlashPoint Host Adapters.  By default, if both FlashPoint and PCI
                   4517:     MultiMaster Host Adapters are present, this driver will probe for
                   4518:     FlashPoint Host Adapters first unless the BIOS primary disk is controlled
                   4519:     by the first PCI MultiMaster Host Adapter, in which case MultiMaster Host
                   4520:     Adapters will be probed first.
                   4521: 
                   4522:   FlashPointFirst
                   4523: 
                   4524:     The "FlashPointFirst" option forces FlashPoint Host Adapters to be probed
                   4525:     before MultiMaster Host Adapters.
                   4526: 
                   4527:   The BusLogic Driver Tagged Queuing Options allow for explicitly specifying
                   4528:   the Queue Depth and whether Tagged Queuing is permitted for each Target
                   4529:   Device (assuming that the Target Device supports Tagged Queuing).  The Queue
                   4530:   Depth is the number of SCSI Commands that are allowed to be concurrently
                   4531:   presented for execution (either to the Host Adapter or Target Device).  Note
                   4532:   that explicitly enabling Tagged Queuing may lead to problems; the option to
                   4533:   enable or disable Tagged Queuing is provided primarily to allow disabling
                   4534:   Tagged Queuing on Target Devices that do not implement it correctly.  The
                   4535:   following options are available:
                   4536: 
                   4537:   QueueDepth:<integer>
                   4538: 
                   4539:     The "QueueDepth:" or QD:" option specifies the Queue Depth to use for all
                   4540:     Target Devices that support Tagged Queuing, as well as the maximum Queue
                   4541:     Depth for devices that do not support Tagged Queuing.  If no Queue Depth
                   4542:     option is provided, the Queue Depth will be determined automatically based
                   4543:     on the Host Adapter's Total Queue Depth and the number, type, speed, and
                   4544:     capabilities of the detected Target Devices.  For Host Adapters that
                   4545:     require ISA Bounce Buffers, the Queue Depth is automatically set by default
                   4546:     to BusLogic_TaggedQueueDepthBB or BusLogic_UntaggedQueueDepthBB to avoid
                   4547:     excessive preallocation of DMA Bounce Buffer memory.  Target Devices that
                   4548:     do not support Tagged Queuing always have their Queue Depth set to
                   4549:     BusLogic_UntaggedQueueDepth or BusLogic_UntaggedQueueDepthBB, unless a
                   4550:     lower Queue Depth option is provided.  A Queue Depth of 1 automatically
                   4551:     disables Tagged Queuing.
                   4552: 
                   4553:   QueueDepth:[<integer>,<integer>...]
                   4554: 
                   4555:     The "QueueDepth:[...]" or "QD:[...]" option specifies the Queue Depth
                   4556:     individually for each Target Device.  If an <integer> is omitted, the
                   4557:     associated Target Device will have its Queue Depth selected automatically.
                   4558: 
                   4559:   TaggedQueuing:Default
                   4560: 
                   4561:     The "TaggedQueuing:Default" or "TQ:Default" option permits Tagged Queuing
                   4562:     based on the firmware version of the BusLogic Host Adapter and based on
                   4563:     whether the Queue Depth allows queuing multiple commands.
                   4564: 
                   4565:   TaggedQueuing:Enable
                   4566: 
                   4567:     The "TaggedQueuing:Enable" or "TQ:Enable" option enables Tagged Queuing for
                   4568:     all Target Devices on this Host Adapter, overriding any limitation that
                   4569:     would otherwise be imposed based on the Host Adapter firmware version.
                   4570: 
                   4571:   TaggedQueuing:Disable
                   4572: 
                   4573:     The "TaggedQueuing:Disable" or "TQ:Disable" option disables Tagged Queuing
                   4574:     for all Target Devices on this Host Adapter.
                   4575: 
                   4576:   TaggedQueuing:<Target-Spec>
                   4577: 
                   4578:     The "TaggedQueuing:<Target-Spec>" or "TQ:<Target-Spec>" option controls
                   4579:     Tagged Queuing individually for each Target Device.  <Target-Spec> is a
                   4580:     sequence of "Y", "N", and "X" characters.  "Y" enables Tagged Queuing, "N"
                   4581:     disables Tagged Queuing, and "X" accepts the default based on the firmware
                   4582:     version.  The first character refers to Target Device 0, the second to
                   4583:     Target Device 1, and so on; if the sequence of "Y", "N", and "X" characters
                   4584:     does not cover all the Target Devices, unspecified characters are assumed
                   4585:     to be "X".
                   4586: 
                   4587:   The BusLogic Driver Error Recovery Option allows for explicitly specifying
                   4588:   the Error Recovery action to be performed when BusLogic_ResetCommand is
                   4589:   called due to a SCSI Command failing to complete successfully.  The following
                   4590:   options are available:
                   4591: 
                   4592:   ErrorRecovery:Default
                   4593: 
                   4594:     The "ErrorRecovery:Default" or "ER:Default" option selects between the Hard
                   4595:     Reset and Bus Device Reset options based on the recommendation of the SCSI
                   4596:     Subsystem.
                   4597: 
                   4598:   ErrorRecovery:HardReset
                   4599: 
                   4600:     The "ErrorRecovery:HardReset" or "ER:HardReset" option will initiate a Host
                   4601:     Adapter Hard Reset which also causes a SCSI Bus Reset.
                   4602: 
                   4603:   ErrorRecovery:BusDeviceReset
                   4604: 
                   4605:     The "ErrorRecovery:BusDeviceReset" or "ER:BusDeviceReset" option will send
                   4606:     a Bus Device Reset message to the individual Target Device causing the
                   4607:     error.  If Error Recovery is again initiated for this Target Device and no
                   4608:     SCSI Command to this Target Device has completed successfully since the Bus
                   4609:     Device Reset message was sent, then a Hard Reset will be attempted.
                   4610: 
                   4611:   ErrorRecovery:None
                   4612: 
                   4613:     The "ErrorRecovery:None" or "ER:None" option suppresses Error Recovery.
                   4614:     This option should only be selected if a SCSI Bus Reset or Bus Device Reset
                   4615:     will cause the Target Device or a critical operation to suffer a complete
                   4616:     and unrecoverable failure.
                   4617: 
                   4618:   ErrorRecovery:<Target-Spec>
                   4619: 
                   4620:     The "ErrorRecovery:<Target-Spec>" or "ER:<Target-Spec>" option controls
                   4621:     Error Recovery individually for each Target Device.  <Target-Spec> is a
                   4622:     sequence of "D", "H", "B", and "N" characters.  "D" selects Default, "H"
                   4623:     selects Hard Reset, "B" selects Bus Device Reset, and "N" selects None.
                   4624:     The first character refers to Target Device 0, the second to Target Device
                   4625:     1, and so on; if the sequence of "D", "H", "B", and "N" characters does not
                   4626:     cover all the possible Target Devices, unspecified characters are assumed
                   4627:     to be "D".
                   4628: 
                   4629:   The BusLogic Driver Miscellaneous Options comprise the following:
                   4630: 
                   4631:   BusSettleTime:<seconds>
                   4632: 
                   4633:     The "BusSettleTime:" or "BST:" option specifies the Bus Settle Time in
                   4634:     seconds.  The Bus Settle Time is the amount of time to wait between a Host
                   4635:     Adapter Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI
                   4636:     Commands.  If unspecified, it defaults to BusLogic_DefaultBusSettleTime.
                   4637: 
                   4638:   InhibitTargetInquiry
                   4639: 
                   4640:     The "InhibitTargetInquiry" option inhibits the execution of an Inquire
                   4641:     Target Devices or Inquire Installed Devices command on MultiMaster Host
                   4642:     Adapters.  This may be necessary with some older Target Devices that do not
                   4643:     respond correctly when Logical Units above 0 are addressed.
                   4644: 
                   4645:   The BusLogic Driver Debugging Options comprise the following:
                   4646: 
                   4647:   TraceProbe
                   4648: 
                   4649:     The "TraceProbe" option enables tracing of Host Adapter Probing.
                   4650: 
                   4651:   TraceHardwareReset
                   4652: 
                   4653:     The "TraceHardwareReset" option enables tracing of Host Adapter Hardware
                   4654:     Reset.
                   4655: 
                   4656:   TraceConfiguration
                   4657: 
                   4658:     The "TraceConfiguration" option enables tracing of Host Adapter
                   4659:     Configuration.
                   4660: 
                   4661:   TraceErrors
                   4662: 
                   4663:     The "TraceErrors" option enables tracing of SCSI Commands that return an
                   4664:     error from the Target Device.  The CDB and Sense Data will be printed for
                   4665:     each SCSI Command that fails.
                   4666: 
                   4667:   Debug
                   4668: 
                   4669:     The "Debug" option enables all debugging options.
                   4670: 
                   4671:   The following examples demonstrate setting the Queue Depth for Target Devices
                   4672:   1 and 2 on the first host adapter to 7 and 15, the Queue Depth for all Target
                   4673:   Devices on the second host adapter to 31, and the Bus Settle Time on the
                   4674:   second host adapter to 30 seconds.
                   4675: 
                   4676:   Linux Kernel Command Line:
                   4677: 
                   4678:     linux BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30
                   4679: 
                   4680:   LILO Linux Boot Loader (in /etc/lilo.conf):
                   4681: 
                   4682:     append = "BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"
                   4683: 
                   4684:   INSMOD Loadable Kernel Module Installation Facility:
                   4685: 
                   4686:     insmod BusLogic.o \
                   4687:        'BusLogic_Options="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"'
                   4688: 
                   4689:   NOTE: Module Utilities 2.1.71 or later is required for correct parsing
                   4690:        of driver options containing commas.
                   4691: 
                   4692: */
                   4693: 
                   4694: static void BusLogic_ParseDriverOptions(char *OptionsString)
                   4695: {
                   4696:   while (true)
                   4697:     {
                   4698:       BusLogic_DriverOptions_T *DriverOptions =
                   4699:        &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
                   4700:       int TargetID;
                   4701:       memset(DriverOptions, 0, sizeof(BusLogic_DriverOptions_T));
                   4702:       for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
                   4703:        DriverOptions->ErrorRecoveryStrategy[TargetID] =
                   4704:          BusLogic_ErrorRecovery_Default;
                   4705:       while (*OptionsString != '\0' && *OptionsString != ';')
                   4706:        {
                   4707:          /* Probing Options. */
                   4708:          if (BusLogic_ParseKeyword(&OptionsString, "IO:"))
                   4709:            {
                   4710:              BusLogic_IO_Address_T IO_Address =
                   4711:                simple_strtoul(OptionsString, &OptionsString, 0);
                   4712:              BusLogic_ProbeOptions.LimitedProbeISA = true;
                   4713:              switch (IO_Address)
                   4714:                {
                   4715:                case 0x330:
                   4716:                  BusLogic_ProbeOptions.Probe330 = true;
                   4717:                  break;
                   4718:                case 0x334:
                   4719:                  BusLogic_ProbeOptions.Probe334 = true;
                   4720:                  break;
                   4721:                case 0x230:
                   4722:                  BusLogic_ProbeOptions.Probe230 = true;
                   4723:                  break;
                   4724:                case 0x234:
                   4725:                  BusLogic_ProbeOptions.Probe234 = true;
                   4726:                  break;
                   4727:                case 0x130:
                   4728:                  BusLogic_ProbeOptions.Probe130 = true;
                   4729:                  break;
                   4730:                case 0x134:
                   4731:                  BusLogic_ProbeOptions.Probe134 = true;
                   4732:                  break;
                   4733:                default:
                   4734:                  BusLogic_Error("BusLogic: Invalid Driver Options "
                   4735:                                 "(illegal I/O Address 0x%X)\n",
                   4736:                                 NULL, IO_Address);
                   4737:                  return;
                   4738:                }
                   4739:            }
                   4740:          else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
                   4741:            BusLogic_ProbeOptions.NoProbeISA = true;
                   4742:          else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
                   4743:            BusLogic_ProbeOptions.NoProbePCI = true;
                   4744:          else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
                   4745:            BusLogic_ProbeOptions.NoProbe = true;
                   4746:          else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
                   4747:            BusLogic_ProbeOptions.NoSortPCI = true;
                   4748:          else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
                   4749:            BusLogic_ProbeOptions.MultiMasterFirst = true;
                   4750:          else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
                   4751:            BusLogic_ProbeOptions.FlashPointFirst = true;
                   4752:          /* Tagged Queuing Options. */
                   4753:          else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") ||
                   4754:                   BusLogic_ParseKeyword(&OptionsString, "QD:["))
                   4755:            {
                   4756:              for (TargetID = 0;
                   4757:                   TargetID < BusLogic_MaxTargetDevices;
                   4758:                   TargetID++)
                   4759:                {
                   4760:                  unsigned short QueueDepth =
                   4761:                    simple_strtoul(OptionsString, &OptionsString, 0);
                   4762:                  if (QueueDepth > BusLogic_MaxTaggedQueueDepth)
                   4763:                    {
                   4764:                      BusLogic_Error("BusLogic: Invalid Driver Options "
                   4765:                                     "(illegal Queue Depth %d)\n",
                   4766:                                     NULL, QueueDepth);
                   4767:                      return;
                   4768:                    }
                   4769:                  DriverOptions->QueueDepth[TargetID] = QueueDepth;
                   4770:                  if (*OptionsString == ',')
                   4771:                    OptionsString++;
                   4772:                  else if (*OptionsString == ']')
                   4773:                    break;
                   4774:                  else
                   4775:                    {
                   4776:                      BusLogic_Error("BusLogic: Invalid Driver Options "
                   4777:                                     "(',' or ']' expected at '%s')\n",
                   4778:                                     NULL, OptionsString);
                   4779:                      return;
                   4780:                    }
                   4781:                }
                   4782:              if (*OptionsString != ']')
                   4783:                {
                   4784:                  BusLogic_Error("BusLogic: Invalid Driver Options "
                   4785:                                 "(']' expected at '%s')\n",
                   4786:                                 NULL, OptionsString);
                   4787:                  return;
                   4788:                }
                   4789:              else OptionsString++;
                   4790:            }
                   4791:          else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") ||
                   4792:                   BusLogic_ParseKeyword(&OptionsString, "QD:"))
                   4793:            {
                   4794:              unsigned short QueueDepth =
                   4795:                simple_strtoul(OptionsString, &OptionsString, 0);
                   4796:              if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth)
                   4797:                {
                   4798:                  BusLogic_Error("BusLogic: Invalid Driver Options "
                   4799:                                 "(illegal Queue Depth %d)\n",
                   4800:                                 NULL, QueueDepth);
                   4801:                  return;
                   4802:                }
                   4803:              DriverOptions->CommonQueueDepth = QueueDepth;
                   4804:              for (TargetID = 0;
                   4805:                   TargetID < BusLogic_MaxTargetDevices;
                   4806:                   TargetID++)
                   4807:                DriverOptions->QueueDepth[TargetID] = QueueDepth;
                   4808:            }
                   4809:          else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") ||
                   4810:                   BusLogic_ParseKeyword(&OptionsString, "TQ:"))
                   4811:            {
                   4812:              if (BusLogic_ParseKeyword(&OptionsString, "Default"))
                   4813:                {
                   4814:                  DriverOptions->TaggedQueuingPermitted = 0x0000;
                   4815:                  DriverOptions->TaggedQueuingPermittedMask = 0x0000;
                   4816:                }
                   4817:              else if (BusLogic_ParseKeyword(&OptionsString, "Enable"))
                   4818:                {
                   4819:                  DriverOptions->TaggedQueuingPermitted = 0xFFFF;
                   4820:                  DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
                   4821:                }
                   4822:              else if (BusLogic_ParseKeyword(&OptionsString, "Disable"))
                   4823:                {
                   4824:                  DriverOptions->TaggedQueuingPermitted = 0x0000;
                   4825:                  DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
                   4826:                }
                   4827:              else
                   4828:                {
                   4829:                  unsigned short TargetBit;
                   4830:                  for (TargetID = 0, TargetBit = 1;
                   4831:                       TargetID < BusLogic_MaxTargetDevices;
                   4832:                       TargetID++, TargetBit <<= 1)
                   4833:                    switch (*OptionsString++)
                   4834:                      {
                   4835:                      case 'Y':
                   4836:                        DriverOptions->TaggedQueuingPermitted |= TargetBit;
                   4837:                        DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
                   4838:                        break;
                   4839:                      case 'N':
                   4840:                        DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
                   4841:                        DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
                   4842:                        break;
                   4843:                      case 'X':
                   4844:                        break;
                   4845:                      default:
                   4846:                        OptionsString--;
                   4847:                        TargetID = BusLogic_MaxTargetDevices;
                   4848:                        break;
                   4849:                      }
                   4850:                }
                   4851:            }
                   4852:          /* Error Recovery Option. */
                   4853:          else if (BusLogic_ParseKeyword(&OptionsString, "ErrorRecovery:") ||
                   4854:                   BusLogic_ParseKeyword(&OptionsString, "ER:"))
                   4855:            {
                   4856:              if (BusLogic_ParseKeyword(&OptionsString, "Default"))
                   4857:                for (TargetID = 0;
                   4858:                     TargetID < BusLogic_MaxTargetDevices;
                   4859:                     TargetID++)
                   4860:                  DriverOptions->ErrorRecoveryStrategy[TargetID] =
                   4861:                    BusLogic_ErrorRecovery_Default;
                   4862:              else if (BusLogic_ParseKeyword(&OptionsString, "HardReset"))
                   4863:                for (TargetID = 0;
                   4864:                     TargetID < BusLogic_MaxTargetDevices;
                   4865:                     TargetID++)
                   4866:                  DriverOptions->ErrorRecoveryStrategy[TargetID] =
                   4867:                    BusLogic_ErrorRecovery_HardReset;
                   4868:              else if (BusLogic_ParseKeyword(&OptionsString, "BusDeviceReset"))
                   4869:                for (TargetID = 0;
                   4870:                     TargetID < BusLogic_MaxTargetDevices;
                   4871:                     TargetID++)
                   4872:                  DriverOptions->ErrorRecoveryStrategy[TargetID] =
                   4873:                    BusLogic_ErrorRecovery_BusDeviceReset;
                   4874:              else if (BusLogic_ParseKeyword(&OptionsString, "None"))
                   4875:                for (TargetID = 0;
                   4876:                     TargetID < BusLogic_MaxTargetDevices;
                   4877:                     TargetID++)
                   4878:                  DriverOptions->ErrorRecoveryStrategy[TargetID] =
                   4879:                    BusLogic_ErrorRecovery_None;
                   4880:              else
                   4881:                for (TargetID = 0;
                   4882:                     TargetID < BusLogic_MaxTargetDevices;
                   4883:                     TargetID++)
                   4884:                  switch (*OptionsString++)
                   4885:                    {
                   4886:                    case 'D':
                   4887:                      DriverOptions->ErrorRecoveryStrategy[TargetID] =
                   4888:                        BusLogic_ErrorRecovery_Default;
                   4889:                      break;
                   4890:                    case 'H':
                   4891:                      DriverOptions->ErrorRecoveryStrategy[TargetID] =
                   4892:                        BusLogic_ErrorRecovery_HardReset;
                   4893:                      break;
                   4894:                    case 'B':
                   4895:                      DriverOptions->ErrorRecoveryStrategy[TargetID] =
                   4896:                        BusLogic_ErrorRecovery_BusDeviceReset;
                   4897:                      break;
                   4898:                    case 'N':
                   4899:                      DriverOptions->ErrorRecoveryStrategy[TargetID] =
                   4900:                        BusLogic_ErrorRecovery_None;
                   4901:                      break;
                   4902:                    default:
                   4903:                      OptionsString--;
                   4904:                      TargetID = BusLogic_MaxTargetDevices;
                   4905:                      break;
                   4906:                    }
                   4907:            }
                   4908:          /* Miscellaneous Options. */
                   4909:          else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") ||
                   4910:                   BusLogic_ParseKeyword(&OptionsString, "BST:"))
                   4911:            {
                   4912:              unsigned short BusSettleTime =
                   4913:                simple_strtoul(OptionsString, &OptionsString, 0);
                   4914:              if (BusSettleTime > 5 * 60)
                   4915:                {
                   4916:                  BusLogic_Error("BusLogic: Invalid Driver Options "
                   4917:                                 "(illegal Bus Settle Time %d)\n",
                   4918:                                 NULL, BusSettleTime);
                   4919:                  return;
                   4920:                }
                   4921:              DriverOptions->BusSettleTime = BusSettleTime;
                   4922:            }
                   4923:          else if (BusLogic_ParseKeyword(&OptionsString,
                   4924:                                         "InhibitTargetInquiry"))
                   4925:            DriverOptions->LocalOptions.InhibitTargetInquiry = true;
                   4926:          /* Debugging Options. */
                   4927:          else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
                   4928:              BusLogic_GlobalOptions.TraceProbe = true;
                   4929:          else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
                   4930:              BusLogic_GlobalOptions.TraceHardwareReset = true;
                   4931:          else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
                   4932:              BusLogic_GlobalOptions.TraceConfiguration = true;
                   4933:          else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
                   4934:              BusLogic_GlobalOptions.TraceErrors = true;
                   4935:          else if (BusLogic_ParseKeyword(&OptionsString, "Debug"))
                   4936:            {
                   4937:              BusLogic_GlobalOptions.TraceProbe = true;
                   4938:              BusLogic_GlobalOptions.TraceHardwareReset = true;
                   4939:              BusLogic_GlobalOptions.TraceConfiguration = true;
                   4940:              BusLogic_GlobalOptions.TraceErrors = true;
                   4941:            }
                   4942:          if (*OptionsString == ',')
                   4943:            OptionsString++;
                   4944:          else if (*OptionsString != ';' && *OptionsString != '\0')
                   4945:            {
                   4946:              BusLogic_Error("BusLogic: Unexpected Driver Option '%s' "
                   4947:                             "ignored\n", NULL, OptionsString);
                   4948:              *OptionsString = '\0';
                   4949:            }
                   4950:        }
                   4951:       if (!(BusLogic_DriverOptionsCount == 0 ||
                   4952:            BusLogic_ProbeInfoCount == 0 ||
                   4953:            BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount))
                   4954:        {
                   4955:          BusLogic_Error("BusLogic: Invalid Driver Options "
                   4956:                         "(all or no I/O Addresses must be specified)\n", NULL);
                   4957:          return;
                   4958:        }
                   4959:       /*
                   4960:        Tagged Queuing is disabled when the Queue Depth is 1 since queuing
                   4961:        multiple commands is not possible.
                   4962:       */
                   4963:       for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
                   4964:        if (DriverOptions->QueueDepth[TargetID] == 1)
                   4965:          {
                   4966:            unsigned short TargetBit = 1 << TargetID;
                   4967:            DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
                   4968:            DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
                   4969:          }
                   4970:       if (*OptionsString == ';') OptionsString++;
                   4971:       if (*OptionsString == '\0') return;
                   4972:     }
                   4973: }
                   4974: 
                   4975: 
                   4976: /*
                   4977:   BusLogic_Setup handles processing of Kernel Command Line Arguments.
                   4978: */
                   4979: 
                   4980: void BusLogic_Setup(char *CommandLineString, int *CommandLineIntegers)
                   4981: {
                   4982:   if (CommandLineIntegers[0] != 0)
                   4983:     {
                   4984:       BusLogic_Error("BusLogic: Obsolete Command Line Entry "
                   4985:                     "Format Ignored\n", NULL);
                   4986:       return;
                   4987:     }
                   4988:   if (CommandLineString == NULL || *CommandLineString == '\0') return;
                   4989:   BusLogic_ParseDriverOptions(CommandLineString);
                   4990: }
                   4991: 
                   4992: 
                   4993: /*
                   4994:   Include Module support if requested.
                   4995: */
                   4996: 
                   4997: #ifdef MODULE
                   4998: 
                   4999: SCSI_Host_Template_T driver_template = BUSLOGIC;
                   5000: 
                   5001: #include "scsi_module.c"
                   5002: 
                   5003: #endif

unix.superglobalmegacorp.com

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