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, NULL) < 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, NULL);
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                                       void *DeviceIdentifier,
1769                                       Registers_T *InterruptRegisters)
1770 {
1771   BusLogic_CCB_T *FirstCompletedCCB = NULL, *LastCompletedCCB = NULL;
1772   BusLogic_HostAdapter_T *HostAdapter;
1773   int HostAdapterResetPendingCount = 0;
1774   /*
1775     Iterate over the installed BusLogic Host Adapters accepting any Incoming
1776     Mailbox entries and saving the completed CCBs for processing.  This
1777     interrupt handler is installed with SA_INTERRUPT, so interrupts are
1778     disabled when the interrupt handler is entered.
1779   */
1780   for (HostAdapter = BusLogic_RegisteredHostAdapters;
1781        HostAdapter != NULL;
1782        HostAdapter = HostAdapter->Next)
1783     {
1784       unsigned char InterruptRegister;
1785       /*
1786         Acquire exclusive access to Host Adapter.
1787       */
1788       BusLogic_LockHostAdapterID(HostAdapter);
1789       /*
1790         Read the Host Adapter Interrupt Register.
1791       */
1792       InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
1793       if (InterruptRegister & BusLogic_InterruptValid)
1794         {
1795           /*
1796             Acknowledge the interrupt and reset the Host Adapter
1797             Interrupt Register.
1798           */
1799           BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
1800           /*
1801             Process valid SCSI Reset State and Incoming Mailbox Loaded
1802             interrupts.  Command Complete interrupts are noted, and
1803             Outgoing Mailbox Available interrupts are ignored, as they
1804             are never enabled.
1805           */
1806           if (InterruptRegister & BusLogic_SCSIResetState)
1807             {
1808               HostAdapter->HostAdapterResetPending = true;
1809               HostAdapterResetPendingCount++;
1810             }
1811           else if (InterruptRegister & BusLogic_IncomingMailboxLoaded)
1812             {
1813               /*
1814                 Scan through the Incoming Mailboxes in Strict Round Robin
1815                 fashion, saving any completed CCBs for further processing.
1816                 It is essential that for each CCB and SCSI Command issued,
1817                 command completion processing is performed exactly once.
1818                 Therefore, only Incoming Mailboxes with completion code
1819                 Command Completed Without Error, Command Completed With
1820                 Error, or Command Aborted At Host Request are saved for
1821                 completion processing.  When an Incoming Mailbox has a
1822                 completion code of Aborted Command Not Found, the CCB had
1823                 already completed or been aborted before the current Abort
1824                 request was processed, and so completion processing has
1825                 already occurred and no further action should be taken.
1826               */
1827               BusLogic_IncomingMailbox_T *NextIncomingMailbox =
1828                 HostAdapter->NextIncomingMailbox;
1829               BusLogic_CompletionCode_T MailboxCompletionCode;
1830               while ((MailboxCompletionCode =
1831                       NextIncomingMailbox->CompletionCode) !=
1832                      BusLogic_IncomingMailboxFree)
1833                 {
1834                   BusLogic_CCB_T *CCB = NextIncomingMailbox->CCB;
1835                   if (MailboxCompletionCode != BusLogic_AbortedCommandNotFound)
1836                     if (CCB->Status == BusLogic_CCB_Active)
1837                       {
1838                         /*
1839                           Mark this CCB as completed and add it to the end
1840                           of the list of completed CCBs.
1841                         */
1842                         CCB->Status = BusLogic_CCB_Completed;
1843                         CCB->MailboxCompletionCode = MailboxCompletionCode;
1844                         CCB->Next = NULL;
1845                         if (FirstCompletedCCB == NULL)
1846                           {
1847                             FirstCompletedCCB = CCB;
1848                             LastCompletedCCB = CCB;
1849                           }
1850                         else
1851                           {
1852                             LastCompletedCCB->Next = CCB;
1853                             LastCompletedCCB = CCB;
1854                           }
1855                         HostAdapter->QueuedOperationCount[CCB->TargetID]--;
1856                       }
1857                     else
1858                       {
1859                         /*
1860                           If a CCB ever appears in an Incoming Mailbox and
1861                           is not marked as status Active, then there is
1862                           most likely a bug in the Host Adapter firmware.
1863                         */
1864                         printk("scsi%d: Illegal CCB #%d status %d in "
1865                                "Incoming Mailbox\n", HostAdapter->HostNumber,
1866                                CCB->SerialNumber, CCB->Status);
1867                       }
1868                   else printk("scsi%d: Aborted CCB #%d to Target %d "
1869                               "Not Found\n", HostAdapter->HostNumber,
1870                               CCB->SerialNumber, CCB->TargetID);
1871                   NextIncomingMailbox->CompletionCode =
1872                     BusLogic_IncomingMailboxFree;
1873                   if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
1874                     NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
1875                 }
1876               HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
1877             }
1878           else if (InterruptRegister & BusLogic_CommandComplete)
1879             HostAdapter->HostAdapterCommandCompleted = true;
1880         }
1881       /*
1882         Release exclusive access to Host Adapter.
1883       */
1884       BusLogic_UnlockHostAdapterID(HostAdapter);
1885     }
1886   /*
1887     Enable interrupts while the completed CCBs are processed.
1888   */
1889   sti();
1890   /*
1891     Iterate over the Host Adapters performing any pending Host Adapter Resets.
1892   */
1893   if (HostAdapterResetPendingCount > 0)
1894     for (HostAdapter = BusLogic_RegisteredHostAdapters;
1895          HostAdapter != NULL;
1896          HostAdapter = HostAdapter->Next)
1897       if (HostAdapter->HostAdapterResetPending)
1898         {
1899           BusLogic_ResetHostAdapter(HostAdapter, NULL);
1900           HostAdapter->HostAdapterResetPending = false;
1901           scsi_mark_host_bus_reset(HostAdapter->SCSI_Host);
1902         }
1903   /*
1904     Iterate over the completed CCBs setting the SCSI Command Result Codes,
1905     deallocating the CCBs, and calling the Completion Routines.
1906   */
1907   while (FirstCompletedCCB != NULL)
1908     {
1909       BusLogic_CCB_T *CCB = FirstCompletedCCB;
1910       SCSI_Command_T *Command = CCB->Command;
1911       FirstCompletedCCB = FirstCompletedCCB->Next;
1912       HostAdapter = CCB->HostAdapter;
1913       /*
1914         Bus Device Reset CCBs have the Command field non-NULL only when a Bus
1915         Device Reset was requested for a command that was not currently active
1916         in the Host Adapter, and hence would not have its Completion Routine
1917         called otherwise.
1918       */
1919       if (CCB->Opcode == BusLogic_SCSIBusDeviceReset)
1920         {
1921           printk("scsi%d: Bus Device Reset CCB #%d to Target %d Completed\n",
1922                  HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
1923           if (Command != NULL) Command->result = DID_RESET << 16;
1924         }
1925       else
1926         /*
1927           Translate the Mailbox Completion Code, Host Adapter Status, and
1928           Target Device Status into a SCSI Subsystem Result Code.
1929         */
1930         switch (CCB->MailboxCompletionCode)
1931           {
1932           case BusLogic_IncomingMailboxFree:
1933           case BusLogic_AbortedCommandNotFound:
1934             printk("scsi%d: CCB #%d to Target %d Impossible State\n",
1935                    HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
1936             break;
1937           case BusLogic_CommandCompletedWithoutError:
1938             HostAdapter->CommandSuccessfulFlag[CCB->TargetID] = true;
1939             Command->result = DID_OK << 16;
1940             break;
1941           case BusLogic_CommandAbortedAtHostRequest:
1942             printk("scsi%d: CCB #%d to Target %d Aborted\n",
1943                    HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
1944             Command->result = DID_ABORT << 16;
1945             break;
1946           case BusLogic_CommandCompletedWithError:
1947             Command->result =
1948               BusLogic_ComputeResultCode(CCB->HostAdapterStatus,
1949                                          CCB->TargetDeviceStatus);
1950             if (BusLogic_GlobalOptions & BusLogic_TraceErrors)
1951               if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
1952                 {
1953                   int i;
1954                   printk("scsi%d: CCB #%d Target %d: Result %X "
1955                          "Host Adapter Status %02X Target Status %02X\n",
1956                          HostAdapter->HostNumber, CCB->SerialNumber,
1957                          CCB->TargetID, Command->result,
1958                          CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
1959                   printk("scsi%d: CDB   ", HostAdapter->HostNumber);
1960                   for (i = 0; i < CCB->CDB_Length; i++)
1961                     printk(" %02X", CCB->CDB[i]);
1962                   printk("\n");
1963                   printk("scsi%d: Sense ", HostAdapter->HostNumber);
1964                   for (i = 0; i < CCB->SenseDataLength; i++)
1965                     printk(" %02X", (*CCB->SenseDataPointer)[i]);
1966                   printk("\n");
1967                 }
1968             break;
1969           }
1970       /*
1971         Place CCB back on the Host Adapter's free list.
1972       */
1973       BusLogic_DeallocateCCB(CCB);
1974       /*
1975         Call the SCSI Command Completion Routine if appropriate.
1976       */
1977       if (Command != NULL) Command->scsi_done(Command);
1978     }
1979 }
1980 
1981 
1982 /*
1983   BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
1984   Mailbox for execution by Host Adapter.
1985 */
1986 
1987 static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T
     /* [previous][next][first][last][top][bottom][index][help] */
1988                                                *HostAdapter,
1989                                              BusLogic_ActionCode_T ActionCode,
1990                                              BusLogic_CCB_T *CCB)
1991 {
1992   BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
1993   boolean Result = false;
1994   BusLogic_LockHostAdapter(HostAdapter);
1995   NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
1996   if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
1997     {
1998       CCB->Status = BusLogic_CCB_Active;
1999       /*
2000         The CCB field must be written before the Action Code field since
2001         the Host Adapter is operating asynchronously and the locking code
2002         does not protect against simultaneous access by the Host Adapter.
2003       */
2004       NextOutgoingMailbox->CCB = CCB;
2005       NextOutgoingMailbox->ActionCode = ActionCode;
2006       BusLogic_StartMailboxScan(HostAdapter);
2007       if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
2008         NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2009       HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
2010       if (ActionCode == BusLogic_MailboxStartCommand)
2011         HostAdapter->QueuedOperationCount[CCB->TargetID]++;
2012       Result = true;
2013     }
2014   BusLogic_UnlockHostAdapter(HostAdapter);
2015   return Result;
2016 }
2017 
2018 
2019 /*
2020   BusLogic_QueueCommand creates a CCB for Command and places it into an
2021   Outgoing Mailbox for execution by the associated Host Adapter.
2022 */
2023 
2024 int BusLogic_QueueCommand(SCSI_Command_T *Command,
     /* [previous][next][first][last][top][bottom][index][help] */
2025                           void (*CompletionRoutine)(SCSI_Command_T *))
2026 {
2027   BusLogic_HostAdapter_T *HostAdapter =
2028     (BusLogic_HostAdapter_T *) Command->host->hostdata;
2029   unsigned char *CDB = Command->cmnd;
2030   unsigned char CDB_Length = Command->cmd_len;
2031   unsigned char TargetID = Command->target;
2032   unsigned char LogicalUnit = Command->lun;
2033   void *BufferPointer = Command->request_buffer;
2034   int BufferLength = Command->request_bufflen;
2035   int SegmentCount = Command->use_sg;
2036   BusLogic_CCB_T *CCB;
2037   long EnableTQ;
2038   /*
2039     SCSI REQUEST_SENSE commands will be executed automatically by the Host
2040     Adapter for any errors, so they should not be executed explicitly unless
2041     the Sense Data is zero indicating that no error occurred.
2042   */
2043   if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
2044     {
2045       Command->result = DID_OK << 16;
2046       CompletionRoutine(Command);
2047       return 0;
2048     }
2049   /*
2050     Allocate a CCB from the Host Adapter's free list.  If there are none
2051     available and memory allocation fails, return a result code of Bus Busy
2052     so that this Command will be retried.
2053   */
2054   CCB = BusLogic_AllocateCCB(HostAdapter);
2055   if (CCB == NULL)
2056     {
2057       Command->result = DID_BUS_BUSY << 16;
2058       CompletionRoutine(Command);
2059       return 0;
2060     }
2061   /*
2062     Initialize the fields in the BusLogic Command Control Block (CCB).
2063   */
2064   if (SegmentCount == 0)
2065     {
2066       CCB->Opcode = BusLogic_InitiatorCCB;
2067       CCB->DataLength = BufferLength;
2068       CCB->DataPointer = BufferPointer;
2069     }
2070   else
2071     {
2072       SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
2073       int Segment;
2074       CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
2075       CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
2076       CCB->DataPointer = CCB->ScatterGatherList;
2077       for (Segment = 0; Segment < SegmentCount; Segment++)
2078         {
2079           CCB->ScatterGatherList[Segment].SegmentByteCount =
2080             ScatterList[Segment].length;
2081           CCB->ScatterGatherList[Segment].SegmentDataPointer =
2082             ScatterList[Segment].address;
2083         }
2084     }
2085   switch (CDB[0])
2086     {
2087     case READ_6:
2088     case READ_10:
2089       CCB->DataDirection = BusLogic_DataInLengthChecked;
2090       HostAdapter->ReadWriteOperationCount[TargetID]++;
2091       break;
2092     case WRITE_6:
2093     case WRITE_10:
2094       CCB->DataDirection = BusLogic_DataOutLengthChecked;
2095       HostAdapter->ReadWriteOperationCount[TargetID]++;
2096       break;
2097     default:
2098       CCB->DataDirection = BusLogic_UncheckedDataTransfer;
2099       break;
2100     }
2101   CCB->CDB_Length = CDB_Length;
2102   CCB->SenseDataLength = sizeof(Command->sense_buffer);
2103   CCB->HostAdapterStatus = 0;
2104   CCB->TargetDeviceStatus = 0;
2105   CCB->TargetID = TargetID;
2106   CCB->LogicalUnit = LogicalUnit;
2107   /*
2108     For Wide SCSI Host Adapters, Wide Mode CCBs are used to support more than
2109     8 Logical Units per Target, and this requires setting the overloaded
2110     TagEnable field to Logical Unit bit 5.
2111   */
2112   if (HostAdapter->HostWideSCSI)
2113     {
2114       CCB->TagEnable = LogicalUnit >> 5;
2115       CCB->WideModeTagEnable = false;
2116     }
2117   else CCB->TagEnable = false;
2118   /*
2119     BusLogic recommends that after a Reset the first couple of commands that
2120     are sent to a Target be sent in a non Tagged Queue fashion so that the Host
2121     Adapter and Target can establish Synchronous Transfer before Queue Tag
2122     messages can interfere with the Synchronous Negotiation message.  By
2123     waiting to enable tagged Queuing until after the first 16 read/write
2124     commands have been sent, it is assured that the Tagged Queuing message
2125     will not occur while the partition table is printed.
2126   */
2127   if ((HostAdapter->TaggedQueuingPermitted & (1 << TargetID)) &&
2128       Command->device->tagged_supported &&
2129       (EnableTQ = HostAdapter->ReadWriteOperationCount[TargetID] - 16) >= 0)
2130     {
2131       BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
2132       unsigned long CurrentTime = jiffies;
2133       if (EnableTQ == 0)
2134         printk("scsi%d: Tagged Queuing now active for Target %d\n",
2135                HostAdapter->HostNumber, TargetID);
2136       /*
2137         When using Tagged Queuing with Simple Queue Tags, it appears that disk
2138         drive controllers do not guarantee that a queued command will not
2139         remain in a disconnected state indefinitely if commands that read or
2140         write nearer the head position continue to arrive without interruption.
2141         Therefore, for each Target Device this driver keeps track of the last
2142         time either the queue was empty or an Ordered Queue Tag was issued.  If
2143         more than 2 seconds have elapsed since this last sequence point, this
2144         command will be issued with an Ordered Queue Tag rather than a Simple
2145         Queue Tag, which forces the Target Device to complete all previously
2146         queued commands before this command may be executed.
2147       */
2148       if (HostAdapter->QueuedOperationCount[TargetID] == 0)
2149         HostAdapter->LastSequencePoint[TargetID] = CurrentTime;
2150       else if (CurrentTime - HostAdapter->LastSequencePoint[TargetID] > 2*HZ)
2151         {
2152           HostAdapter->LastSequencePoint[TargetID] = CurrentTime;
2153           QueueTag = BusLogic_OrderedQueueTag;
2154         }
2155       if (HostAdapter->HostWideSCSI)
2156         {
2157           CCB->WideModeTagEnable = true;
2158           CCB->WideModeQueueTag = QueueTag;
2159         }
2160       else
2161         {
2162           CCB->TagEnable = true;
2163           CCB->QueueTag = QueueTag;
2164         }
2165     }
2166   memcpy(CCB->CDB, CDB, CDB_Length);
2167   CCB->SenseDataPointer = (SCSI_SenseData_T *) &Command->sense_buffer;
2168   CCB->Command = Command;
2169   Command->scsi_done = CompletionRoutine;
2170   /*
2171     Place the CCB in an Outgoing Mailbox.  If there are no Outgoing
2172     Mailboxes available, return a result code of Bus Busy so that this
2173     Command will be retried.
2174   */
2175   if (!(BusLogic_WriteOutgoingMailbox(HostAdapter,
2176                                       BusLogic_MailboxStartCommand, CCB)))
2177     {
2178       printk("scsi%d: cannot write Outgoing Mailbox\n",
2179              HostAdapter->HostNumber);
2180       BusLogic_DeallocateCCB(CCB);
2181       Command->result = DID_BUS_BUSY << 16;
2182       CompletionRoutine(Command);
2183     }
2184   return 0;
2185 }
2186 
2187 
2188 /*
2189   BusLogic_AbortCommand aborts Command if possible.
2190 */
2191 
2192 int BusLogic_AbortCommand(SCSI_Command_T *Command)
     /* [previous][next][first][last][top][bottom][index][help] */
2193 {
2194   BusLogic_HostAdapter_T *HostAdapter =
2195     (BusLogic_HostAdapter_T *) Command->host->hostdata;
2196   unsigned long CommandPID = Command->pid;
2197   unsigned char InterruptRegister;
2198   BusLogic_CCB_T *CCB;
2199   int Result;
2200   /*
2201     If the Host Adapter has posted an interrupt but the Interrupt Handler
2202     has not been called for some reason (i.e. the interrupt was lost), try
2203     calling the Interrupt Handler directly to process the commands that
2204     have been completed.
2205   */
2206   InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
2207   if (InterruptRegister & BusLogic_InterruptValid)
2208     {
2209       unsigned long ProcessorFlags;
2210       printk("scsi%d: Recovering Lost/Delayed Interrupt for IRQ Channel %d\n",
2211              HostAdapter->HostNumber, HostAdapter->IRQ_Channel);
2212       save_flags(ProcessorFlags);
2213       cli();
2214       BusLogic_InterruptHandler(HostAdapter->IRQ_Channel, NULL, NULL);
2215       restore_flags(ProcessorFlags);
2216       return SCSI_ABORT_SNOOZE;
2217     }
2218   /*
2219     Find the CCB to be aborted if possible.
2220   */
2221   BusLogic_LockHostAdapter(HostAdapter);
2222   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2223     if (CCB->Command == Command) break;
2224   BusLogic_UnlockHostAdapter(HostAdapter);
2225   if (CCB == NULL)
2226     {
2227       printk("scsi%d: Unable to Abort Command to Target %d - No CCB Found\n",
2228              HostAdapter->HostNumber, Command->target);
2229       return SCSI_ABORT_NOT_RUNNING;
2230     }
2231   /*
2232     Briefly pause to see if this command will complete.
2233   */
2234   printk("scsi%d: Pausing briefly to see if CCB #%d "
2235          "to Target %d will complete\n",
2236          HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
2237   BusLogic_Delay(2);
2238   /*
2239     If this CCB is still Active and still refers to the same Command, then
2240     actually aborting this Command is necessary.
2241   */
2242   BusLogic_LockHostAdapter(HostAdapter);
2243   Result = SCSI_ABORT_NOT_RUNNING;
2244   if (CCB->Status == BusLogic_CCB_Active &&
2245       CCB->Command == Command && Command->pid == CommandPID)
2246     {
2247       /*
2248         Attempt to abort this CCB.
2249       */
2250       if (BusLogic_WriteOutgoingMailbox(HostAdapter,
2251                                         BusLogic_MailboxAbortCommand, CCB))
2252         {
2253           printk("scsi%d: Aborting CCB #%d to Target %d\n",
2254                  HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
2255           Result = SCSI_ABORT_PENDING;
2256         }
2257       else
2258         {
2259           printk("scsi%d: Unable to Abort CCB #%d to Target %d - "
2260                  "No Outgoing Mailboxes\n", HostAdapter->HostNumber,
2261                  CCB->SerialNumber, CCB->TargetID);
2262           Result = SCSI_ABORT_BUSY;
2263         }
2264     }
2265   else printk("scsi%d: CCB #%d to Target %d completed\n",
2266               HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
2267   BusLogic_UnlockHostAdapter(HostAdapter);
2268   return Result;
2269 }
2270 
2271 
2272 /*
2273   BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
2274   currently executing SCSI commands as having been reset, as well as
2275   the specified Command if non-NULL.
2276 */
2277 
2278 static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
     /* [previous][next][first][last][top][bottom][index][help] */
2279                                      SCSI_Command_T *Command)
2280 {
2281   BusLogic_CCB_T *CCB;
2282   if (Command == NULL)
2283     printk("scsi%d: Resetting %s due to SCSI Reset State Interrupt\n",
2284            HostAdapter->HostNumber, HostAdapter->BoardName);
2285   else printk("scsi%d: Resetting %s due to Target %d\n",
2286               HostAdapter->HostNumber, HostAdapter->BoardName, Command->target);
2287   /*
2288     Attempt to Reset and Reinitialize the Host Adapter.
2289   */
2290   BusLogic_LockHostAdapter(HostAdapter);
2291   if (!(BusLogic_HardResetHostAdapter(HostAdapter) &&
2292         BusLogic_InitializeHostAdapter(HostAdapter)))
2293     {
2294       printk("scsi%d: Resetting %s Failed\n",
2295               HostAdapter->HostNumber, HostAdapter->BoardName);
2296       BusLogic_UnlockHostAdapter(HostAdapter);
2297       return SCSI_RESET_ERROR;
2298     }
2299   BusLogic_UnlockHostAdapter(HostAdapter);
2300   /*
2301     Wait a few seconds between the Host Adapter Hard Reset which initiates
2302     a SCSI Bus Reset and issuing any SCSI commands.  Some SCSI devices get
2303     confused if they receive SCSI commands too soon after a SCSI Bus Reset.
2304   */
2305   BusLogic_Delay(HostAdapter->BusSettleTime);
2306   /*
2307     Mark all currently executing CCBs as having been reset.
2308   */
2309   BusLogic_LockHostAdapter(HostAdapter);
2310   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2311     if (CCB->Status == BusLogic_CCB_Active)
2312       {
2313         CCB->Status = BusLogic_CCB_Reset;
2314         if (CCB->Command == Command)
2315           {
2316             CCB->Command = NULL;
2317             /*
2318               Disable Tagged Queuing if it was active for this Target Device.
2319             */
2320             if (((HostAdapter->HostWideSCSI && CCB->WideModeTagEnable) ||
2321                  (!HostAdapter->HostWideSCSI && CCB->TagEnable)) &&
2322                 (HostAdapter->TaggedQueuingPermitted & (1 << CCB->TargetID)))
2323               {
2324                 HostAdapter->TaggedQueuingPermitted &= ~(1 << CCB->TargetID);
2325                 printk("scsi%d: Tagged Queuing now disabled for Target %d\n",
2326                        HostAdapter->HostNumber, CCB->TargetID);
2327               }
2328           }
2329       }
2330   BusLogic_UnlockHostAdapter(HostAdapter);
2331   /*
2332     Perform completion processing for the Command being Reset.
2333   */
2334   if (Command != NULL)
2335     {
2336       Command->result = DID_RESET << 16;
2337       Command->scsi_done(Command);
2338     }
2339   /*
2340     Perform completion processing for any other active CCBs.
2341   */
2342   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2343     if (CCB->Status == BusLogic_CCB_Reset)
2344       {
2345         Command = CCB->Command;
2346         BusLogic_DeallocateCCB(CCB);
2347         if (Command != NULL)
2348           {
2349             Command->result = DID_RESET << 16;
2350             Command->scsi_done(Command);
2351           }
2352       }
2353   return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
2354 }
2355 
2356 
2357 /*
2358   BusLogic_BusDeviceReset sends a Bus Device Reset to the Target
2359   associated with Command.
2360 */
2361 
2362 static int BusLogic_BusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
     /* [previous][next][first][last][top][bottom][index][help] */
2363                                    SCSI_Command_T *Command)
2364 {
2365   BusLogic_CCB_T *CCB = BusLogic_AllocateCCB(HostAdapter), *XCCB;
2366   unsigned char TargetID = Command->target;
2367   /*
2368     If sending a Bus Device Reset is impossible, attempt a full Host
2369     Adapter Hard Reset and SCSI Bus Reset.
2370   */
2371   if (CCB == NULL)
2372     return BusLogic_ResetHostAdapter(HostAdapter, Command);
2373   printk("scsi%d: Sending Bus Device Reset CCB #%d to Target %d\n",
2374          HostAdapter->HostNumber, CCB->SerialNumber, TargetID);
2375   CCB->Opcode = BusLogic_SCSIBusDeviceReset;
2376   CCB->TargetID = TargetID;
2377   CCB->Command = Command;
2378   /*
2379     If there is a currently executing CCB in the Host Adapter for this Command,
2380     then an Incoming Mailbox entry will be made with a completion code of
2381     BusLogic_HostAdapterAssertedBusDeviceReset.  Otherwise, the CCB's Command
2382     field will be left pointing to the Command so that the interrupt for the
2383     completion of the Bus Device Reset can call the Completion Routine for the
2384     Command.
2385   */
2386   BusLogic_LockHostAdapter(HostAdapter);
2387   for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll)
2388     if (XCCB->Command == Command && XCCB->Status == BusLogic_CCB_Active)
2389       {
2390         CCB->Command = NULL;
2391         /*
2392           Disable Tagged Queuing if it was active for this Target Device.
2393         */
2394         if (((HostAdapter->HostWideSCSI && XCCB->WideModeTagEnable) ||
2395             (!HostAdapter->HostWideSCSI && XCCB->TagEnable)) &&
2396             (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
2397           {
2398             HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2399             printk("scsi%d: Tagged Queuing now disabled for Target %d\n",
2400                    HostAdapter->HostNumber, TargetID);
2401           }
2402         break;
2403       }
2404   BusLogic_UnlockHostAdapter(HostAdapter);
2405   /*
2406     Attempt to write an Outgoing Mailbox with the Bus Device Reset CCB.
2407     If sending a Bus Device Reset is impossible, attempt a full Host
2408     Adapter Hard Reset and SCSI Bus Reset.
2409   */
2410   if (!(BusLogic_WriteOutgoingMailbox(HostAdapter,
2411                                       BusLogic_MailboxStartCommand, CCB)))
2412     {
2413       printk("scsi%d: cannot write Outgoing Mailbox for Bus Device Reset\n",
2414              HostAdapter->HostNumber);
2415       BusLogic_DeallocateCCB(CCB);
2416       return BusLogic_ResetHostAdapter(HostAdapter, Command);
2417     }
2418   HostAdapter->ReadWriteOperationCount[TargetID] = 0;
2419   HostAdapter->QueuedOperationCount[TargetID] = 0;
2420   return SCSI_RESET_PENDING;
2421 }
2422 
2423 
2424 /*
2425   BusLogic_ResetCommand takes appropriate action to reset Command.
2426 */
2427 
2428 int BusLogic_ResetCommand(SCSI_Command_T *Command)
     /* [previous][next][first][last][top][bottom][index][help] */
2429 {
2430   BusLogic_HostAdapter_T *HostAdapter =
2431     (BusLogic_HostAdapter_T *) Command->host->hostdata;
2432   unsigned char TargetID = Command->target;
2433   unsigned char ErrorRecoveryOption =
2434     HostAdapter->ErrorRecoveryOption[TargetID];
2435   if (ErrorRecoveryOption == BusLogic_ErrorRecoveryDefault)
2436     if (Command->host->suggest_bus_reset)
2437       ErrorRecoveryOption = BusLogic_ErrorRecoveryHardReset;
2438     else ErrorRecoveryOption = BusLogic_ErrorRecoveryBusDeviceReset;
2439   switch (ErrorRecoveryOption)
2440     {
2441     case BusLogic_ErrorRecoveryHardReset:
2442       return BusLogic_ResetHostAdapter(HostAdapter, Command);
2443     case BusLogic_ErrorRecoveryBusDeviceReset:
2444       if (HostAdapter->CommandSuccessfulFlag[TargetID])
2445         {
2446           HostAdapter->CommandSuccessfulFlag[TargetID] = false;
2447           return BusLogic_BusDeviceReset(HostAdapter, Command);
2448         }
2449       else return BusLogic_ResetHostAdapter(HostAdapter, Command);
2450     }
2451   printk("scsi%d: Error Recovery for Target %d Suppressed\n",
2452          HostAdapter->HostNumber, TargetID);
2453   return SCSI_RESET_PUNT;
2454 }
2455 
2456 
2457 /*
2458   BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
2459   Parameters for Disk.  The default disk geometry is 64 heads, 32 sectors, and
2460   the appropriate number of cylinders so as not to exceed drive capacity.  In
2461   order for disks equal to or larger than 1 GB to be addressable by the BIOS
2462   without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
2463   may be enabled in AutoSCSI on "C" Series boards or by a dip switch setting
2464   on older boards.  With Extended Translation enabled, drives between 1 GB
2465   inclusive and 2 GB exclusive are given a disk geometry of 128 heads and 32
2466   sectors, and drives between 2 GB inclusive and 8 GB exclusive are given a
2467   disk geometry of 255 heads and 63 sectors.  On "C" Series boards the firmware
2468   can be queried for the precise translation in effect for each drive
2469   individually, but there is really no need to do so since we know the total
2470   capacity of the drive and whether Extended Translation is enabled, hence we
2471   can deduce the BIOS disk geometry that must be in effect.
2472 */
2473 
2474 int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
     /* [previous][next][first][last][top][bottom][index][help] */
2475                                 int *Parameters)
2476 {
2477   BusLogic_HostAdapter_T *HostAdapter =
2478     (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
2479   BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
2480   if (HostAdapter->ExtendedTranslation &&
2481       Disk->capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */)
2482     if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
2483       {
2484         DiskParameters->Heads = 255;
2485         DiskParameters->Sectors = 63;
2486       }
2487     else
2488       {
2489         DiskParameters->Heads = 128;
2490         DiskParameters->Sectors = 32;
2491       }
2492   else
2493     {
2494       DiskParameters->Heads = 64;
2495       DiskParameters->Sectors = 32;
2496     }
2497   DiskParameters->Cylinders =
2498     Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
2499   return 0;
2500 }
2501 
2502 
2503 /*
2504   BusLogic_Setup handles processing of Kernel Command Line Arguments.
2505 
2506   For the BusLogic driver, a kernel command line entry comprises the driver
2507   identifier "BusLogic=" optionally followed by a comma-separated sequence of
2508   integers and then optionally followed by a comma-separated sequence of
2509   strings.  Each command line entry applies to one BusLogic Host Adapter.
2510   Multiple command line entries may be used in systems which contain multiple
2511   BusLogic Host Adapters.
2512 
2513   The first integer specified is the I/O Address at which the Host Adapter is
2514   located.  If unspecified, it defaults to 0 which means to apply this entry to
2515   the first BusLogic Host Adapter found during the default probe sequence.  If
2516   any I/O Address parameters are provided on the command line, then the default
2517   probe sequence is omitted.
2518 
2519   The second integer specified is the number of Concurrent Commands per Logical
2520   Unit to allow for Target Devices on the Host Adapter.  If unspecified, it
2521   defaults to 0 which means to use the value of BusLogic_Concurrency for
2522   non-ISA Host Adapters, or BusLogic_Concurrency_ISA for ISA Host Adapters.
2523 
2524   The third integer specified is the Bus Settle Time in seconds.  This is
2525   the amount of time to wait between a Host Adapter Hard Reset which initiates
2526   a SCSI Bus Reset and issuing any SCSI commands.  If unspecified, it defaults
2527   to 0 which means to use the value of BusLogic_DefaultBusSettleTime.
2528 
2529   The fourth integer specified is the Local Options.  If unspecified, it
2530   defaults to 0.  Note that Local Options are only applied to a specific Host
2531   Adapter.
2532 
2533   The fifth integer specified is the Global Options.  If unspecified, it
2534   defaults to 0.  Note that Global Options are applied across all Host
2535   Adapters.
2536 
2537   The string options are used to provide control over Tagged Queuing and Error
2538   Recovery. If both Tagged Queuing and Error Recovery strings are provided, the
2539   Tagged Queuing specification string must come first.
2540 
2541   The Tagged Queuing specification begins with "TQ:" and allows for explicitly
2542   specifying whether Tagged Queuing is permitted on Target Devices that support
2543   it.  The following specification options are available:
2544 
2545   TQ:Default            Tagged Queuing will be permitted based on the firmware
2546                         version of the BusLogic Host Adapter and based on
2547                         whether the Concurrency value allows queuing multiple
2548                         commands.
2549 
2550   TQ:Enable             Tagged Queuing will be enabled for all Target Devices
2551                         on this Host Adapter overriding any limitation that
2552                         would otherwise be imposed based on the Host Adapter
2553                         firmware version.
2554 
2555   TQ:Disable            Tagged Queuing will be disabled for all Target Devices
2556                         on this Host Adapter.
2557 
2558   TQ:<Per-Target-Spec>  Tagged Queuing will be controlled individually for each
2559                         Target Device.  <Per-Target-Spec> is a sequence of "Y",
2560                         "N", and "X" characters.  "Y" enabled Tagged Queuing,
2561                         "N" disables Tagged Queuing, and "X" accepts the
2562                         default based on the firmware version.  The first
2563                         character refers to Target 0, the second to Target 1,
2564                         and so on; if the sequence of "Y", "N", and "X"
2565                         characters does not cover all the Target Devices,
2566                         unspecified characters are assumed to be "X".
2567 
2568   Note that explicitly requesting Tagged Queuing may lead to problems; this
2569   facility is provided primarily to allow disabling Tagged Queuing on Target
2570   Devices that do not implement it correctly.
2571 
2572   The Error Recovery specification begins with "ER:" and allows for explicitly
2573   specifying the Error Recovery action to be performed when ResetCommand is
2574   called due to a SCSI Command failing to complete successfully.  The following
2575   specification options are available:
2576 
2577   ER:Default            Error Recovery will select between the Hard Reset and
2578                         Bus Device Reset options based on the recommendation
2579                         of the SCSI Subsystem.
2580 
2581   ER:HardReset          Error Recovery will initiate a Host Adapter Hard Reset
2582                         which also causes a SCSI Bus Reset.
2583 
2584   ER:BusDeviceReset     Error Recovery will send a Bus Device Reset message to
2585                         the individual Target Device causing the error.  If
2586                         Error Recovery is again initiated for this Target
2587                         Device and no SCSI Command to this Target Device has
2588                         completed successfully since the Bus Device Reset
2589                         message was sent, then a Hard Reset will be attempted.
2590 
2591   ER:None               Error Recovery will be suppressed.  This option should
2592                         only be selected if a SCSI Bus Reset or Bus Device
2593                         Reset will cause the Target Device to fail completely
2594                         and unrecoverably.
2595 
2596   ER:<Per-Target-Spec>  Error Recovery will be controlled individually for each
2597                         Target Device.  <Per-Target-Spec> is a sequence of "D",
2598                         "H", "B", and "N" characters.  "D" selects Default, "H"
2599                         selects Hard Reset, "B" selects Bus Device Reset, and
2600                         "N" selects None.  The first character refers to Target
2601                         0, the second to Target 1, and so on; if the sequence
2602                         of "D", "H", "B", and "N" characters does not cover all
2603                         the Target Devices, unspecified characters are assumed
2604                         to be "D".
2605 */
2606 
2607 void BusLogic_Setup(char *Strings, int *Integers)
     /* [previous][next][first][last][top][bottom][index][help] */
2608 {
2609   BusLogic_CommandLineEntry_T *CommandLineEntry =
2610     &BusLogic_CommandLineEntries[BusLogic_CommandLineEntryCount++];
2611   static int ProbeListIndex = 0;
2612   int IntegerCount = Integers[0], TargetID, i;
2613   CommandLineEntry->IO_Address = 0;
2614   CommandLineEntry->Concurrency = 0;
2615   CommandLineEntry->BusSettleTime = 0;
2616   CommandLineEntry->LocalOptions = 0;
2617   CommandLineEntry->TaggedQueuingPermitted = 0;
2618   CommandLineEntry->TaggedQueuingPermittedMask = 0;
2619   memset(CommandLineEntry->ErrorRecoveryOption,
2620          BusLogic_ErrorRecoveryDefault,
2621          sizeof(CommandLineEntry->ErrorRecoveryOption));
2622   if (IntegerCount > 5)
2623     printk("BusLogic: Unexpected Command Line Integers ignored\n");
2624   if (IntegerCount >= 1)
2625     {
2626       unsigned short IO_Address = Integers[1];
2627       if (IO_Address > 0)
2628         {
2629           for (i = 0; ; i++)
2630             if (BusLogic_IO_StandardAddresses[i] == 0)
2631               {
2632                 printk("BusLogic: Invalid Command Line Entry "
2633                        "(illegal I/O Address 0x%X)\n", IO_Address);
2634                 return;
2635               }
2636             else if (i < ProbeListIndex &&
2637                      IO_Address == BusLogic_IO_AddressProbeList[i])
2638               {
2639                 printk("BusLogic: Invalid Command Line Entry "
2640                        "(duplicate I/O Address 0x%X)\n", IO_Address);
2641                 return;
2642               }
2643             else if (IO_Address >= 0x1000 ||
2644                      IO_Address == BusLogic_IO_StandardAddresses[i]) break;
2645           BusLogic_IO_AddressProbeList[ProbeListIndex++] = IO_Address;
2646           BusLogic_IO_AddressProbeList[ProbeListIndex] = 0;
2647         }
2648       CommandLineEntry->IO_Address = IO_Address;
2649     }
2650   if (IntegerCount >= 2)
2651     {
2652       unsigned short Concurrency = Integers[2];
2653       if (Concurrency > BusLogic_MailboxCount)
2654         {
2655           printk("BusLogic: Invalid Command Line Entry "
2656                  "(illegal Concurrency %d)\n", Concurrency);
2657           return;
2658         }
2659       CommandLineEntry->Concurrency = Concurrency;
2660     }
2661   if (IntegerCount >= 3)
2662     CommandLineEntry->BusSettleTime = Integers[3];
2663   if (IntegerCount >= 4)
2664     CommandLineEntry->LocalOptions = Integers[4];
2665   if (IntegerCount >= 5)
2666     BusLogic_GlobalOptions |= Integers[5];
2667   if (!(BusLogic_CommandLineEntryCount == 0 || ProbeListIndex == 0 ||
2668         BusLogic_CommandLineEntryCount == ProbeListIndex))
2669     {
2670       printk("BusLogic: Invalid Command Line Entry "
2671              "(all or no I/O Addresses must be specified)\n");
2672       return;
2673     }
2674   if (Strings == NULL) return;
2675   if (strncmp(Strings, "TQ:", 3) == 0)
2676     {
2677       Strings += 3;
2678       if (strncmp(Strings, "Default", 7) == 0)
2679         Strings += 7;
2680       else if (strncmp(Strings, "Enable", 6) == 0)
2681         {
2682           Strings += 6;
2683           CommandLineEntry->TaggedQueuingPermitted = 0xFFFF;
2684           CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
2685         }
2686       else if (strncmp(Strings, "Disable", 7) == 0)
2687         {
2688           Strings += 7;
2689           CommandLineEntry->TaggedQueuingPermitted = 0x0000;
2690           CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
2691         }
2692       else
2693         for (TargetID = 0; TargetID < BusLogic_MaxTargetIDs; TargetID++)
2694           switch (*Strings++)
2695             {
2696             case 'Y':
2697               CommandLineEntry->TaggedQueuingPermitted |= 1 << TargetID;
2698               CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
2699               break;
2700             case 'N':
2701               CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
2702               break;
2703             case 'X':
2704               break;
2705             default:
2706               Strings--;
2707               TargetID = BusLogic_MaxTargetIDs;
2708               break;
2709             }
2710     }
2711   if (*Strings == ',') Strings++;
2712   if (strncmp(Strings, "ER:", 3) == 0)
2713     {
2714       Strings += 3;
2715       if (strncmp(Strings, "Default", 7) == 0)
2716         Strings += 7;
2717       else if (strncmp(Strings, "HardReset", 9) == 0)
2718         {
2719           Strings += 9;
2720           memset(CommandLineEntry->ErrorRecoveryOption,
2721                  BusLogic_ErrorRecoveryHardReset,
2722                  sizeof(CommandLineEntry->ErrorRecoveryOption));
2723         }
2724       else if (strncmp(Strings, "BusDeviceReset", 14) == 0)
2725         {
2726           Strings += 14;
2727           memset(CommandLineEntry->ErrorRecoveryOption,
2728                  BusLogic_ErrorRecoveryBusDeviceReset,
2729                  sizeof(CommandLineEntry->ErrorRecoveryOption));
2730         }
2731       else if (strncmp(Strings, "None", 4) == 0)
2732         {
2733           Strings += 4;
2734           memset(CommandLineEntry->ErrorRecoveryOption,
2735                  BusLogic_ErrorRecoveryNone,
2736                  sizeof(CommandLineEntry->ErrorRecoveryOption));
2737         }
2738       else
2739         for (TargetID = 0; TargetID < BusLogic_MaxTargetIDs; TargetID++)
2740           switch (*Strings++)
2741             {
2742             case 'D':
2743               CommandLineEntry->ErrorRecoveryOption[TargetID] =
2744                 BusLogic_ErrorRecoveryDefault;
2745               break;
2746             case 'H':
2747               CommandLineEntry->ErrorRecoveryOption[TargetID] =
2748                 BusLogic_ErrorRecoveryHardReset;
2749               break;
2750             case 'B':
2751               CommandLineEntry->ErrorRecoveryOption[TargetID] =
2752                 BusLogic_ErrorRecoveryBusDeviceReset;
2753               break;
2754             case 'N':
2755               CommandLineEntry->ErrorRecoveryOption[TargetID] =
2756                 BusLogic_ErrorRecoveryNone;
2757               break;
2758             default:
2759               Strings--;
2760               TargetID = BusLogic_MaxTargetIDs;
2761               break;
2762             }
2763     }
2764   if (*Strings != '\0')
2765     printk("BusLogic: Unexpected Command Line String '%s' ignored\n", Strings);
2766 }
2767 
2768 
2769 /*
2770   Include Module support if requested.
2771 */
2772 
2773 
2774 #ifdef MODULE
2775 
2776 SCSI_Host_Template_T driver_template = BUSLOGIC;
2777 
2778 #include "scsi_module.c"
2779 
2780 #endif

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