root/drivers/scsi/BusLogic.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. BusLogic_AnnounceDriver
  2. BusLogic_DriverInfo
  3. BusLogic_InitializeAddressProbeList
  4. BusLogic_RegisterHostAdapter
  5. BusLogic_UnregisterHostAdapter
  6. BusLogic_CreateCCBs
  7. BusLogic_DestroyCCBs
  8. BusLogic_AllocateCCB
  9. BusLogic_DeallocateCCB
  10. BusLogic_Command
  11. BusLogic_Failure
  12. BusLogic_ProbeHostAdapter
  13. BusLogic_HardResetHostAdapter
  14. BusLogic_CheckHostAdapter
  15. BusLogic_ReadHostAdapterConfiguration
  16. BusLogic_AcquireResources
  17. BusLogic_ReleaseResources
  18. BusLogic_TestInterrupts
  19. BusLogic_InitializeHostAdapter
  20. BusLogic_InquireTargetDevices
  21. BusLogic_DetectHostAdapter
  22. BusLogic_ReleaseHostAdapter
  23. BusLogic_ComputeResultCode
  24. BusLogic_InterruptHandler
  25. BusLogic_WriteOutgoingMailbox
  26. BusLogic_QueueCommand
  27. BusLogic_AbortCommand
  28. BusLogic_ResetHostAdapter
  29. BusLogic_BusDeviceReset
  30. BusLogic_ResetCommand
  31. BusLogic_BIOSDiskParameters
  32. BusLogic_Setup

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

/* [previous][next][first][last][top][bottom][index][help] */