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_RegisterHostAdapter
  4. BusLogic_UnregisterHostAdapter
  5. BusLogic_CreateMailboxes
  6. BusLogic_DestroyMailboxes
  7. BusLogic_CreateCCBs
  8. BusLogic_DestroyCCBs
  9. BusLogic_AllocateCCB
  10. BusLogic_DeallocateCCB
  11. BusLogic_Command
  12. BusLogic_InitializeAddressProbeList
  13. BusLogic_Failure
  14. BusLogic_ProbeHostAdapter
  15. BusLogic_HardResetHostAdapter
  16. BusLogic_CheckHostAdapter
  17. BusLogic_ReadHostAdapterConfiguration
  18. BusLogic_AcquireResources
  19. BusLogic_ReleaseResources
  20. BusLogic_TestInterrupts
  21. BusLogic_InitializeHostAdapter
  22. BusLogic_InquireTargetDevices
  23. BusLogic_InitializeHostStructure
  24. BusLogic_SelectQueueDepths
  25. BusLogic_DetectHostAdapter
  26. BusLogic_ReleaseHostAdapter
  27. BusLogic_ComputeResultCode
  28. BusLogic_InterruptHandler
  29. BusLogic_WriteOutgoingMailbox
  30. BusLogic_QueueCommand
  31. BusLogic_AbortCommand
  32. BusLogic_ResetHostAdapter
  33. BusLogic_SendBusDeviceReset
  34. BusLogic_ResetCommand
  35. BusLogic_BIOSDiskParameters
  36. 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 any modifications to this software be
  18   sent directly to him for evaluation and testing.
  19 
  20   Special thanks to Wayne Yen and Alex Win of BusLogic, whose advice has been
  21   invaluable, to David Gentzel, for writing the original Linux BusLogic driver,
  22   and to Paul Gortmaker, for being such a dedicated test site.
  23 
  24 */
  25 
  26 
  27 #define BusLogic_DriverVersion          "1.3.2"
  28 #define BusLogic_DriverDate             "16 April 1996"
  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_StandardAddresses is the list of standard ISA I/O Addresses at
  91   which 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 non-NULL 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_RegisterHostAdapter adds Host Adapter to the list of registered
 171   BusLogic Host Adapters.
 172 */
 173 
 174 static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
     /* [previous][next][first][last][top][bottom][index][help] */
 175 {
 176   HostAdapter->Next = NULL;
 177   if (BusLogic_RegisteredHostAdapters != NULL)
 178     {
 179       BusLogic_HostAdapter_T *LastHostAdapter = BusLogic_RegisteredHostAdapters;
 180       BusLogic_HostAdapter_T *NextHostAdapter;
 181       while ((NextHostAdapter = LastHostAdapter->Next) != NULL)
 182         LastHostAdapter = NextHostAdapter;
 183       LastHostAdapter->Next = HostAdapter;
 184     }
 185   else BusLogic_RegisteredHostAdapters = HostAdapter;
 186 }
 187 
 188 
 189 /*
 190   BusLogic_UnregisterHostAdapter removes Host Adapter from the list of
 191   registered BusLogic Host Adapters.
 192 */
 193 
 194 static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
     /* [previous][next][first][last][top][bottom][index][help] */
 195 {
 196   if (BusLogic_RegisteredHostAdapters != HostAdapter)
 197     {
 198       BusLogic_HostAdapter_T *LastHostAdapter = BusLogic_RegisteredHostAdapters;
 199       while (LastHostAdapter != NULL && LastHostAdapter->Next != HostAdapter)
 200         LastHostAdapter = LastHostAdapter->Next;
 201       if (LastHostAdapter != NULL)
 202         LastHostAdapter->Next = HostAdapter->Next;
 203     }
 204   else BusLogic_RegisteredHostAdapters = HostAdapter->Next;
 205   HostAdapter->Next = NULL;
 206 }
 207 
 208 
 209 /*
 210   BusLogic_CreateMailboxes allocates the Outgoing and Incoming Mailboxes for
 211   Host Adapter.
 212 */
 213 
 214 static boolean BusLogic_CreateMailboxes(BusLogic_HostAdapter_T *HostAdapter)
     /* [previous][next][first][last][top][bottom][index][help] */
 215 {
 216   HostAdapter->FirstOutgoingMailbox =
 217     (BusLogic_OutgoingMailbox_T *)
 218       scsi_init_malloc(HostAdapter->MailboxCount
 219                        * (sizeof(BusLogic_OutgoingMailbox_T)
 220                           + sizeof(BusLogic_IncomingMailbox_T)),
 221                        (HostAdapter->BounceBuffersRequired
 222                         ? GFP_ATOMIC | GFP_DMA
 223                         : GFP_ATOMIC));
 224   if (HostAdapter->FirstOutgoingMailbox == NULL)
 225     {
 226       printk("scsi%d: UNABLE TO ALLOCATE MAILBOXES - DETACHING\n",
 227              HostAdapter->HostNumber);
 228       return false;
 229     }
 230   HostAdapter->LastOutgoingMailbox =
 231     HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
 232   HostAdapter->FirstIncomingMailbox =
 233     (BusLogic_IncomingMailbox_T *) (HostAdapter->LastOutgoingMailbox + 1);
 234   HostAdapter->LastIncomingMailbox =
 235     HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
 236   return true;
 237 }
 238 
 239 
 240 /*
 241   BusLogic_DestroyMailboxes deallocates the Outgoing and Incoming Mailboxes
 242   for Host Adapter.
 243 */
 244 
 245 static void BusLogic_DestroyMailboxes(BusLogic_HostAdapter_T *HostAdapter)
     /* [previous][next][first][last][top][bottom][index][help] */
 246 {
 247   if (HostAdapter->FirstOutgoingMailbox == NULL) return;
 248   scsi_init_free((char *) HostAdapter->FirstOutgoingMailbox,
 249                  HostAdapter->MailboxCount
 250                  * (sizeof(BusLogic_OutgoingMailbox_T)
 251                     + sizeof(BusLogic_IncomingMailbox_T)));
 252 }
 253 
 254 
 255 /*
 256   BusLogic_CreateCCBs allocates the initial Command Control Blocks (CCBs)
 257   for Host Adapter.
 258 */
 259 
 260 static boolean BusLogic_CreateCCBs(BusLogic_HostAdapter_T *HostAdapter)
     /* [previous][next][first][last][top][bottom][index][help] */
 261 {
 262   int i;
 263   for (i = 0; i < HostAdapter->InitialCCBs; i++)
 264     {
 265       BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
 266         scsi_init_malloc(sizeof(BusLogic_CCB_T),
 267                          (HostAdapter->BounceBuffersRequired
 268                           ? GFP_ATOMIC | GFP_DMA
 269                           : GFP_ATOMIC));
 270       if (CCB == NULL)
 271         {
 272           printk("scsi%d: UNABLE TO ALLOCATE CCB %d - DETACHING\n",
 273                  HostAdapter->HostNumber, i);
 274           return false;
 275         }
 276       memset(CCB, 0, sizeof(BusLogic_CCB_T));
 277       CCB->HostAdapter = HostAdapter;
 278       CCB->Status = BusLogic_CCB_Free;
 279       CCB->Next = HostAdapter->Free_CCBs;
 280       CCB->NextAll = HostAdapter->All_CCBs;
 281       HostAdapter->Free_CCBs = CCB;
 282       HostAdapter->All_CCBs = CCB;
 283     }
 284   return true;
 285 }
 286 
 287 
 288 /*
 289   BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
 290 */
 291 
 292 static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *HostAdapter)
     /* [previous][next][first][last][top][bottom][index][help] */
 293 {
 294   BusLogic_CCB_T *NextCCB = HostAdapter->All_CCBs, *CCB;
 295   HostAdapter->All_CCBs = NULL;
 296   HostAdapter->Free_CCBs = NULL;
 297   while ((CCB = NextCCB) != NULL)
 298     {
 299       NextCCB = CCB->NextAll;
 300       scsi_init_free((char *) CCB, sizeof(BusLogic_CCB_T));
 301     }
 302 }
 303 
 304 
 305 /*
 306   BusLogic_AllocateCCB allocates a CCB from the Host Adapter's free list,
 307   allocating more memory from the Kernel if necessary.  The Host Adapter's
 308   Lock should have already been acquired by the caller.
 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   int Allocated;
 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       return CCB;
 323     }
 324   for (Allocated = 0; Allocated < HostAdapter->IncrementalCCBs; Allocated++)
 325     {
 326       CCB = (BusLogic_CCB_T *)
 327         scsi_init_malloc(sizeof(BusLogic_CCB_T),
 328                          (HostAdapter->BounceBuffersRequired
 329                           ? GFP_ATOMIC | GFP_DMA
 330                           : GFP_ATOMIC));
 331       if (CCB == NULL) break;
 332       memset(CCB, 0, sizeof(BusLogic_CCB_T));
 333       CCB->HostAdapter = HostAdapter;
 334       CCB->Status = BusLogic_CCB_Free;
 335       CCB->Next = HostAdapter->Free_CCBs;
 336       CCB->NextAll = HostAdapter->All_CCBs;
 337       HostAdapter->Free_CCBs = CCB;
 338       HostAdapter->All_CCBs = CCB;
 339     }
 340   CCB = HostAdapter->Free_CCBs;
 341   if (CCB == NULL)
 342     {
 343       printk("scsi%d: Failed to allocate additional CCBs\n",
 344              HostAdapter->HostNumber);
 345       return NULL;
 346     }
 347   printk("scsi%d: Allocated %d additional CCBs\n",
 348          HostAdapter->HostNumber, Allocated);
 349   CCB->SerialNumber = ++SerialNumber;
 350   HostAdapter->Free_CCBs = CCB->Next;
 351   CCB->Next = NULL;
 352   return CCB;
 353 }
 354 
 355 
 356 /*
 357   BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's
 358   free list.  The Host Adapter's Lock should have already been acquired by the
 359   caller.
 360 */
 361 
 362 static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB)
     /* [previous][next][first][last][top][bottom][index][help] */
 363 {
 364   BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
 365   CCB->Command = NULL;
 366   CCB->Status = BusLogic_CCB_Free;
 367   CCB->Next = HostAdapter->Free_CCBs;
 368   HostAdapter->Free_CCBs = CCB;
 369 }
 370 
 371 
 372 /*
 373   BusLogic_Command sends the command OperationCode to HostAdapter, optionally
 374   providing ParameterLength bytes of ParameterData and receiving at most
 375   ReplyLength bytes of ReplyData; any excess reply data is received but
 376   discarded.
 377 
 378   On success, this function returns the number of reply bytes read from
 379   the Host Adapter (including any discarded data); on failure, it returns
 380   -1 if the command was invalid, or -2 if a timeout occurred.
 381 
 382   This function is only called during board detection and initialization, so
 383   performance and latency are not critical, and exclusive access to the Host
 384   Adapter hardware is assumed.  Once the board and driver are initialized, the
 385   only Host Adapter command that is issued is the single byte Execute Mailbox
 386   Command operation code , which does not require waiting for the Host Adapter
 387   Ready bit to be set in the Status Register.
 388 */
 389 
 390 static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
     /* [previous][next][first][last][top][bottom][index][help] */
 391                             BusLogic_OperationCode_T OperationCode,
 392                             void *ParameterData,
 393                             int ParameterLength,
 394                             void *ReplyData,
 395                             int ReplyLength)
 396 {
 397   unsigned char *ParameterPointer = (unsigned char *) ParameterData;
 398   unsigned char *ReplyPointer = (unsigned char *) ReplyData;
 399   unsigned char StatusRegister = 0, InterruptRegister;
 400   long TimeoutCounter;
 401   int ReplyBytes = 0;
 402   /*
 403     Clear out the Reply Data if provided.
 404   */
 405   if (ReplyLength > 0)
 406     memset(ReplyData, 0, ReplyLength);
 407   /*
 408     Wait for the Host Adapter Ready bit to be set and the Command/Parameter
 409     Register Busy bit to be reset in the Status Register.
 410   */
 411   TimeoutCounter = loops_per_sec >> 3;
 412   while (--TimeoutCounter >= 0)
 413     {
 414       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
 415       if ((StatusRegister & BusLogic_HostAdapterReady) &&
 416           !(StatusRegister & BusLogic_CommandParameterRegisterBusy))
 417         break;
 418     }
 419   BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
 420   if (TimeoutCounter < 0) return -2;
 421   /*
 422     Write the OperationCode to the Command/Parameter Register.
 423   */
 424   HostAdapter->HostAdapterCommandCompleted = false;
 425   BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
 426   /*
 427     Write any additional Parameter Bytes.
 428   */
 429   TimeoutCounter = 10000;
 430   while (ParameterLength > 0 && --TimeoutCounter >= 0)
 431     {
 432       /*
 433         Wait 100 microseconds to give the Host Adapter enough time to determine
 434         whether the last value written to the Command/Parameter Register was
 435         valid or not.  If the Command Complete bit is set in the Interrupt
 436         Register, then the Command Invalid bit in the Status Register will be
 437         reset if the Operation Code or Parameter was valid and the command
 438         has completed, or set if the Operation Code or Parameter was invalid.
 439         If the Data In Register Ready bit is set in the Status Register, then
 440         the Operation Code was valid, and data is waiting to be read back
 441         from the Host Adapter.  Otherwise, wait for the Command/Parameter
 442         Register Busy bit in the Status Register to be reset.
 443       */
 444       udelay(100);
 445       InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
 446       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
 447       if (InterruptRegister & BusLogic_CommandComplete) break;
 448       if (HostAdapter->HostAdapterCommandCompleted) break;
 449       if (StatusRegister & BusLogic_DataInRegisterReady) break;
 450       if (StatusRegister & BusLogic_CommandParameterRegisterBusy) continue;
 451       BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
 452       ParameterLength--;
 453     }
 454   BusLogic_CommandFailureReason = "Timeout waiting for Parameter Acceptance";
 455   if (TimeoutCounter < 0) return -2;
 456   /*
 457     The Modify I/O Address command does not cause a Command Complete Interrupt.
 458   */
 459   if (OperationCode == BusLogic_ModifyIOAddress)
 460     {
 461       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
 462       BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
 463       if (StatusRegister & BusLogic_CommandInvalid) return -1;
 464       BusLogic_CommandFailureReason = NULL;
 465       return 0;
 466     }
 467   /*
 468     Select an appropriate timeout value for awaiting command completion.
 469   */
 470   switch (OperationCode)
 471     {
 472     case BusLogic_InquireInstalledDevicesID0to7:
 473     case BusLogic_InquireInstalledDevicesID8to15:
 474     case BusLogic_InquireDevices:
 475       /* Approximately 60 seconds. */
 476       TimeoutCounter = loops_per_sec << 2;
 477       break;
 478     default:
 479       /* Approximately 1 second. */
 480       TimeoutCounter = loops_per_sec >> 4;
 481       break;
 482     }
 483   /*
 484     Receive any Reply Bytes, waiting for either the Command Complete bit to
 485     be set in the Interrupt Register, or for the Interrupt Handler to set the
 486     Host Adapter Command Completed bit in the Host Adapter structure.
 487   */
 488   while (--TimeoutCounter >= 0)
 489     {
 490       InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
 491       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
 492       if (InterruptRegister & BusLogic_CommandComplete) break;
 493       if (HostAdapter->HostAdapterCommandCompleted) break;
 494       if (StatusRegister & BusLogic_DataInRegisterReady)
 495         if (++ReplyBytes <= ReplyLength)
 496           *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
 497         else BusLogic_ReadDataInRegister(HostAdapter);
 498       if (OperationCode == BusLogic_FetchHostAdapterLocalRAM &&
 499           (StatusRegister & BusLogic_HostAdapterReady)) break;
 500     }
 501   BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
 502   if (TimeoutCounter < 0) return -2;
 503   /*
 504     If testing Command Complete Interrupts, wait a short while in case the
 505     loop immediately above terminated due to the Command Complete bit being
 506     set in the Interrupt Register, but the interrupt hasn't actually been
 507     processed yet.  Otherwise, acknowledging the interrupt here could prevent
 508     the interrupt test from succeeding.
 509   */
 510   if (OperationCode == BusLogic_TestCommandCompleteInterrupt)
 511     udelay(10000);
 512   /*
 513     Clear any pending Command Complete Interrupt.
 514   */
 515   BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
 516   if (BusLogic_GlobalOptions & BusLogic_TraceConfiguration)
 517     if (OperationCode != BusLogic_TestCommandCompleteInterrupt)
 518       {
 519         int i;
 520         printk("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:",
 521                OperationCode, StatusRegister, ReplyLength, ReplyBytes);
 522         if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes;
 523         for (i = 0; i < ReplyLength; i++)
 524           printk(" %02X", ((unsigned char *) ReplyData)[i]);
 525         printk("\n");
 526       }
 527   /*
 528     Process Command Invalid conditions.
 529   */
 530   if (StatusRegister & BusLogic_CommandInvalid)
 531     {
 532       /*
 533         Some early BusLogic Host Adapters may not recover properly from
 534         a Command Invalid condition, so if this appears to be the case,
 535         a Soft Reset is issued to the Host Adapter.  Potentially invalid
 536         commands are never attempted after Mailbox Initialization is
 537         performed, so there should be no Host Adapter state lost by a
 538         Soft Reset in response to a Command Invalid condition.
 539       */
 540       udelay(1000);
 541       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
 542       if (StatusRegister != (BusLogic_HostAdapterReady |
 543                              BusLogic_InitializationRequired))
 544         {
 545           BusLogic_WriteControlRegister(HostAdapter, BusLogic_SoftReset);
 546           udelay(1000);
 547         }
 548       BusLogic_CommandFailureReason = "Command Invalid";
 549       return -1;
 550     }
 551   /*
 552     Handle Excess Parameters Supplied conditions.
 553   */
 554   BusLogic_CommandFailureReason = "Excess Parameters Supplied";
 555   if (ParameterLength > 0) return -1;
 556   /*
 557     Indicate the command completed successfully.
 558   */
 559   BusLogic_CommandFailureReason = NULL;
 560   return ReplyBytes;
 561 }
 562 
 563 
 564 /*
 565   BusLogic_InitializeAddressProbeList initializes the list of I/O Addresses
 566   to be probed for potential BusLogic SCSI Host Adapters by interrogating the
 567   PCI Configuration Space on PCI machines as well as from the list of standard
 568   BusLogic I/O Addresses.
 569 */
 570 
 571 static void BusLogic_InitializeAddressProbeList(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 572 {
 573   int DestinationIndex = 0, SourceIndex = 0;
 574   /*
 575     If BusLogic_Setup has provided an I/O Address probe list, do not override
 576     the Kernel Command Line specifications.
 577   */
 578   if (BusLogic_IO_AddressProbeList[0] != 0) return;
 579 #ifdef CONFIG_PCI
 580   /*
 581     Interrogate PCI Configuration Space for any BusLogic SCSI Host Adapters.
 582   */
 583   if (pcibios_present())
 584     {
 585       unsigned short BusDeviceFunction[BusLogic_IO_MaxProbeAddresses];
 586       unsigned short Index = 0, VendorID, DeviceID;
 587       boolean NonIncreasingScanningOrder = false;
 588       unsigned char Bus, DeviceFunction;
 589       unsigned int BaseAddress0;
 590       while (pcibios_find_class(PCI_CLASS_STORAGE_SCSI<<8, Index++,
 591                                 &Bus, &DeviceFunction) == 0)
 592         if (pcibios_read_config_word(Bus, DeviceFunction,
 593                                      PCI_VENDOR_ID, &VendorID) == 0 &&
 594             VendorID == PCI_VENDOR_ID_BUSLOGIC &&
 595             pcibios_read_config_word(Bus, DeviceFunction,
 596                                      PCI_DEVICE_ID, &DeviceID) == 0 &&
 597             (DeviceID == PCI_DEVICE_ID_BUSLOGIC_946C ||
 598              DeviceID == PCI_DEVICE_ID_BUSLOGIC_946C_2) &&
 599             pcibios_read_config_dword(Bus, DeviceFunction,
 600                                       PCI_BASE_ADDRESS_0, &BaseAddress0) == 0 &&
 601             (BaseAddress0 & PCI_BASE_ADDRESS_SPACE) ==
 602               PCI_BASE_ADDRESS_SPACE_IO)
 603           {
 604             BusLogic_IO_AddressProbeList[DestinationIndex] =
 605               BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
 606             BusDeviceFunction[DestinationIndex] = (Bus << 8) | DeviceFunction;
 607             if (DestinationIndex > 0 &&
 608                 BusDeviceFunction[DestinationIndex] <
 609                   BusDeviceFunction[DestinationIndex-1])
 610               NonIncreasingScanningOrder = true;
 611             DestinationIndex++;
 612           }
 613       /*
 614         If there are multiple BusLogic PCI SCSI Host Adapters present and if
 615         they are enumerated by the PCI BIOS in an order other than by strictly
 616         increasing Bus Number and Device Number, then interrogate the setting
 617         of the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option.
 618         If it is ON, sort the PCI Host Adapter I/O Addresses by increasing Bus
 619         Number and Device Number so that the Host Adapters are recognized in
 620         the same order by the Linux kernel as by the Host Adapter's BIOS.
 621       */
 622       if (DestinationIndex > 1 && NonIncreasingScanningOrder)
 623         {
 624           BusLogic_FetchHostAdapterLocalRAMRequest_T
 625             FetchHostAdapterLocalRAMRequest;
 626           BusLogic_AutoSCSIByte45_T AutoSCSIByte45;
 627           BusLogic_HostAdapter_T HostAdapterPrototype;
 628           BusLogic_HostAdapter_T *HostAdapter = &HostAdapterPrototype;
 629           HostAdapter->IO_Address = BusLogic_IO_AddressProbeList[0];
 630           FetchHostAdapterLocalRAMRequest.ByteOffset =
 631             BusLogic_AutoSCSI_BaseOffset + 45;
 632           FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIByte45);
 633           AutoSCSIByte45.ForceBusDeviceScanningOrder = false;
 634           BusLogic_Command(HostAdapter,
 635                            BusLogic_FetchHostAdapterLocalRAM,
 636                            &FetchHostAdapterLocalRAMRequest,
 637                            sizeof(FetchHostAdapterLocalRAMRequest),
 638                            &AutoSCSIByte45, sizeof(AutoSCSIByte45));
 639           if (AutoSCSIByte45.ForceBusDeviceScanningOrder)
 640             {
 641               /*
 642                 Sort the I/O Addresses such that the corresponding PCI devices
 643                 are in ascending order by Bus Number and Device Number.
 644               */
 645               int LastInterchange = DestinationIndex-1, Bound, j;
 646               while (LastInterchange > 0)
 647                 {
 648                   Bound = LastInterchange;
 649                   LastInterchange = 0;
 650                   for (j = 0; j < Bound; j++)
 651                     if (BusDeviceFunction[j] > BusDeviceFunction[j+1])
 652                       {
 653                         unsigned short Temp;
 654                         Temp = BusDeviceFunction[j];
 655                         BusDeviceFunction[j] = BusDeviceFunction[j+1];
 656                         BusDeviceFunction[j+1] = Temp;
 657                         Temp = BusLogic_IO_AddressProbeList[j];
 658                         BusLogic_IO_AddressProbeList[j] =
 659                           BusLogic_IO_AddressProbeList[j+1];
 660                         BusLogic_IO_AddressProbeList[j+1] = Temp;
 661                         LastInterchange = j;
 662                       }
 663                 }
 664             }
 665         }
 666     }
 667 #endif
 668   /*
 669     Append the list of standard BusLogic ISA I/O Addresses.
 670   */
 671   while (DestinationIndex < BusLogic_IO_MaxProbeAddresses &&
 672          BusLogic_IO_StandardAddresses[SourceIndex] > 0)
 673     BusLogic_IO_AddressProbeList[DestinationIndex++] =
 674       BusLogic_IO_StandardAddresses[SourceIndex++];
 675   BusLogic_IO_AddressProbeList[DestinationIndex] = 0;
 676 }
 677 
 678 
 679 /*
 680   BusLogic_Failure prints a standardized error message, and then returns false.
 681 */
 682 
 683 static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter,
     /* [previous][next][first][last][top][bottom][index][help] */
 684                                 char *ErrorMessage)
 685 {
 686   BusLogic_AnnounceDriver();
 687   printk("While configuring BusLogic Host Adapter at I/O Address 0x%X:\n",
 688          HostAdapter->IO_Address);
 689   printk("%s FAILED - DETACHING\n", ErrorMessage);
 690   if (BusLogic_CommandFailureReason != NULL)
 691     printk("ADDITIONAL FAILURE INFO - %s\n", BusLogic_CommandFailureReason);
 692   return false;
 693 }
 694 
 695 
 696 /*
 697   BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
 698 */
 699 
 700 static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
     /* [previous][next][first][last][top][bottom][index][help] */
 701 {
 702   boolean TraceProbe = (BusLogic_GlobalOptions & BusLogic_TraceProbe);
 703   unsigned char StatusRegister, GeometryRegister;
 704   /*
 705     Read the Status Register to test if there is an I/O port that responds.  A
 706     nonexistent I/O port will return 0xFF, in which case there is definitely no
 707     BusLogic Host Adapter at this base I/O Address.
 708   */
 709   StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
 710   if (TraceProbe)
 711     printk("BusLogic_Probe(0x%X): Status 0x%02X\n",
 712            HostAdapter->IO_Address, StatusRegister);
 713   if (StatusRegister == 0xFF) return false;
 714   /*
 715     Read the undocumented BusLogic Geometry Register to test if there is an I/O
 716     port that responds.  Adaptec Host Adapters do not implement the Geometry
 717     Register, so this test helps serve to avoid incorrectly recognizing an
 718     Adaptec 1542A or 1542B as a BusLogic.  Unfortunately, the Adaptec 1542C
 719     series does respond to the Geometry Register I/O port, but it will be
 720     rejected later when the Inquire Extended Setup Information command is
 721     issued in BusLogic_CheckHostAdapter.  The AMI FastDisk Host Adapter is a
 722     BusLogic clone that implements the same interface as earlier BusLogic
 723     boards, including the undocumented commands, and is therefore supported by
 724     this driver.  However, the AMI FastDisk always returns 0x00 upon reading
 725     the Geometry Register, so the extended translation option should always be
 726     left disabled on the AMI FastDisk.
 727   */
 728   GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
 729   if (TraceProbe)
 730     printk("BusLogic_Probe(0x%X): Geometry 0x%02X\n",
 731            HostAdapter->IO_Address, GeometryRegister);
 732   if (GeometryRegister == 0xFF) return false;
 733   /*
 734     Indicate the Host Adapter Probe completed successfully.
 735   */
 736   return true;
 737 }
 738 
 739 
 740 /*
 741   BusLogic_HardResetHostAdapter issues a Hard Reset to the Host Adapter,
 742   and waits for Host Adapter Diagnostics to complete.
 743 */
 744 
 745 static boolean BusLogic_HardResetHostAdapter(BusLogic_HostAdapter_T
     /* [previous][next][first][last][top][bottom][index][help] */
 746                                              *HostAdapter)
 747 {
 748   boolean TraceHardReset = (BusLogic_GlobalOptions & BusLogic_TraceHardReset);
 749   long TimeoutCounter = loops_per_sec >> 2;
 750   unsigned char StatusRegister = 0;
 751   /*
 752     Issue a Hard Reset Command to the Host Adapter.  The Host Adapter should
 753     respond by setting Diagnostic Active in the Status Register.
 754   */
 755   BusLogic_WriteControlRegister(HostAdapter, BusLogic_HardReset);
 756   /*
 757     Wait until Diagnostic Active is set in the Status Register.
 758   */
 759   while (--TimeoutCounter >= 0)
 760     {
 761       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
 762       if ((StatusRegister & BusLogic_DiagnosticActive)) break;
 763     }
 764   if (TraceHardReset)
 765     printk("BusLogic_HardReset(0x%X): Diagnostic Active, Status 0x%02X\n",
 766            HostAdapter->IO_Address, StatusRegister);
 767   if (TimeoutCounter < 0) return false;
 768   /*
 769     Wait 100 microseconds to allow completion of any initial diagnostic
 770     activity which might leave the contents of the Status Register
 771     unpredictable.
 772   */
 773   udelay(100);
 774   /*
 775     Wait until Diagnostic Active is reset in the Status Register.
 776   */
 777   while (--TimeoutCounter >= 0)
 778     {
 779       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
 780       if (!(StatusRegister & BusLogic_DiagnosticActive)) break;
 781     }
 782   if (TraceHardReset)
 783     printk("BusLogic_HardReset(0x%X): Diagnostic Completed, Status 0x%02X\n",
 784            HostAdapter->IO_Address, StatusRegister);
 785   if (TimeoutCounter < 0) return false;
 786   /*
 787     Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
 788     or Data In Register Ready bits is set in the Status Register.
 789   */
 790   while (--TimeoutCounter >= 0)
 791     {
 792       StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
 793       if (StatusRegister & (BusLogic_DiagnosticFailure |
 794                             BusLogic_HostAdapterReady |
 795                             BusLogic_DataInRegisterReady))
 796         break;
 797     }
 798   if (TraceHardReset)
 799     printk("BusLogic_HardReset(0x%X): Host Adapter Ready, Status 0x%02X\n",
 800            HostAdapter->IO_Address, StatusRegister);
 801   if (TimeoutCounter < 0) return false;
 802   /*
 803     If Diagnostic Failure is set or Host Adapter Ready is reset, then an
 804     error occurred during the Host Adapter diagnostics.  If Data In Register
 805     Ready is set, then there is an Error Code available.
 806   */
 807   if ((StatusRegister & BusLogic_DiagnosticFailure) ||
 808       !(StatusRegister & BusLogic_HostAdapterReady))
 809     {
 810       BusLogic_CommandFailureReason = NULL;
 811       BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
 812       printk("HOST ADAPTER STATUS REGISTER = %02X\n", StatusRegister);
 813       if (StatusRegister & BusLogic_DataInRegisterReady)
 814         {
 815           unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
 816           printk("HOST ADAPTER ERROR CODE = %d\n", ErrorCode);
 817         }
 818       return false;
 819     }
 820   /*
 821     Indicate the Host Adapter Hard Reset completed successfully.
 822   */
 823   return true;
 824 }
 825 
 826 
 827 /*
 828   BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
 829   Host Adapter.
 830 */
 831 
 832 static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
     /* [previous][next][first][last][top][bottom][index][help] */
 833 {
 834   BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
 835   BusLogic_RequestedReplyLength_T RequestedReplyLength;
 836   unsigned long ProcessorFlags;
 837   int Result;
 838   /*
 839     Issue the Inquire Extended Setup Information command.  Only genuine
 840     BusLogic Host Adapters and true clones support this command.  Adaptec 1542C
 841     series Host Adapters that respond to the Geometry Register I/O port will
 842     fail this command.  Interrupts must be disabled around the call to
 843     BusLogic_Command since a Command Complete interrupt could occur if the IRQ
 844     Channel was previously enabled for another BusLogic Host Adapter sharing
 845     the same IRQ Channel.
 846   */
 847   save_flags(ProcessorFlags);
 848   cli();
 849   RequestedReplyLength = sizeof(ExtendedSetupInformation);
 850   Result = BusLogic_Command(HostAdapter,
 851                             BusLogic_InquireExtendedSetupInformation,
 852                             &RequestedReplyLength, sizeof(RequestedReplyLength),
 853                             &ExtendedSetupInformation,
 854                             sizeof(ExtendedSetupInformation));
 855   restore_flags(ProcessorFlags);
 856   if (BusLogic_GlobalOptions & BusLogic_TraceProbe)
 857     printk("BusLogic_Check(0x%X): Result %d\n",
 858            HostAdapter->IO_Address, Result);
 859   return (Result == sizeof(ExtendedSetupInformation));
 860 }
 861 
 862 
 863 /*
 864   BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
 865   from Host Adapter.
 866 */
 867 
 868 static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T
     /* [previous][next][first][last][top][bottom][index][help] */
 869                                                      *HostAdapter)
 870 {
 871   BusLogic_BoardID_T BoardID;
 872   BusLogic_Configuration_T Configuration;
 873   BusLogic_SetupInformation_T SetupInformation;
 874   BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
 875   BusLogic_BoardModelNumber_T BoardModelNumber;
 876   BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
 877   BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
 878   BusLogic_GenericIOPortInformation_T GenericIOPortInformation;
 879   BusLogic_FetchHostAdapterLocalRAMRequest_T FetchHostAdapterLocalRAMRequest;
 880   BusLogic_AutoSCSIByte15_T AutoSCSIByte15;
 881   BusLogic_RequestedReplyLength_T RequestedReplyLength;
 882   unsigned char GeometryRegister, *TargetPointer, Character;
 883   unsigned short AllTargetsMask, DisconnectPermitted;
 884   unsigned short TaggedQueuingPermitted, TaggedQueuingPermittedDefault;
 885   boolean CommonErrorRecovery;
 886   int TargetID, i;
 887   /*
 888     Issue the Inquire Board ID command.
 889   */
 890   if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0,
 891                        &BoardID, sizeof(BoardID)) != sizeof(BoardID))
 892     return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
 893   /*
 894     Issue the Inquire Configuration command.
 895   */
 896   if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0,
 897                        &Configuration, sizeof(Configuration))
 898       != sizeof(Configuration))
 899     return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
 900   /*
 901     Issue the Inquire Setup Information command.
 902   */
 903   RequestedReplyLength = sizeof(SetupInformation);
 904   if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
 905                        &RequestedReplyLength, sizeof(RequestedReplyLength),
 906                        &SetupInformation, sizeof(SetupInformation))
 907       != sizeof(SetupInformation))
 908     return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
 909   /*
 910     Issue the Inquire Extended Setup Information command.
 911   */
 912   RequestedReplyLength = sizeof(ExtendedSetupInformation);
 913   if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation,
 914                        &RequestedReplyLength, sizeof(RequestedReplyLength),
 915                        &ExtendedSetupInformation,
 916                        sizeof(ExtendedSetupInformation))
 917       != sizeof(ExtendedSetupInformation))
 918     return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
 919   /*
 920     Issue the Inquire Board Model Number command.
 921   */
 922   if (!(BoardID.FirmwareVersion1stDigit == '2' &&
 923         ExtendedSetupInformation.BusType == 'A'))
 924     {
 925       RequestedReplyLength = sizeof(BoardModelNumber);
 926       if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardModelNumber,
 927                            &RequestedReplyLength, sizeof(RequestedReplyLength),
 928                            &BoardModelNumber, sizeof(BoardModelNumber))
 929           != sizeof(BoardModelNumber))
 930         return BusLogic_Failure(HostAdapter, "INQUIRE BOARD MODEL NUMBER");
 931     }
 932   else strcpy(BoardModelNumber, "542B");
 933   /*
 934     Issue the Inquire Firmware Version 3rd Digit command.
 935   */
 936   if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit,
 937                        NULL, 0, &FirmwareVersion3rdDigit,
 938                        sizeof(FirmwareVersion3rdDigit))
 939       != sizeof(FirmwareVersion3rdDigit))
 940     return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
 941   /*
 942     Issue the Inquire Firmware Version Letter command.
 943   */
 944   FirmwareVersionLetter = '\0';
 945   if (BoardID.FirmwareVersion1stDigit > '3' ||
 946       (BoardID.FirmwareVersion1stDigit == '3' &&
 947        BoardID.FirmwareVersion2ndDigit >= '3'))
 948     if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter,
 949                          NULL, 0, &FirmwareVersionLetter,
 950                          sizeof(FirmwareVersionLetter))
 951         != sizeof(FirmwareVersionLetter))
 952       return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE VERSION LETTER");
 953   /*
 954     BusLogic Host Adapters can be identified by their model number and
 955     the major version number of their firmware as follows:
 956 
 957     5.xx        BusLogic "W" Series Host Adapters:
 958                   BT-948/958/958D
 959     4.xx        BusLogic "C" Series Host Adapters:
 960                   BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
 961     3.xx        BusLogic "S" Series Host Adapters:
 962                   BT-747S/747D/757S/757D/445S/545S/542D
 963                   BT-542B/742A (revision H)
 964     2.xx        BusLogic "A" Series Host Adapters:
 965                   BT-542B/742A (revision G and below)
 966     0.xx        AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
 967   */
 968   /*
 969     Issue the Inquire Generic I/O Port Information command to read the
 970     termination information from "W" Series Host Adapters.
 971   */
 972   if (BoardID.FirmwareVersion1stDigit == '5')
 973     {
 974       if (BusLogic_Command(HostAdapter,
 975                            BusLogic_InquireGenericIOPortInformation,
 976                            NULL, 0, &GenericIOPortInformation,
 977                            sizeof(GenericIOPortInformation))
 978           != sizeof(GenericIOPortInformation))
 979         return BusLogic_Failure(HostAdapter,
 980                                 "INQUIRE GENERIC I/O PORT INFORMATION");
 981       /*
 982         Save the Termination Information in the Host Adapter structure.
 983       */
 984       if (GenericIOPortInformation.Valid)
 985         {
 986           HostAdapter->TerminationInfoValid = true;
 987           HostAdapter->LowByteTerminated =
 988             GenericIOPortInformation.LowByteTerminated;
 989           HostAdapter->HighByteTerminated =
 990             GenericIOPortInformation.HighByteTerminated;
 991         }
 992     }
 993   /*
 994     Issue the Fetch Host Adapter Local RAM command to read the termination
 995     information from the AutoSCSI area of "C" Series Host Adapters.
 996   */
 997   if (BoardID.FirmwareVersion1stDigit == '4')
 998     {
 999       FetchHostAdapterLocalRAMRequest.ByteOffset =
1000         BusLogic_AutoSCSI_BaseOffset + 15;
1001       FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIByte15);
1002       if (BusLogic_Command(HostAdapter,
1003                            BusLogic_FetchHostAdapterLocalRAM,
1004                            &FetchHostAdapterLocalRAMRequest,
1005                            sizeof(FetchHostAdapterLocalRAMRequest),
1006                            &AutoSCSIByte15, sizeof(AutoSCSIByte15))
1007           != sizeof(AutoSCSIByte15))
1008         return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
1009       /*
1010         Save the Termination Information in the Host Adapter structure.
1011       */
1012       HostAdapter->TerminationInfoValid = true;
1013       HostAdapter->LowByteTerminated = AutoSCSIByte15.LowByteTerminated;
1014       HostAdapter->HighByteTerminated = AutoSCSIByte15.HighByteTerminated;
1015     }
1016   /*
1017     Save the Model Name and Board Name in the Host Adapter structure.
1018   */
1019   TargetPointer = HostAdapter->ModelName;
1020   *TargetPointer++ = 'B';
1021   *TargetPointer++ = 'T';
1022   *TargetPointer++ = '-';
1023   for (i = 0; i < sizeof(BoardModelNumber); i++)
1024     {
1025       Character = BoardModelNumber[i];
1026       if (Character == ' ' || Character == '\0') break;
1027       *TargetPointer++ = Character;
1028     }
1029   *TargetPointer++ = '\0';
1030   strcpy(HostAdapter->BoardName, "BusLogic ");
1031   strcat(HostAdapter->BoardName, HostAdapter->ModelName);
1032   strcpy(HostAdapter->InterruptLabel, HostAdapter->BoardName);
1033   /*
1034     Save the Firmware Version in the Host Adapter structure.
1035   */
1036   TargetPointer = HostAdapter->FirmwareVersion;
1037   *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
1038   *TargetPointer++ = '.';
1039   *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
1040   if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
1041     *TargetPointer++ = FirmwareVersion3rdDigit;
1042   if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
1043     *TargetPointer++ = FirmwareVersionLetter;
1044   *TargetPointer++ = '\0';
1045   /*
1046     Determine the IRQ Channel and save it in the Host Adapter structure.
1047   */
1048   if (Configuration.IRQ_Channel9)
1049     HostAdapter->IRQ_Channel = 9;
1050   else if (Configuration.IRQ_Channel10)
1051     HostAdapter->IRQ_Channel = 10;
1052   else if (Configuration.IRQ_Channel11)
1053     HostAdapter->IRQ_Channel = 11;
1054   else if (Configuration.IRQ_Channel12)
1055     HostAdapter->IRQ_Channel = 12;
1056   else if (Configuration.IRQ_Channel14)
1057     HostAdapter->IRQ_Channel = 14;
1058   else if (Configuration.IRQ_Channel15)
1059     HostAdapter->IRQ_Channel = 15;
1060   /*
1061     Determine the DMA Channel and save it in the Host Adapter structure.
1062   */
1063   if (Configuration.DMA_Channel5)
1064     HostAdapter->DMA_Channel = 5;
1065   else if (Configuration.DMA_Channel6)
1066     HostAdapter->DMA_Channel = 6;
1067   else if (Configuration.DMA_Channel7)
1068     HostAdapter->DMA_Channel = 7;
1069   /*
1070     Save the Host Adapter SCSI ID in the Host Adapter structure.
1071   */
1072   HostAdapter->SCSI_ID = Configuration.HostAdapterID;
1073   /*
1074     Save the Synchronous Initiation flag and SCSI Parity Checking flag
1075     in the Host Adapter structure.
1076   */
1077   HostAdapter->SynchronousInitiation =
1078     SetupInformation.SynchronousInitiationEnabled;
1079   HostAdapter->ParityChecking = SetupInformation.ParityCheckEnabled;
1080   /*
1081     Determine the Bus Type and save it in the Host Adapter structure,
1082     overriding the DMA Channel if it is inappropriate for the bus type.
1083   */
1084   switch (HostAdapter->ModelName[3])
1085     {
1086     case '4':
1087       HostAdapter->BusType = BusLogic_VESA_Bus;
1088       HostAdapter->DMA_Channel = 0;
1089       break;
1090     case '5':
1091       HostAdapter->BusType = BusLogic_ISA_Bus;
1092       break;
1093     case '6':
1094       HostAdapter->BusType = BusLogic_MCA_Bus;
1095       HostAdapter->DMA_Channel = 0;
1096       break;
1097     case '7':
1098       HostAdapter->BusType = BusLogic_EISA_Bus;
1099       HostAdapter->DMA_Channel = 0;
1100       break;
1101     case '9':
1102       HostAdapter->BusType = BusLogic_PCI_Bus;
1103       HostAdapter->DMA_Channel = 0;
1104       break;
1105     }
1106   /*
1107     Determine whether Extended Translation is enabled and save it in
1108     the Host Adapter structure.
1109   */
1110   GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
1111   if (GeometryRegister & BusLogic_ExtendedTranslationEnabled)
1112     HostAdapter->ExtendedTranslation = true;
1113   /*
1114     Save the Disconnect/Reconnect Permitted flag bits in the Host Adapter
1115     structure.  The Disconnect Permitted information is only valid on "W" and
1116     "C" Series boards, but Disconnect/Reconnect is always permitted on "S" and
1117     "A" Series boards.
1118   */
1119   if (HostAdapter->FirmwareVersion[0] >= '4')
1120     HostAdapter->DisconnectPermitted =
1121       (SetupInformation.DisconnectPermittedID8to15 << 8)
1122       | SetupInformation.DisconnectPermittedID0to7;
1123   else HostAdapter->DisconnectPermitted = 0xFF;
1124   /*
1125     Save the Scatter Gather Limits, Level Sensitive Interrupts flag, Wide
1126     SCSI flag, Differential SCSI flag, Automatic Configuration flag, and
1127     Ultra SCSI flag in the Host Adapter structure.
1128   */
1129   HostAdapter->HostAdapterScatterGatherLimit =
1130     ExtendedSetupInformation.ScatterGatherLimit;
1131   HostAdapter->DriverScatterGatherLimit =
1132     HostAdapter->HostAdapterScatterGatherLimit;
1133   if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
1134     HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1135   if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupts)
1136     HostAdapter->LevelSensitiveInterrupts = true;
1137   HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
1138   HostAdapter->HostDifferentialSCSI =
1139     ExtendedSetupInformation.HostDifferentialSCSI;
1140   HostAdapter->HostAutomaticConfiguration =
1141     ExtendedSetupInformation.HostAutomaticConfiguration;
1142   HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
1143   /*
1144     Determine the Host Adapter BIOS Address if the BIOS is enabled and
1145     save it in the Host Adapter structure.  The BIOS is disabled if the
1146     BIOS_Address is 0.
1147   */
1148   HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
1149   /*
1150     ISA Host Adapters require Bounce Buffers if there is more than 16MB memory.
1151   */
1152   if (HostAdapter->BusType == BusLogic_ISA_Bus && high_memory > MAX_DMA_ADDRESS)
1153     HostAdapter->BounceBuffersRequired = true;
1154   /*
1155     BusLogic BT-445S Host Adapters prior to board revision E have a hardware
1156     bug whereby when the BIOS is enabled, transfers to/from the same address
1157     range the BIOS occupies modulo 16MB are handled incorrectly.  Only properly
1158     functioning BT-445S boards have firmware version 3.37, so we require that
1159     ISA Bounce Buffers be used for the buggy BT-445S models if there is more
1160     than 16MB memory.
1161   */
1162   if (HostAdapter->BIOS_Address > 0 &&
1163       strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
1164       strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 &&
1165       high_memory > MAX_DMA_ADDRESS)
1166     HostAdapter->BounceBuffersRequired = true;
1167   /*
1168     Determine the maximum number of Target IDs and Logical Units supported by
1169     this driver for Wide and Narrow Host Adapters.
1170   */
1171   if (HostAdapter->HostWideSCSI)
1172     {
1173       HostAdapter->MaxTargetDevices = 16;
1174       HostAdapter->MaxLogicalUnits = 64;
1175     }
1176   else
1177     {
1178       HostAdapter->MaxTargetDevices = 8;
1179       HostAdapter->MaxLogicalUnits = 8;
1180     }
1181   /*
1182     Select appropriate values for the Mailbox Count, Initial CCBs, and
1183     Incremental CCBs variables based on whether or not Strict Round Robin Mode
1184     is supported.  If Strict Round Robin Mode is supported, then there is no
1185     performance degradation in using the maximum possible number of Outgoing
1186     and Incoming Mailboxes and allowing the Tagged and Untagged Queue Depths to
1187     determine the actual utilization.  If Strict Round Robin Mode is not
1188     supported, then the Host Adapter must scan all the Outgoing Mailboxes
1189     whenever an Outgoing Mailbox entry is made, which can cause a substantial
1190     performance penalty.  The Host Adapters actually have room to store the
1191     following number of CCBs internally; that is, they can internally queue and
1192     manage this many active commands on the SCSI bus simultaneously.
1193     Performance measurements demonstrate that the Mailbox Count should be set
1194     to the maximum possible, rather than the internal CCB capacity, as it is
1195     more efficient to have the queued commands waiting in Outgoing Mailboxes if
1196     necessary than to block the process in the higher levels of the SCSI
1197     Subsystem.
1198 
1199         192       BT-948/958/958D
1200         100       BT-946C/956C/956CD/747C/757C/757CD/445C
1201          50       BT-545C/540CF
1202          30       BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
1203   */
1204   if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
1205     {
1206       HostAdapter->StrictRoundRobinModeSupported = true;
1207       HostAdapter->MailboxCount = 255;
1208       HostAdapter->InitialCCBs = 64;
1209       HostAdapter->IncrementalCCBs = 32;
1210     }
1211   else
1212     {
1213       HostAdapter->StrictRoundRobinModeSupported = false;
1214       HostAdapter->MailboxCount = 32;
1215       HostAdapter->InitialCCBs = 32;
1216       HostAdapter->IncrementalCCBs = 4;
1217     }
1218   if (HostAdapter->FirmwareVersion[0] == '5')
1219     HostAdapter->TotalQueueDepth = 192;
1220   else if (HostAdapter->FirmwareVersion[0] == '4')
1221     HostAdapter->TotalQueueDepth =
1222       (HostAdapter->BusType != BusLogic_ISA_Bus ? 100 : 50);
1223   else HostAdapter->TotalQueueDepth = 30;
1224   /*
1225     Select an appropriate value for the Tagged Queue Depth either from a
1226     Command Line Entry, or based on whether this Host Adapter requires that
1227     ISA Bounce Buffers be used.  The Tagged Queue Depth is left at 0 for
1228     automatic determination in BusLogic_SelectQueueDepths.  Initialize the
1229     Untagged Queue Depth.
1230   */
1231   if (HostAdapter->CommandLineEntry != NULL &&
1232       HostAdapter->CommandLineEntry->TaggedQueueDepth > 0)
1233     HostAdapter->TaggedQueueDepth =
1234       HostAdapter->CommandLineEntry->TaggedQueueDepth;
1235   else if (HostAdapter->BounceBuffersRequired)
1236     HostAdapter->TaggedQueueDepth = BusLogic_TaggedQueueDepth_BB;
1237   else HostAdapter->TaggedQueueDepth = 0;
1238   HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
1239   if (HostAdapter->UntaggedQueueDepth > HostAdapter->TaggedQueueDepth &&
1240       HostAdapter->TaggedQueueDepth > 0)
1241     HostAdapter->UntaggedQueueDepth = HostAdapter->TaggedQueueDepth;
1242   /*
1243     Select an appropriate value for Bus Settle Time either from a Command
1244     Line Entry, or from BusLogic_DefaultBusSettleTime.
1245   */
1246   if (HostAdapter->CommandLineEntry != NULL &&
1247       HostAdapter->CommandLineEntry->BusSettleTime > 0)
1248     HostAdapter->BusSettleTime = HostAdapter->CommandLineEntry->BusSettleTime;
1249   else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
1250   /*
1251     Select an appropriate value for Local Options from a Command Line Entry.
1252   */
1253   if (HostAdapter->CommandLineEntry != NULL)
1254     HostAdapter->LocalOptions = HostAdapter->CommandLineEntry->LocalOptions;
1255   /*
1256     Select appropriate values for the Error Recovery Strategy array either from
1257     a Command Line Entry, or using BusLogic_ErrorRecovery_Default.
1258   */
1259   if (HostAdapter->CommandLineEntry != NULL)
1260     memcpy(HostAdapter->ErrorRecoveryStrategy,
1261            HostAdapter->CommandLineEntry->ErrorRecoveryStrategy,
1262            sizeof(HostAdapter->ErrorRecoveryStrategy));
1263   else memset(HostAdapter->ErrorRecoveryStrategy,
1264               BusLogic_ErrorRecovery_Default,
1265               sizeof(HostAdapter->ErrorRecoveryStrategy));
1266   /*
1267     Tagged Queuing support is available and operates properly on all "W" Series
1268     boards, on "C" Series boards with firmware version 4.22 and above, and on
1269     "S" Series boards with firmware version 3.35 and above.  Tagged Queuing is
1270     disabled by default when the Tagged Queue Depth is 1 since queuing multiple
1271     commands is not possible.
1272   */
1273   TaggedQueuingPermittedDefault = 0;
1274   if (HostAdapter->TaggedQueueDepth != 1)
1275     switch (HostAdapter->FirmwareVersion[0])
1276       {
1277       case '5':
1278         TaggedQueuingPermittedDefault = 0xFFFF;
1279         break;
1280       case '4':
1281         if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
1282           TaggedQueuingPermittedDefault = 0xFFFF;
1283         break;
1284       case '3':
1285         if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
1286           TaggedQueuingPermittedDefault = 0xFFFF;
1287         break;
1288       }
1289   /*
1290     Tagged Queuing is only useful if Disconnect/Reconnect is permitted.
1291     Therefore, mask the Tagged Queuing Permitted Default bits with the
1292     Disconnect/Reconnect Permitted bits.
1293   */
1294   TaggedQueuingPermittedDefault &= HostAdapter->DisconnectPermitted;
1295   /*
1296     Combine the default Tagged Queuing Permitted bits with any Command
1297     Line Entry Tagged Queuing specification.
1298   */
1299   if (HostAdapter->CommandLineEntry != NULL)
1300     HostAdapter->TaggedQueuingPermitted =
1301       (HostAdapter->CommandLineEntry->TaggedQueuingPermitted &
1302        HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask) |
1303       (TaggedQueuingPermittedDefault &
1304        ~HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask);
1305   else HostAdapter->TaggedQueuingPermitted = TaggedQueuingPermittedDefault;
1306   /*
1307     Announce the Host Adapter Configuration.
1308   */
1309   printk("scsi%d: Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
1310          HostAdapter->HostNumber, HostAdapter->ModelName,
1311          BusLogic_BusNames[HostAdapter->BusType],
1312          (HostAdapter->HostWideSCSI ? " Wide" : ""),
1313          (HostAdapter->HostDifferentialSCSI ? " Differential" : ""),
1314          (HostAdapter->HostUltraSCSI ? " Ultra" : ""));
1315   printk("scsi%d:   Firmware Version: %s, I/O Address: 0x%X, "
1316          "IRQ Channel: %d/%s\n",
1317          HostAdapter->HostNumber, HostAdapter->FirmwareVersion,
1318          HostAdapter->IO_Address, HostAdapter->IRQ_Channel,
1319          (HostAdapter->LevelSensitiveInterrupts ? "Level" : "Edge"));
1320   printk("scsi%d:   DMA Channel: ", HostAdapter->HostNumber);
1321   if (HostAdapter->DMA_Channel > 0)
1322     printk("%d, ", HostAdapter->DMA_Channel);
1323   else printk("None, ");
1324   if (HostAdapter->BIOS_Address > 0)
1325     printk("BIOS Address: 0x%lX, ", HostAdapter->BIOS_Address);
1326   else printk("BIOS Address: None, ");
1327   printk("Host Adapter SCSI ID: %d\n", HostAdapter->SCSI_ID);
1328   printk("scsi%d:   Scatter/Gather Limit: %d of %d segments, "
1329          "Parity Checking: %s\n", HostAdapter->HostNumber,
1330          HostAdapter->DriverScatterGatherLimit,
1331          HostAdapter->HostAdapterScatterGatherLimit,
1332          (HostAdapter->ParityChecking ? "Enabled" : "Disabled"));
1333   printk("scsi%d:   Synchronous Initiation: %s, "
1334          "Extended Disk Translation: %s\n", HostAdapter->HostNumber,
1335          (HostAdapter->SynchronousInitiation ? "Enabled" : "Disabled"),
1336          (HostAdapter->ExtendedTranslation ? "Enabled" : "Disabled"));
1337   AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
1338   DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
1339   printk("scsi%d:   Disconnect/Reconnect: ", HostAdapter->HostNumber);
1340   if (DisconnectPermitted == 0)
1341     printk("Disabled");
1342   else if (DisconnectPermitted == AllTargetsMask)
1343     printk("Enabled");
1344   else
1345     for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1346       printk("%c", (DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
1347   printk(", Tagged Queuing: ");
1348   TaggedQueuingPermitted =
1349     HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
1350   if (TaggedQueuingPermitted == 0)
1351     printk("Disabled");
1352   else if (TaggedQueuingPermitted == AllTargetsMask)
1353     printk("Enabled");
1354   else
1355     for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1356       printk("%c", (TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
1357   printk("\n");
1358   printk("scsi%d:   Total Queue Depth: %d, Mailboxes: %d, Initial CCBs: %d\n",
1359          HostAdapter->HostNumber, HostAdapter->TotalQueueDepth,
1360          HostAdapter->MailboxCount, HostAdapter->InitialCCBs);
1361   printk("scsi%d:   Tagged Queue Depth: ", HostAdapter->HostNumber);
1362   if (HostAdapter->TaggedQueueDepth > 0)
1363     printk("%d", HostAdapter->TaggedQueueDepth);
1364   else printk("Automatic");
1365   printk(", Untagged Queue Depth: %d\n", HostAdapter->UntaggedQueueDepth);
1366   if (HostAdapter->TerminationInfoValid)
1367     if (HostAdapter->HostWideSCSI)
1368       printk("scsi%d:   Host Adapter SCSI Bus Termination (Low/High): %s/%s\n",
1369              HostAdapter->HostNumber,
1370              (HostAdapter->LowByteTerminated ? "Enabled" : "Disabled"),
1371              (HostAdapter->HighByteTerminated ? "Enabled" : "Disabled"));
1372     else printk("scsi%d:   Host Adapter SCSI Bus Termination: %s\n",
1373                 HostAdapter->HostNumber,
1374                 (HostAdapter->LowByteTerminated ? "Enabled" : "Disabled"));
1375   CommonErrorRecovery = true;
1376   for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1377     if (HostAdapter->ErrorRecoveryStrategy[TargetID] !=
1378         HostAdapter->ErrorRecoveryStrategy[0])
1379       {
1380         CommonErrorRecovery = false;
1381         break;
1382       }
1383   printk("scsi%d:   Error Recovery Strategy: ", HostAdapter->HostNumber);
1384   if (CommonErrorRecovery)
1385     printk("%s", BusLogic_ErrorRecoveryStrategyNames[
1386                    HostAdapter->ErrorRecoveryStrategy[0]]);
1387   else
1388     for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1389       printk("%s", BusLogic_ErrorRecoveryStrategyLetters[
1390                      HostAdapter->ErrorRecoveryStrategy[TargetID]]);
1391   printk("\n");
1392   /*
1393     Indicate reading the Host Adapter Configuration completed successfully.
1394   */
1395   return true;
1396 }
1397 
1398 
1399 /*
1400   BusLogic_AcquireResources acquires the system resources necessary to use
1401   Host Adapter.
1402 */
1403 
1404 static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter)
     /* [previous][next][first][last][top][bottom][index][help] */
1405 {
1406   if (HostAdapter->IRQ_Channel == 0)
1407     {
1408       printk("scsi%d: NO INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
1409              HostAdapter->HostNumber);
1410       return false;
1411     }
1412   /*
1413     Acquire exclusive or shared access to the IRQ Channel.  A usage count is
1414     maintained so that PCI, EISA, or MCA shared interrupts can be supported.
1415   */
1416   if (BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]++ == 0)
1417     {
1418       if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
1419                       SA_INTERRUPT | SA_SHIRQ,
1420                       HostAdapter->InterruptLabel, NULL) < 0)
1421         {
1422           BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]--;
1423           printk("scsi%d: UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
1424                  HostAdapter->HostNumber, HostAdapter->IRQ_Channel);
1425           return false;
1426         }
1427     }
1428   else
1429     {
1430       BusLogic_HostAdapter_T *FirstHostAdapter =
1431         BusLogic_RegisteredHostAdapters;
1432       while (FirstHostAdapter != NULL)
1433         {
1434           if (FirstHostAdapter->IRQ_Channel == HostAdapter->IRQ_Channel)
1435             {
1436               if (strlen(FirstHostAdapter->InterruptLabel) + 11
1437                   < sizeof(FirstHostAdapter->InterruptLabel))
1438                 {
1439                   strcat(FirstHostAdapter->InterruptLabel, " + ");
1440                   strcat(FirstHostAdapter->InterruptLabel,
1441                          HostAdapter->ModelName);
1442                 }
1443               break;
1444             }
1445           FirstHostAdapter = FirstHostAdapter->Next;
1446         }
1447     }
1448   HostAdapter->IRQ_ChannelAcquired = true;
1449   /*
1450     Acquire exclusive access to the DMA Channel.
1451   */
1452   if (HostAdapter->DMA_Channel > 0)
1453     {
1454       if (request_dma(HostAdapter->DMA_Channel, HostAdapter->BoardName) < 0)
1455         {
1456           printk("scsi%d: UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
1457                  HostAdapter->HostNumber, HostAdapter->DMA_Channel);
1458           return false;
1459         }
1460       set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
1461       enable_dma(HostAdapter->DMA_Channel);
1462       HostAdapter->DMA_ChannelAcquired = true;
1463     }
1464   /*
1465     Indicate the System Resource Acquisition completed successfully,
1466   */
1467   return true;
1468 }
1469 
1470 
1471 /*
1472   BusLogic_ReleaseResources releases any system resources previously acquired
1473   by BusLogic_AcquireResources.
1474 */
1475 
1476 static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
     /* [previous][next][first][last][top][bottom][index][help] */
1477 {
1478   /*
1479     Release exclusive or shared access to the IRQ Channel.
1480   */
1481   if (HostAdapter->IRQ_ChannelAcquired)
1482     if (--BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9] == 0)
1483       free_irq(HostAdapter->IRQ_Channel, NULL);
1484   /*
1485     Release exclusive access to the DMA Channel.
1486   */
1487   if (HostAdapter->DMA_ChannelAcquired)
1488     free_dma(HostAdapter->DMA_Channel);
1489 }
1490 
1491 
1492 /*
1493   BusLogic_TestInterrupts tests for proper functioning of the Host Adapter
1494   Interrupt Register and that interrupts generated by the Host Adapter are
1495   getting through to the Interrupt Handler.  A large proportion of initial
1496   problems with installing PCI Host Adapters are due to configuration problems
1497   where either the Host Adapter or Motherboard is configured incorrectly, and
1498   interrupts do not get through as a result.
1499 */
1500 
1501 static boolean BusLogic_TestInterrupts(BusLogic_HostAdapter_T *HostAdapter)
     /* [previous][next][first][last][top][bottom][index][help] */
1502 {
1503   unsigned int InitialInterruptCount, FinalInterruptCount;
1504   int TestCount = 5, i;
1505   InitialInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel];
1506   /*
1507     Issue the Test Command Complete Interrupt commands.
1508   */
1509   for (i = 0; i < TestCount; i++)
1510     BusLogic_Command(HostAdapter, BusLogic_TestCommandCompleteInterrupt,
1511                      NULL, 0, NULL, 0);
1512   /*
1513     Verify that BusLogic_InterruptHandler was called at least TestCount times.
1514     Shared IRQ Channels could cause more than TestCount interrupts to occur,
1515     but there should never be fewer than TestCount.
1516   */
1517   FinalInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel];
1518   if (FinalInterruptCount < InitialInterruptCount + TestCount)
1519     {
1520       BusLogic_Failure(HostAdapter, "HOST ADAPTER INTERRUPT TEST");
1521       printk("\n\
1522 Interrupts are not getting through from the Host Adapter to the BusLogic\n\
1523 Driver Interrupt Handler. The most likely cause is that either the Host\n\
1524 Adapter or Motherboard is configured incorrectly.  Please check the Host\n\
1525 Adapter configuration with AutoSCSI or by examining any dip switch and\n\
1526 jumper settings on the Host Adapter, and verify that no other device is\n\
1527 attempting to use the same IRQ Channel.  For PCI Host Adapters, it may also\n\
1528 be necessary to investigate and manually set the PCI interrupt assignments\n\
1529 and edge/level interrupt type selection in the BIOS Setup Program or with\n\
1530 Motherboard jumpers.\n\n");
1531       return false;
1532     }
1533   /*
1534     Indicate the Host Adapter Interrupt Test completed successfully.
1535   */
1536   return true;
1537 }
1538 
1539 
1540 /*
1541   BusLogic_InitializeHostAdapter initializes Host Adapter.  This is the only
1542   function called during SCSI Host Adapter detection which modifies the state
1543   of the Host Adapter from its initial power on or hard reset state.
1544 */
1545 
1546 static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T
     /* [previous][next][first][last][top][bottom][index][help] */
1547                                               *HostAdapter)
1548 {
1549   BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
1550   BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
1551   BusLogic_WideModeCCBRequest_T WideModeCCBRequest;
1552   BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
1553   int TargetID;
1554   /*
1555     Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
1556     Command Successful Flag, Active Command Count, and Total Command Count
1557     for each Target Device.
1558   */
1559   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1560     HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
1561   memset(HostAdapter->TaggedQueuingActive, false,
1562          sizeof(HostAdapter->TaggedQueuingActive));
1563   memset(HostAdapter->CommandSuccessfulFlag, false,
1564          sizeof(HostAdapter->CommandSuccessfulFlag));
1565   memset(HostAdapter->ActiveCommandCount, 0,
1566          sizeof(HostAdapter->ActiveCommandCount));
1567   memset(HostAdapter->TotalCommandCount, 0,
1568          sizeof(HostAdapter->TotalCommandCount));
1569   /*
1570     Initialize the Outgoing and Incoming Mailbox structures.
1571   */
1572   memset(HostAdapter->FirstOutgoingMailbox, 0,
1573          HostAdapter->MailboxCount * sizeof(BusLogic_OutgoingMailbox_T));
1574   memset(HostAdapter->FirstIncomingMailbox, 0,
1575          HostAdapter->MailboxCount * sizeof(BusLogic_IncomingMailbox_T));
1576   /*
1577     Initialize the pointers to the Next Mailboxes.
1578   */
1579   HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
1580   HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
1581   /*
1582     Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
1583   */
1584   ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
1585   ExtendedMailboxRequest.BaseMailboxAddress = HostAdapter->FirstOutgoingMailbox;
1586   if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox,
1587                        &ExtendedMailboxRequest,
1588                        sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
1589     return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
1590   /*
1591     Enable Strict Round Robin Mode if supported by the Host Adapter.  In
1592     Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
1593     Mailbox for each new command, rather than scanning through all the
1594     Outgoing Mailboxes to find any that have new commands in them.  Strict
1595     Round Robin Mode is significantly more efficient.
1596   */
1597   if (HostAdapter->StrictRoundRobinModeSupported)
1598     {
1599       RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
1600       if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
1601                            &RoundRobinModeRequest,
1602                            sizeof(RoundRobinModeRequest), NULL, 0) < 0)
1603         return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
1604     }
1605   /*
1606     For Wide SCSI Host Adapters, issue the Enable Wide Mode CCB command to
1607     allow more than 8 Logical Units per Target Device to be supported.
1608   */
1609   if (HostAdapter->HostWideSCSI)
1610     {
1611       WideModeCCBRequest = BusLogic_WideModeCCB;
1612       if (BusLogic_Command(HostAdapter, BusLogic_EnableWideModeCCB,
1613                            &WideModeCCBRequest,
1614                            sizeof(WideModeCCBRequest), NULL, 0) < 0)
1615         return BusLogic_Failure(HostAdapter, "ENABLE WIDE MODE CCB");
1616     }
1617   /*
1618     For PCI Host Adapters being accessed through the PCI compliant I/O
1619     Address, disable the ISA compatible I/O Address to avoid detecting the
1620     same Host Adapter at both I/O Addresses.
1621   */
1622   if (HostAdapter->BusType == BusLogic_PCI_Bus)
1623     {
1624       int Index;
1625       for (Index = 0; BusLogic_IO_StandardAddresses[Index] > 0; Index++)
1626         if (HostAdapter->IO_Address == BusLogic_IO_StandardAddresses[Index])
1627           break;
1628       if (BusLogic_IO_StandardAddresses[Index] == 0)
1629         {
1630           ModifyIOAddressRequest = BusLogic_ModifyIO_Disable;
1631           if (BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress,
1632                                &ModifyIOAddressRequest,
1633                                sizeof(ModifyIOAddressRequest), NULL, 0) < 0)
1634             return BusLogic_Failure(HostAdapter, "MODIFY I/O ADDRESS");
1635         }
1636     }
1637   /*
1638     Announce Successful Initialization.
1639   */
1640   printk("scsi%d: *** %s Initialized Successfully ***\n",
1641          HostAdapter->HostNumber, HostAdapter->BoardName);
1642   /*
1643     Indicate the Host Adapter Initialization completed successfully.
1644   */
1645   return true;
1646 }
1647 
1648 
1649 /*
1650   BusLogic_InquireTargetDevices inquires about the Target Devices accessible
1651   through Host Adapter and reports on the results.
1652 */
1653 
1654 static boolean BusLogic_InquireTargetDevices(BusLogic_HostAdapter_T
     /* [previous][next][first][last][top][bottom][index][help] */
1655                                              *HostAdapter)
1656 {
1657   BusLogic_InstalledDevices_T InstalledDevices;
1658   BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
1659   BusLogic_SetupInformation_T SetupInformation;
1660   BusLogic_SynchronousPeriod_T SynchronousPeriod;
1661   BusLogic_RequestedReplyLength_T RequestedReplyLength;
1662   int TargetDevicesFound = 0, TargetID;
1663   /*
1664     Wait a few seconds between the Host Adapter Hard Reset which initiates
1665     a SCSI Bus Reset and issuing any SCSI Commands.  Some SCSI devices get
1666     confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
1667   */
1668   BusLogic_Delay(HostAdapter->BusSettleTime);
1669   /*
1670     Inhibit the Target Devices Inquiry if requested.
1671   */
1672   if (HostAdapter->LocalOptions & BusLogic_InhibitTargetInquiry)
1673     {
1674       printk("scsi%d:   Target Device Inquiry Inhibited\n",
1675              HostAdapter->HostNumber);
1676       return true;
1677     }
1678   /*
1679     Issue the Inquire Devices command for boards with firmware version 4.25 or
1680     later, or the Inquire Installed Devices ID 0 to 7 command for older boards.
1681     This is necessary to force Synchronous Transfer Negotiation so that the
1682     Inquire Setup Information and Inquire Synchronous Period commands will
1683     return valid data.  The Inquire Devices command is preferable to Inquire
1684     Installed Devices ID 0 to 7 since it only probes Logical Unit 0 of each
1685     Target Device.
1686   */
1687   if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0)
1688     {
1689       if (BusLogic_Command(HostAdapter, BusLogic_InquireDevices, NULL, 0,
1690                            &InstalledDevices, sizeof(InstalledDevices))
1691           != sizeof(InstalledDevices))
1692         return BusLogic_Failure(HostAdapter, "INQUIRE DEVICES");
1693     }
1694   else
1695     {
1696       if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7,
1697                            NULL, 0, &InstalledDevicesID0to7,
1698                            sizeof(InstalledDevicesID0to7))
1699           != sizeof(InstalledDevicesID0to7))
1700         return BusLogic_Failure(HostAdapter,
1701                                 "INQUIRE INSTALLED DEVICES ID 0 TO 7");
1702       InstalledDevices = 0;
1703       for (TargetID = 0; TargetID < 8; TargetID++)
1704         if (InstalledDevicesID0to7[TargetID] != 0)
1705           InstalledDevices |= (1 << TargetID);
1706     }
1707   /*
1708     Issue the Inquire Setup Information command.
1709   */
1710   RequestedReplyLength = sizeof(SetupInformation);
1711   if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
1712                        &RequestedReplyLength, sizeof(RequestedReplyLength),
1713                        &SetupInformation, sizeof(SetupInformation))
1714       != sizeof(SetupInformation))
1715     return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
1716   /*
1717     Issue the Inquire Synchronous Period command.
1718   */
1719   if (HostAdapter->FirmwareVersion[0] >= '3')
1720     {
1721       RequestedReplyLength = sizeof(SynchronousPeriod);
1722       if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod,
1723                            &RequestedReplyLength, sizeof(RequestedReplyLength),
1724                            &SynchronousPeriod, sizeof(SynchronousPeriod))
1725           != sizeof(SynchronousPeriod))
1726         return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
1727     }
1728   else
1729     for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1730       if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
1731         SynchronousPeriod[TargetID] =
1732           20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
1733                                    .TransferPeriod;
1734       else SynchronousPeriod[TargetID] = 0;
1735   /*
1736     Save the Installed Devices, Synchronous Values, and Synchronous Period
1737     information in the Host Adapter structure.
1738   */
1739   HostAdapter->InstalledDevices = InstalledDevices;
1740   memcpy(HostAdapter->SynchronousValues,
1741          SetupInformation.SynchronousValuesID0to7,
1742          sizeof(BusLogic_SynchronousValues8_T));
1743   if (HostAdapter->HostWideSCSI)
1744     memcpy(&HostAdapter->SynchronousValues[8],
1745            SetupInformation.SynchronousValuesID8to15,
1746            sizeof(BusLogic_SynchronousValues8_T));
1747   memcpy(HostAdapter->SynchronousPeriod, SynchronousPeriod,
1748          sizeof(BusLogic_SynchronousPeriod_T));
1749   /*
1750     Report on the Target Devices found.
1751   */
1752   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
1753     if (HostAdapter->InstalledDevices & (1 << TargetID))
1754       {
1755         int SynchronousPeriod = HostAdapter->SynchronousPeriod[TargetID];
1756         if (SynchronousPeriod > 10)
1757           {
1758             int SynchronousTransferRate = 100000000 / SynchronousPeriod;
1759             int RoundedSynchronousTransferRate =
1760               (SynchronousTransferRate + 5000) / 10000;
1761             printk("scsi%d:   Target %d: Synchronous at "
1762                    "%d.%02d mega-transfers/second, offset %d\n",
1763                    HostAdapter->HostNumber, TargetID,
1764                    RoundedSynchronousTransferRate / 100,
1765                    RoundedSynchronousTransferRate % 100,
1766                    HostAdapter->SynchronousValues[TargetID].Offset);
1767           }
1768         else if (SynchronousPeriod > 0)
1769           {
1770             int SynchronousTransferRate = 100000000 / SynchronousPeriod;
1771             int RoundedSynchronousTransferRate =
1772               (SynchronousTransferRate + 50000) / 100000;
1773             printk("scsi%d:   Target %d: Synchronous at "
1774                    "%d.%01d mega-transfers/second, offset %d\n",
1775                    HostAdapter->HostNumber, TargetID,
1776                    RoundedSynchronousTransferRate / 10,
1777                    RoundedSynchronousTransferRate % 10,
1778                    HostAdapter->SynchronousValues[TargetID].Offset);
1779           }
1780         else printk("scsi%d:   Target %d: Asynchronous\n",
1781                     HostAdapter->HostNumber, TargetID);
1782         TargetDevicesFound++;
1783       }
1784   if (TargetDevicesFound == 0)
1785     printk("scsi%d:   No Target Devices Found\n", HostAdapter->HostNumber);
1786   /*
1787     Indicate the Target Device Inquiry completed successfully.
1788   */
1789   return true;
1790 }
1791 
1792 
1793 /*
1794   BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
1795   structure.  The base, io_port, n_io_ports, irq, and dma_channel fields in the
1796   SCSI Host structure are intentionally left uninitialized, as this driver
1797   handles acquisition and release of these resources explicitly, as well as
1798   ensuring exclusive access to the Host Adapter hardware and data structures
1799   through explicit acquisition and release of the Host Adapter's Lock.
1800 */
1801 
1802 static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T
     /* [previous][next][first][last][top][bottom][index][help] */
1803                                                *HostAdapter,
1804                                              SCSI_Host_T *Host)
1805 {
1806   Host->max_id = HostAdapter->MaxTargetDevices;
1807   Host->max_lun = HostAdapter->MaxLogicalUnits;
1808   Host->max_channel = 0;
1809   Host->unique_id = HostAdapter->IO_Address;
1810   Host->this_id = HostAdapter->SCSI_ID;
1811   Host->can_queue = HostAdapter->MailboxCount;
1812   Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
1813   Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
1814   Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
1815 }
1816 
1817 
1818 /*
1819   BusLogic_SelectQueueDepths selects Queue Depths for each Target Device
1820   based on the Host Adapter's Total Queue Depth and the number, type, speed,
1821   and capabilities of the Target Devices.
1822 */
1823 
1824 static void BusLogic_SelectQueueDepths(SCSI_Host_T *Host,
     /* [previous][next][first][last][top][bottom][index][help] */
1825                                        SCSI_Device_T *DeviceList)
1826 {
1827   BusLogic_HostAdapter_T *HostAdapter =
1828     (BusLogic_HostAdapter_T *) Host->hostdata;
1829   int TaggedQueueDepth = HostAdapter->TaggedQueueDepth;
1830   int UntaggedQueueDepth = HostAdapter->UntaggedQueueDepth;
1831   int TaggedDeviceCount = 0, UntaggedDeviceCount = 0;
1832   SCSI_Device_T *Device;
1833   for (Device = DeviceList; Device != NULL; Device = Device->next)
1834     if (Device->host == Host)
1835       {
1836         if (Device->tagged_supported &&
1837             (HostAdapter->TaggedQueuingPermitted & (1 << Device->id)))
1838           TaggedDeviceCount++;
1839         else UntaggedDeviceCount++;
1840       }
1841   if (TaggedQueueDepth == 0 && TaggedDeviceCount > 0)
1842     TaggedQueueDepth =
1843       1 + ((HostAdapter->TotalQueueDepth
1844             - UntaggedDeviceCount * UntaggedQueueDepth)
1845            / TaggedDeviceCount);
1846   if (TaggedQueueDepth > BusLogic_MaxTaggedQueueDepth)
1847     TaggedQueueDepth = BusLogic_MaxTaggedQueueDepth;
1848   for (Device = DeviceList; Device != NULL; Device = Device->next)
1849     if (Device->host == Host)
1850       {
1851         if (Device->tagged_supported &&
1852             (HostAdapter->TaggedQueuingPermitted & (1 << Device->id)))
1853           Device->queue_depth = TaggedQueueDepth;
1854         else Device->queue_depth = UntaggedQueueDepth;
1855         if (BusLogic_GlobalOptions & BusLogic_TraceQueueDepths)
1856           printk("scsi%d: Setting Queue Depth for Target %d to %d\n",
1857                  HostAdapter->HostNumber, Device->id, Device->queue_depth);
1858       }
1859 }
1860 
1861 
1862 /*
1863   BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
1864   I/O Addresses where they may be located, initializing, registering, and
1865   reporting the configuration of each BusLogic Host Adapter it finds.  It
1866   returns the number of BusLogic Host Adapters successfully initialized and
1867   registered.
1868 */
1869 
1870 int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)
     /* [previous][next][first][last][top][bottom][index][help] */
1871 {
1872   int BusLogicHostAdapterCount = 0, CommandLineEntryIndex = 0;
1873   int AddressProbeIndex = 0;
1874   BusLogic_InitializeAddressProbeList();
1875   while (BusLogic_IO_AddressProbeList[AddressProbeIndex] > 0)
1876     {
1877       BusLogic_HostAdapter_T HostAdapterPrototype;
1878       BusLogic_HostAdapter_T *HostAdapter = &HostAdapterPrototype;
1879       SCSI_Host_T *Host;
1880       memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
1881       HostAdapter->IO_Address =
1882         BusLogic_IO_AddressProbeList[AddressProbeIndex++];
1883       /*
1884         Initialize the Command Line Entry field if an explicit I/O Address
1885         was specified.
1886       */
1887       if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
1888           BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address ==
1889           HostAdapter->IO_Address)
1890         HostAdapter->CommandLineEntry =
1891           &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
1892       /*
1893         Check whether the I/O Address range is already in use.
1894       */
1895       if (check_region(HostAdapter->IO_Address, BusLogic_IO_PortCount) < 0)
1896         continue;
1897       /*
1898         Probe the Host Adapter.  If unsuccessful, abort further initialization.
1899       */
1900       if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
1901       /*
1902         Hard Reset the Host Adapter.  If unsuccessful, abort further
1903         initialization.
1904       */
1905       if (!BusLogic_HardResetHostAdapter(HostAdapter)) continue;
1906       /*
1907         Check the Host Adapter.  If unsuccessful, abort further initialization.
1908       */
1909       if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
1910       /*
1911         Initialize the Command Line Entry field if an explicit I/O Address
1912         was not specified.
1913       */
1914       if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
1915           BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address == 0)
1916         HostAdapter->CommandLineEntry =
1917           &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
1918       /*
1919         Announce the Driver Version and Date, Author's Name, Copyright Notice,
1920         and Contact Address.
1921       */
1922       BusLogic_AnnounceDriver();
1923       /*
1924         Register usage of the I/O Address range.  From this point onward, any
1925         failure will be assumed to be due to a problem with the Host Adapter,
1926         rather than due to having mistakenly identified this port as belonging
1927         to a BusLogic Host Adapter.  The I/O Address range will not be
1928         released, thereby preventing it from being incorrectly identified as
1929         any other type of Host Adapter.
1930       */
1931       request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
1932                      "BusLogic");
1933       /*
1934         Register the SCSI Host structure.
1935       */
1936       HostTemplate->proc_dir = &BusLogic_ProcDirectoryEntry;
1937       Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T));
1938       HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata;
1939       memcpy(HostAdapter, &HostAdapterPrototype,
1940              sizeof(BusLogic_HostAdapter_T));
1941       HostAdapter->SCSI_Host = Host;
1942       HostAdapter->HostNumber = Host->host_no;
1943       Host->select_queue_depths = BusLogic_SelectQueueDepths;
1944       /*
1945         Add Host Adapter to the end of the list of registered BusLogic
1946         Host Adapters.  In order for Command Complete Interrupts to be
1947         properly dismissed by BusLogic_InterruptHandler, the Host Adapter
1948         must be registered.  This must be done before the IRQ Channel is
1949         acquired, and in a shared IRQ Channel environment, must be done
1950         before any Command Complete Interrupts occur, since the IRQ Channel
1951         may have already been acquired by a previous BusLogic Host Adapter.
1952       */
1953       BusLogic_RegisterHostAdapter(HostAdapter);
1954       /*
1955         Read the Host Adapter Configuration, Acquire the System Resources
1956         necessary to use Host Adapter and initialize the fields in the SCSI
1957         Host structure, then Test Interrupts, Create the Mailboxes and CCBs,
1958         Initialize the Host Adapter, and finally Inquire about the Target
1959         Devices.
1960       */
1961       if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
1962           BusLogic_AcquireResources(HostAdapter) &&
1963           BusLogic_TestInterrupts(HostAdapter) &&
1964           BusLogic_CreateMailboxes(HostAdapter) &&
1965           BusLogic_CreateCCBs(HostAdapter) &&
1966           BusLogic_InitializeHostAdapter(HostAdapter) &&
1967           BusLogic_InquireTargetDevices(HostAdapter))
1968         {
1969           /*
1970             Initialization has been completed successfully.  Release and
1971             re-register usage of the I/O Address range so that the Model
1972             Name of the Host Adapter will appear, and initialize the SCSI
1973             Host structure.
1974           */
1975           release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
1976           request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
1977                          HostAdapter->BoardName);
1978           BusLogic_InitializeHostStructure(HostAdapter, Host);
1979           BusLogicHostAdapterCount++;
1980         }
1981       else
1982         {
1983           /*
1984             An error occurred during Host Adapter Configuration Querying,
1985             Resource Acquisition, Interrupt Testing, CCB Creation, Host Adapter
1986             Initialization, or Target Device Inquiry, so remove Host Adapter
1987             from the list of registered BusLogic Host Adapters, destroy the
1988             CCBs and Mailboxes, Release the System Resources, and Unregister
1989             the SCSI Host.
1990           */
1991           BusLogic_DestroyCCBs(HostAdapter);
1992           BusLogic_DestroyMailboxes(HostAdapter);
1993           BusLogic_ReleaseResources(HostAdapter);
1994           BusLogic_UnregisterHostAdapter(HostAdapter);
1995           scsi_unregister(Host);
1996         }
1997     }
1998   return BusLogicHostAdapterCount;
1999 }
2000 
2001 
2002 /*
2003   BusLogic_ReleaseHostAdapter releases all resources previously acquired to
2004   support a specific Host Adapter, including the I/O Address range, and
2005   unregisters the BusLogic Host Adapter.
2006 */
2007 
2008 int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host)
     /* [previous][next][first][last][top][bottom][index][help] */
2009 {
2010   BusLogic_HostAdapter_T *HostAdapter =
2011     (BusLogic_HostAdapter_T *) Host->hostdata;
2012   /*
2013     Destroy the CCBs and Mailboxes, and release any system resources acquired
2014     to support Host Adapter.
2015   */
2016   BusLogic_DestroyCCBs(HostAdapter);
2017   BusLogic_DestroyMailboxes(HostAdapter);
2018   BusLogic_ReleaseResources(HostAdapter);
2019   /*
2020     Release usage of the I/O Address range.
2021   */
2022   release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
2023   /*
2024     Remove Host Adapter from the list of registered BusLogic Host Adapters.
2025   */
2026   BusLogic_UnregisterHostAdapter(HostAdapter);
2027   return 0;
2028 }
2029 
2030 
2031 /*
2032   BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
2033   the Host Adapter Status and Target Device Status.
2034 */
2035 
2036 static int BusLogic_ComputeResultCode(BusLogic_HostAdapterStatus_T
     /* [previous][next][first][last][top][bottom][index][help] */
2037                                         HostAdapterStatus,
2038                                       BusLogic_TargetDeviceStatus_T
2039                                         TargetDeviceStatus)
2040 {
2041   int HostStatus;
2042   switch (HostAdapterStatus)
2043     {
2044     case BusLogic_CommandCompletedNormally:
2045     case BusLogic_LinkedCommandCompleted:
2046     case BusLogic_LinkedCommandCompletedWithFlag:
2047       HostStatus = DID_OK;
2048       break;
2049     case BusLogic_SCSISelectionTimeout:
2050       HostStatus = DID_TIME_OUT;
2051       break;
2052     case BusLogic_InvalidOutgoingMailboxActionCode:
2053     case BusLogic_InvalidCommandOperationCode:
2054     case BusLogic_InvalidCommandParameter:
2055       printk("BusLogic: BusLogic Driver Protocol Error 0x%02X\n",
2056              HostAdapterStatus);
2057     case BusLogic_DataOverUnderRun:
2058     case BusLogic_UnexpectedBusFree:
2059     case BusLogic_LinkedCCBhasInvalidLUN:
2060     case BusLogic_AutoRequestSenseFailed:
2061     case BusLogic_TaggedQueuingMessageRejected:
2062     case BusLogic_UnsupportedMessageReceived:
2063     case BusLogic_HostAdapterHardwareFailed:
2064     case BusLogic_TargetDeviceReconnectedImproperly:
2065     case BusLogic_AbortQueueGenerated:
2066     case BusLogic_HostAdapterSoftwareError:
2067     case BusLogic_HostAdapterHardwareTimeoutError:
2068     case BusLogic_SCSIParityErrorDetected:
2069       HostStatus = DID_ERROR;
2070       break;
2071     case BusLogic_InvalidBusPhaseRequested:
2072     case BusLogic_TargetFailedResponseToATN:
2073     case BusLogic_HostAdapterAssertedRST:
2074     case BusLogic_OtherDeviceAssertedRST:
2075     case BusLogic_HostAdapterAssertedBusDeviceReset:
2076       HostStatus = DID_RESET;
2077       break;
2078     default:
2079       printk("BusLogic: unknown Host Adapter Status 0x%02X\n",
2080              HostAdapterStatus);
2081       HostStatus = DID_ERROR;
2082       break;
2083     }
2084   return (HostStatus << 16) | TargetDeviceStatus;
2085 }
2086 
2087 
2088 /*
2089   BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
2090   Adapters.  To simplify handling shared IRQ Channels, all installed BusLogic
2091   Host Adapters are scanned whenever any one of them signals a hardware
2092   interrupt.
2093 */
2094 
2095 static void BusLogic_InterruptHandler(int IRQ_Channel,
     /* [previous][next][first][last][top][bottom][index][help] */
2096                                       void *DeviceIdentifier,
2097                                       Registers_T *InterruptRegisters)
2098 {
2099   BusLogic_CCB_T *FirstCompletedCCB = NULL, *LastCompletedCCB = NULL;
2100   BusLogic_HostAdapter_T *HostAdapter;
2101   int HostAdapterResetRequestedCount = 0;
2102   BusLogic_Lock_T Lock;
2103   /*
2104     Iterate over the installed BusLogic Host Adapters accepting any Incoming
2105     Mailbox entries and saving the completed CCBs for processing.  This
2106     interrupt handler is installed as a fast interrupt, so interrupts are
2107     disabled when the interrupt handler is entered.
2108   */
2109   for (HostAdapter = BusLogic_RegisteredHostAdapters;
2110        HostAdapter != NULL;
2111        HostAdapter = HostAdapter->Next)
2112     {
2113       unsigned char InterruptRegister;
2114       /*
2115         Acquire exclusive access to Host Adapter.
2116       */
2117       BusLogic_AcquireHostAdapterLockID(HostAdapter, &Lock);
2118       /*
2119         Read the Host Adapter Interrupt Register.
2120       */
2121       InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
2122       if (InterruptRegister & BusLogic_InterruptValid)
2123         {
2124           /*
2125             Acknowledge the interrupt and reset the Host Adapter
2126             Interrupt Register.
2127           */
2128           BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
2129           /*
2130             Process valid SCSI Reset State and Incoming Mailbox Loaded
2131             Interrupts.  Command Complete Interrupts are noted, and
2132             Outgoing Mailbox Available Interrupts are ignored, as they
2133             are never enabled.
2134           */
2135           if (InterruptRegister & BusLogic_SCSIResetState)
2136             {
2137               HostAdapter->HostAdapterResetRequested = true;
2138               HostAdapterResetRequestedCount++;
2139             }
2140           else if (InterruptRegister & BusLogic_IncomingMailboxLoaded)
2141             {
2142               /*
2143                 Scan through the Incoming Mailboxes in Strict Round Robin
2144                 fashion, saving any completed CCBs for further processing.
2145                 It is essential that for each CCB and SCSI Command issued,
2146                 command completion processing is performed exactly once.
2147                 Therefore, only Incoming Mailboxes with completion code
2148                 Command Completed Without Error, Command Completed With
2149                 Error, or Command Aborted At Host Request are saved for
2150                 completion processing.  When an Incoming Mailbox has a
2151                 completion code of Aborted Command Not Found, the CCB had
2152                 already completed or been aborted before the current Abort
2153                 request was processed, and so completion processing has
2154                 already occurred and no further action should be taken.
2155               */
2156               BusLogic_IncomingMailbox_T *NextIncomingMailbox =
2157                 HostAdapter->NextIncomingMailbox;
2158               BusLogic_CompletionCode_T MailboxCompletionCode;
2159               while ((MailboxCompletionCode =
2160                       NextIncomingMailbox->CompletionCode) !=
2161                      BusLogic_IncomingMailboxFree)
2162                 {
2163                   BusLogic_CCB_T *CCB = NextIncomingMailbox->CCB;
2164                   if (MailboxCompletionCode != BusLogic_AbortedCommandNotFound)
2165                     if (CCB->Status == BusLogic_CCB_Active ||
2166                         CCB->Status == BusLogic_CCB_Reset)
2167                       {
2168                         /*
2169                           Mark this CCB as completed and add it to the end
2170                           of the list of completed CCBs.
2171                         */
2172                         CCB->Status = BusLogic_CCB_Completed;
2173                         CCB->MailboxCompletionCode = MailboxCompletionCode;
2174                         CCB->Next = NULL;
2175                         if (FirstCompletedCCB == NULL)
2176                           {
2177                             FirstCompletedCCB = CCB;
2178                             LastCompletedCCB = CCB;
2179                           }
2180                         else
2181                           {
2182                             LastCompletedCCB->Next = CCB;
2183                             LastCompletedCCB = CCB;
2184                           }
2185                         HostAdapter->ActiveCommandCount[CCB->TargetID]--;
2186                       }
2187                     else
2188                       {
2189                         /*
2190                           If a CCB ever appears in an Incoming Mailbox and
2191                           is not marked as status Active or Reset, then there
2192                           is most likely a bug in the Host Adapter firmware.
2193                         */
2194                         printk("scsi%d: Illegal CCB #%d status %d in "
2195                                "Incoming Mailbox\n", HostAdapter->HostNumber,
2196                                CCB->SerialNumber, CCB->Status);
2197                       }
2198                   else printk("scsi%d: Aborted CCB #%d to Target %d "
2199                               "Not Found\n", HostAdapter->HostNumber,
2200                               CCB->SerialNumber, CCB->TargetID);
2201                   NextIncomingMailbox->CompletionCode =
2202                     BusLogic_IncomingMailboxFree;
2203                   if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
2204                     NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
2205                 }
2206               HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
2207             }
2208           else if (InterruptRegister & BusLogic_CommandComplete)
2209             HostAdapter->HostAdapterCommandCompleted = true;
2210         }
2211       /*
2212         Release exclusive access to Host Adapter.
2213       */
2214       BusLogic_ReleaseHostAdapterLockID(HostAdapter, &Lock);
2215     }
2216   /*
2217     Iterate over the completed CCBs setting the SCSI Command Result Codes,
2218     deallocating the CCBs, and calling the Completion Routines.
2219   */
2220   while (FirstCompletedCCB != NULL)
2221     {
2222       BusLogic_CCB_T *CCB = FirstCompletedCCB;
2223       SCSI_Command_T *Command = CCB->Command;
2224       FirstCompletedCCB = FirstCompletedCCB->Next;
2225       HostAdapter = CCB->HostAdapter;
2226       /*
2227         Acquire exclusive access to Host Adapter.
2228       */
2229       BusLogic_AcquireHostAdapterLockID(HostAdapter, &Lock);
2230       /*
2231         Process the Completed CCB.
2232       */
2233       if (CCB->Opcode == BusLogic_BusDeviceReset)
2234         {
2235           unsigned char TargetID = CCB->TargetID;
2236           printk("scsi%d: Bus Device Reset CCB #%d to Target %d Completed\n",
2237                  HostAdapter->HostNumber, CCB->SerialNumber, TargetID);
2238           HostAdapter->TotalCommandCount[TargetID] = 0;
2239           HostAdapter->TaggedQueuingActive[TargetID] = false;
2240           /*
2241             Place CCB back on the Host Adapter's free list.
2242           */
2243           BusLogic_DeallocateCCB(CCB);
2244           /*
2245             Bus Device Reset CCBs have the Command field non-NULL only when a
2246             Bus Device Reset was requested for a Command that did not have a
2247             currently active CCB in the Host Adapter (i.e., a Synchronous
2248             Bus Device Reset), and hence would not have its Completion Routine
2249             called otherwise.
2250           */
2251           while (Command != NULL)
2252             {
2253               SCSI_Command_T *NextCommand = Command->reset_chain;
2254               Command->reset_chain = NULL;
2255               Command->result = DID_RESET << 16;
2256               Command->scsi_done(Command);
2257               Command = NextCommand;
2258             }
2259           /*
2260             Iterate over the CCBs for this Host Adapter performing completion
2261             processing for any CCBs marked as Reset for this Target.
2262           */
2263           for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2264             if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID)
2265               {
2266                 Command = CCB->Command;
2267                 BusLogic_DeallocateCCB(CCB);
2268                 HostAdapter->ActiveCommandCount[TargetID]--;
2269                 Command->result = DID_RESET << 16;
2270                 Command->scsi_done(Command);
2271               }
2272           HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
2273         }
2274       else
2275         {
2276           /*
2277             Translate the Mailbox Completion Code, Host Adapter Status, and
2278             Target Device Status into a SCSI Subsystem Result Code.
2279           */
2280           switch (CCB->MailboxCompletionCode)
2281             {
2282             case BusLogic_IncomingMailboxFree:
2283             case BusLogic_AbortedCommandNotFound:
2284               printk("scsi%d: CCB #%d to Target %d Impossible State\n",
2285                      HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
2286               break;
2287             case BusLogic_CommandCompletedWithoutError:
2288               HostAdapter->CommandSuccessfulFlag[CCB->TargetID] = true;
2289               Command->result = DID_OK << 16;
2290               break;
2291             case BusLogic_CommandAbortedAtHostRequest:
2292               printk("scsi%d: CCB #%d to Target %d Aborted\n",
2293                      HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
2294               Command->result = DID_ABORT << 16;
2295               break;
2296             case BusLogic_CommandCompletedWithError:
2297               Command->result =
2298                 BusLogic_ComputeResultCode(CCB->HostAdapterStatus,
2299                                            CCB->TargetDeviceStatus);
2300               if (BusLogic_GlobalOptions & BusLogic_TraceErrors)
2301                 if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
2302                   {
2303                     int i;
2304                     printk("scsi%d: CCB #%d Target %d: Result %X "
2305                            "Host Adapter Status %02X Target Status %02X\n",
2306                            HostAdapter->HostNumber, CCB->SerialNumber,
2307                            CCB->TargetID, Command->result,
2308                            CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
2309                     printk("scsi%d: CDB   ", HostAdapter->HostNumber);
2310                     for (i = 0; i < CCB->CDB_Length; i++)
2311                       printk(" %02X", CCB->CDB[i]);
2312                     printk("\n");
2313                     printk("scsi%d: Sense ", HostAdapter->HostNumber);
2314                     for (i = 0; i < CCB->SenseDataLength; i++)
2315                       printk(" %02X", (*CCB->SenseDataPointer)[i]);
2316                     printk("\n");
2317                   }
2318               break;
2319             }
2320           /*
2321             Place CCB back on the Host Adapter's free list.
2322           */
2323           BusLogic_DeallocateCCB(CCB);
2324           /*
2325             Call the SCSI Command Completion Routine.
2326           */
2327           Command->scsi_done(Command);
2328         }
2329       /*
2330         Release exclusive access to Host Adapter.
2331       */
2332       BusLogic_ReleaseHostAdapterLockID(HostAdapter, &Lock);
2333     }
2334   /*
2335     Iterate over the Host Adapters performing any requested Host Adapter Resets.
2336   */
2337   if (HostAdapterResetRequestedCount == 0) return;
2338   for (HostAdapter = BusLogic_RegisteredHostAdapters;
2339        HostAdapter != NULL;
2340        HostAdapter = HostAdapter->Next)
2341     if (HostAdapter->HostAdapterResetRequested)
2342       {
2343         BusLogic_ResetHostAdapter(HostAdapter, NULL, 0);
2344         HostAdapter->HostAdapterResetRequested = false;
2345         scsi_mark_host_reset(HostAdapter->SCSI_Host);
2346       }
2347 }
2348 
2349 
2350 /*
2351   BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
2352   Mailbox for execution by Host Adapter.  The Host Adapter's Lock should have
2353   already been acquired by the caller.
2354 */
2355 
2356 static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T
     /* [previous][next][first][last][top][bottom][index][help] */
2357                                                *HostAdapter,
2358                                              BusLogic_ActionCode_T ActionCode,
2359                                              BusLogic_CCB_T *CCB)
2360 {
2361   BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
2362   NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
2363   if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
2364     {
2365       CCB->Status = BusLogic_CCB_Active;
2366       /*
2367         The CCB field must be written before the Action Code field since
2368         the Host Adapter is operating asynchronously and the locking code
2369         does not protect against simultaneous access by the Host Adapter.
2370       */
2371       NextOutgoingMailbox->CCB = CCB;
2372       NextOutgoingMailbox->ActionCode = ActionCode;
2373       BusLogic_StartMailboxCommand(HostAdapter);
2374       if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
2375         NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2376       HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
2377       if (ActionCode == BusLogic_MailboxStartCommand)
2378         HostAdapter->ActiveCommandCount[CCB->TargetID]++;
2379       return true;
2380     }
2381   return false;
2382 }
2383 
2384 
2385 /*
2386   BusLogic_QueueCommand creates a CCB for Command and places it into an
2387   Outgoing Mailbox for execution by the associated Host Adapter.
2388 */
2389 
2390 int BusLogic_QueueCommand(SCSI_Command_T *Command,
     /* [previous][next][first][last][top][bottom][index][help] */
2391                           void (*CompletionRoutine)(SCSI_Command_T *))
2392 {
2393   BusLogic_HostAdapter_T *HostAdapter =
2394     (BusLogic_HostAdapter_T *) Command->host->hostdata;
2395   unsigned char *CDB = Command->cmnd;
2396   unsigned char CDB_Length = Command->cmd_len;
2397   unsigned char TargetID = Command->target;
2398   unsigned char LogicalUnit = Command->lun;
2399   void *BufferPointer = Command->request_buffer;
2400   int BufferLength = Command->request_bufflen;
2401   int SegmentCount = Command->use_sg;
2402   BusLogic_Lock_T Lock;
2403   BusLogic_CCB_T *CCB;
2404   /*
2405     SCSI REQUEST_SENSE commands will be executed automatically by the Host
2406     Adapter for any errors, so they should not be executed explicitly unless
2407     the Sense Data is zero indicating that no error occurred.
2408   */
2409   if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
2410     {
2411       Command->result = DID_OK << 16;
2412       CompletionRoutine(Command);
2413       return 0;
2414     }
2415   /*
2416     Acquire exclusive access to Host Adapter.
2417   */
2418   BusLogic_AcquireHostAdapterLock(HostAdapter, &Lock);
2419   /*
2420     Allocate a CCB from the Host Adapter's free list.  In the unlikely event
2421     that there are none available and memory allocation fails, wait 1 second
2422     and try again.  If that fails, the Host Adapter is probably hung so we
2423     signal an error as a Host Adapter Hard Reset should be initiated soon.
2424   */
2425   CCB = BusLogic_AllocateCCB(HostAdapter);
2426   if (CCB == NULL)
2427     {
2428       BusLogic_Delay(1);
2429       CCB = BusLogic_AllocateCCB(HostAdapter);
2430       if (CCB == NULL)
2431         {
2432           Command->result = DID_ERROR << 16;
2433           CompletionRoutine(Command);
2434           goto Done;
2435         }
2436     }
2437   /*
2438     Initialize the fields in the BusLogic Command Control Block (CCB).
2439   */
2440   if (SegmentCount == 0)
2441     {
2442       CCB->Opcode = BusLogic_InitiatorCCB;
2443       CCB->DataLength = BufferLength;
2444       CCB->DataPointer = BufferPointer;
2445     }
2446   else
2447     {
2448       SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
2449       int Segment;
2450       CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
2451       CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
2452       CCB->DataPointer = CCB->ScatterGatherList;
2453       for (Segment = 0; Segment < SegmentCount; Segment++)
2454         {
2455           CCB->ScatterGatherList[Segment].SegmentByteCount =
2456             ScatterList[Segment].length;
2457           CCB->ScatterGatherList[Segment].SegmentDataPointer =
2458             ScatterList[Segment].address;
2459         }
2460     }
2461   switch (CDB[0])
2462     {
2463     case READ_6:
2464     case READ_10:
2465       CCB->DataDirection = BusLogic_DataInLengthChecked;
2466       break;
2467     case WRITE_6:
2468     case WRITE_10:
2469       CCB->DataDirection = BusLogic_DataOutLengthChecked;
2470       break;
2471     default:
2472       CCB->DataDirection = BusLogic_UncheckedDataTransfer;
2473       break;
2474     }
2475   CCB->CDB_Length = CDB_Length;
2476   CCB->SenseDataLength = sizeof(Command->sense_buffer);
2477   CCB->HostAdapterStatus = 0;
2478   CCB->TargetDeviceStatus = 0;
2479   CCB->TargetID = TargetID;
2480   CCB->LogicalUnit = LogicalUnit;
2481   /*
2482     For Wide SCSI Host Adapters, Wide Mode CCBs are used to support more than
2483     8 Logical Units per Target, and this requires setting the overloaded
2484     TagEnable field to Logical Unit bit 5.
2485   */
2486   if (HostAdapter->HostWideSCSI)
2487     {
2488       CCB->TagEnable = LogicalUnit >> 5;
2489       CCB->WideModeTagEnable = false;
2490     }
2491   else CCB->TagEnable = false;
2492   /*
2493     BusLogic recommends that after a Reset the first couple of commands that
2494     are sent to a Target Device be sent in a non Tagged Queue fashion so that
2495     the Host Adapter and Target Device can establish Synchronous and Wide
2496     Transfer before Queue Tag messages can interfere with the Synchronous and
2497     Wide Negotiation message.  By waiting to enable Tagged Queuing until after
2498     the first BusLogic_MaxTaggedQueueDepth commands have been sent, it is
2499     assured that after a Reset any pending commands are resent before Tagged
2500     Queuing is enabled and that the Tagged Queuing message will not occur while
2501     the partition table is being printed.
2502   */
2503   if (HostAdapter->TotalCommandCount[TargetID]++ ==
2504         BusLogic_MaxTaggedQueueDepth &&
2505       (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)) &&
2506       Command->device->tagged_supported)
2507     {
2508       HostAdapter->TaggedQueuingActive[TargetID] = true;
2509       printk("scsi%d: Tagged Queuing now active for Target %d\n",
2510              HostAdapter->HostNumber, TargetID);
2511     }
2512   if (HostAdapter->TaggedQueuingActive[TargetID])
2513     {
2514       BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
2515       /*
2516         When using Tagged Queuing with Simple Queue Tags, it appears that disk
2517         drive controllers do not guarantee that a queued command will not
2518         remain in a disconnected state indefinitely if commands that read or
2519         write nearer the head position continue to arrive without interruption.
2520         Therefore, for each Target Device this driver keeps track of the last
2521         time either the queue was empty or an Ordered Queue Tag was issued.  If
2522         more than 5 seconds (half the 10 second disk timeout) have elapsed
2523         since this last sequence point, this command will be issued with an
2524         Ordered Queue Tag rather than a Simple Queue Tag, which forces the
2525         Target Device to complete all previously queued commands before this
2526         command may be executed.
2527       */
2528       if (HostAdapter->ActiveCommandCount[TargetID] == 0)
2529         HostAdapter->LastSequencePoint[TargetID] = jiffies;
2530       else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 5*HZ)
2531         {
2532           HostAdapter->LastSequencePoint[TargetID] = jiffies;
2533           QueueTag = BusLogic_OrderedQueueTag;
2534         }
2535       if (HostAdapter->HostWideSCSI)
2536         {
2537           CCB->WideModeTagEnable = true;
2538           CCB->WideModeQueueTag = QueueTag;
2539         }
2540       else
2541         {
2542           CCB->TagEnable = true;
2543           CCB->QueueTag = QueueTag;
2544         }
2545     }
2546   memcpy(CCB->CDB, CDB, CDB_Length);
2547   CCB->SenseDataPointer = (SCSI_SenseData_T *) &Command->sense_buffer;
2548   CCB->Command = Command;
2549   Command->scsi_done = CompletionRoutine;
2550   /*
2551     Place the CCB in an Outgoing Mailbox.  The higher levels of the SCSI
2552     Subsystem should not attempt to queue more commands than can be placed in
2553     Outgoing Mailboxes, so there should always be one free.  In the unlikely
2554     event that there are none available, wait 1 second and try again.  If
2555     that fails, the Host Adapter is probably hung so we signal an error as
2556     a Host Adapter Hard Reset should be initiated soon.
2557   */
2558   if (!BusLogic_WriteOutgoingMailbox(HostAdapter,
2559                                      BusLogic_MailboxStartCommand, CCB))
2560     {
2561       printk("scsi%d: cannot write Outgoing Mailbox - Pausing for 1 second\n",
2562              HostAdapter->HostNumber);
2563       BusLogic_Delay(1);
2564       if (!BusLogic_WriteOutgoingMailbox(HostAdapter,
2565                                          BusLogic_MailboxStartCommand, CCB))
2566         {
2567           printk("scsi%d: still cannot write Outgoing Mailbox - "
2568                  "Host Adapter Dead?\n", HostAdapter->HostNumber);
2569           BusLogic_DeallocateCCB(CCB);
2570           Command->result = DID_ERROR << 16;
2571           Command->scsi_done(Command);
2572         }
2573     }
2574   /*
2575     Release exclusive access to Host Adapter.
2576   */
2577 Done:
2578   BusLogic_ReleaseHostAdapterLock(HostAdapter, &Lock);
2579   return 0;
2580 }
2581 
2582 
2583 /*
2584   BusLogic_AbortCommand aborts Command if possible.
2585 */
2586 
2587 int BusLogic_AbortCommand(SCSI_Command_T *Command)
     /* [previous][next][first][last][top][bottom][index][help] */
2588 {
2589   BusLogic_HostAdapter_T *HostAdapter =
2590     (BusLogic_HostAdapter_T *) Command->host->hostdata;
2591   unsigned char TargetID = Command->target;
2592   BusLogic_Lock_T Lock;
2593   BusLogic_CCB_T *CCB;
2594   int Result;
2595   /*
2596     Acquire exclusive access to Host Adapter.
2597   */
2598   BusLogic_AcquireHostAdapterLock(HostAdapter, &Lock);
2599   /*
2600     If this Command has already completed, then no Abort is necessary.
2601   */
2602   if (Command->serial_number != Command->serial_number_at_timeout)
2603     {
2604       printk("scsi%d: Unable to Abort Command to Target %d - "
2605              "Already Completed\n", HostAdapter->HostNumber, TargetID);
2606       Result = SCSI_ABORT_NOT_RUNNING;
2607       goto Done;
2608     }
2609   /*
2610     Attempt to find an Active CCB for this Command.  If no Active CCB for this
2611     Command is found, then no Abort is necessary.
2612   */
2613   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2614     if (CCB->Command == Command) break;
2615   if (CCB == NULL)
2616     {
2617       printk("scsi%d: Unable to Abort Command to Target %d - No CCB Found\n",
2618              HostAdapter->HostNumber, TargetID);
2619       Result = SCSI_ABORT_NOT_RUNNING;
2620       goto Done;
2621     }
2622   else if (CCB->Status == BusLogic_CCB_Completed)
2623     {
2624       printk("scsi%d: Unable to Abort Command to Target %d - CCB Completed\n",
2625              HostAdapter->HostNumber, TargetID);
2626       Result = SCSI_ABORT_NOT_RUNNING;
2627       goto Done;
2628     }
2629   else if (CCB->Status == BusLogic_CCB_Reset)
2630     {
2631       printk("scsi%d: Unable to Abort Command to Target %d - CCB Reset\n",
2632              HostAdapter->HostNumber, TargetID);
2633       Result = SCSI_ABORT_NOT_RUNNING;
2634       goto Done;
2635     }
2636   /*
2637     Attempt to Abort this CCB.  Firmware versions prior to 5.xx do not generate
2638     Abort Tag messages, but only generate the non-tagged Abort message.  Since
2639     non-tagged commands are not sent by the Host Adapter until the queue of
2640     outstanding tagged commands has completed, and the Abort message is treated
2641     as a non-tagged command, it is effectively impossible to abort commands
2642     when Tagged Queuing is active.  Firmware version 5.xx does generate Abort
2643     Tag messages, so it is possible to abort commands when Tagged Queuing is
2644     active.
2645   */
2646   if (HostAdapter->TaggedQueuingActive[TargetID] &&
2647       HostAdapter->FirmwareVersion[0] < '5')
2648     {
2649       printk("scsi%d: Unable to Abort CCB #%d to Target %d - "
2650              "Abort Tag Not Supported\n", HostAdapter->HostNumber,
2651              CCB->SerialNumber, TargetID);
2652       Result = SCSI_ABORT_SNOOZE;
2653     }
2654   else if (BusLogic_WriteOutgoingMailbox(HostAdapter,
2655                                          BusLogic_MailboxAbortCommand, CCB))
2656     {
2657       printk("scsi%d: Aborting CCB #%d to Target %d\n",
2658              HostAdapter->HostNumber, CCB->SerialNumber, TargetID);
2659       Result = SCSI_ABORT_PENDING;
2660     }
2661   else
2662     {
2663       printk("scsi%d: Unable to Abort CCB #%d to Target %d - "
2664              "No Outgoing Mailboxes\n", HostAdapter->HostNumber,
2665              CCB->SerialNumber, TargetID);
2666       Result = SCSI_ABORT_BUSY;
2667     }
2668   /*
2669     Release exclusive access to Host Adapter.
2670   */
2671 Done:
2672   BusLogic_ReleaseHostAdapterLock(HostAdapter, &Lock);
2673   return Result;
2674 }
2675 
2676 
2677 /*
2678   BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
2679   currently executing SCSI Commands as having been Reset.
2680 */
2681 
2682 static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
     /* [previous][next][first][last][top][bottom][index][help] */
2683                                      SCSI_Command_T *Command,
2684                                      unsigned int ResetFlags)
2685 {
2686   BusLogic_Lock_T Lock;
2687   BusLogic_CCB_T *CCB;
2688   int TargetID, Result;
2689   /*
2690     Acquire exclusive access to Host Adapter.
2691   */
2692   BusLogic_AcquireHostAdapterLock(HostAdapter, &Lock);
2693   /*
2694     If this is an Asynchronous Reset and this Command has already completed,
2695     then no Reset is necessary.
2696   */
2697   if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
2698     {
2699       TargetID = Command->target;
2700       if (Command->serial_number != Command->serial_number_at_timeout)
2701         {
2702           printk("scsi%d: Unable to Reset Command to Target %d - "
2703                  "Already Completed or Reset\n",
2704                  HostAdapter->HostNumber, TargetID);
2705           Result = SCSI_RESET_NOT_RUNNING;
2706           goto Done;
2707       }
2708       for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2709         if (CCB->Command == Command) break;
2710       if (CCB == NULL)
2711         {
2712           printk("scsi%d: Unable to Reset Command to Target %d - "
2713                  "No CCB Found\n", HostAdapter->HostNumber, TargetID);
2714           Result = SCSI_RESET_NOT_RUNNING;
2715           goto Done;
2716         }
2717       else if (CCB->Status == BusLogic_CCB_Completed)
2718         {
2719           printk("scsi%d: Unable to Reset Command to Target %d - "
2720                  "CCB Completed\n", HostAdapter->HostNumber, TargetID);
2721           Result = SCSI_RESET_NOT_RUNNING;
2722           goto Done;
2723         }
2724       else if (CCB->Status == BusLogic_CCB_Reset &&
2725                HostAdapter->BusDeviceResetPendingCCB[TargetID] == NULL)
2726         {
2727           printk("scsi%d: Unable to Reset Command to Target %d - "
2728                  "Reset Pending\n", HostAdapter->HostNumber, TargetID);
2729           Result = SCSI_RESET_PENDING;
2730           goto Done;
2731         }
2732     }
2733   if (Command == NULL)
2734     printk("scsi%d: Resetting %s due to SCSI Reset State Interrupt\n",
2735            HostAdapter->HostNumber, HostAdapter->BoardName);
2736   else printk("scsi%d: Resetting %s due to Target %d\n",
2737               HostAdapter->HostNumber, HostAdapter->BoardName, Command->target);
2738   /*
2739     Attempt to Reset and Reinitialize the Host Adapter.
2740   */
2741   if (!(BusLogic_HardResetHostAdapter(HostAdapter) &&
2742         BusLogic_InitializeHostAdapter(HostAdapter)))
2743     {
2744       printk("scsi%d: Resetting %s Failed\n",
2745               HostAdapter->HostNumber, HostAdapter->BoardName);
2746       Result = SCSI_RESET_ERROR;
2747       goto Done;
2748     }
2749   /*
2750     Mark all currently executing CCBs as having been Reset.
2751   */
2752   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2753     if (CCB->Status == BusLogic_CCB_Active)
2754       CCB->Status = BusLogic_CCB_Reset;
2755   /*
2756     Wait a few seconds between the Host Adapter Hard Reset which initiates
2757     a SCSI Bus Reset and issuing any SCSI Commands.  Some SCSI devices get
2758     confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
2759     Note that a timer interrupt may occur here, but all active CCBs have
2760     already been marked Reset and so a reentrant call will return Pending.
2761   */
2762   BusLogic_Delay(HostAdapter->BusSettleTime);
2763   /*
2764     If this is a Synchronous Reset, perform completion processing for
2765     the Command being Reset.
2766   */
2767   if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
2768     {
2769       Command->result = DID_RESET << 16;
2770       Command->scsi_done(Command);
2771     }
2772   /*
2773     Perform completion processing for all CCBs marked as Reset.
2774   */
2775   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2776     if (CCB->Status == BusLogic_CCB_Reset)
2777       {
2778         Command = CCB->Command;
2779         BusLogic_DeallocateCCB(CCB);
2780         while (Command != NULL)
2781           {
2782             SCSI_Command_T *NextCommand = Command->reset_chain;
2783             Command->reset_chain = NULL;
2784             Command->result = DID_RESET << 16;
2785             Command->scsi_done(Command);
2786             Command = NextCommand;
2787           }
2788       }
2789   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2790     HostAdapter->LastResetTime[TargetID] = jiffies;
2791   Result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET;
2792   /*
2793     Release exclusive access to Host Adapter.
2794   */
2795 Done:
2796   BusLogic_ReleaseHostAdapterLock(HostAdapter, &Lock);
2797   return Result;
2798 }
2799 
2800 
2801 /*
2802   BusLogic_SendBusDeviceReset sends a Bus Device Reset to the Target
2803   Device associated with Command.
2804 */
2805 
2806 static int BusLogic_SendBusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
     /* [previous][next][first][last][top][bottom][index][help] */
2807                                        SCSI_Command_T *Command,
2808                                        unsigned int ResetFlags)
2809 {
2810   unsigned char TargetID = Command->target;
2811   BusLogic_Lock_T Lock;
2812   BusLogic_CCB_T *CCB;
2813   int Result = -1;
2814   /*
2815     Acquire exclusive access to Host Adapter.
2816   */
2817   BusLogic_AcquireHostAdapterLock(HostAdapter, &Lock);
2818   /*
2819     If this is an Asynchronous Reset and this Command has already completed,
2820     then no Reset is necessary.
2821   */
2822   if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
2823     {
2824       if (Command->serial_number != Command->serial_number_at_timeout)
2825         {
2826           printk("scsi%d: Unable to Reset Command to Target %d - "
2827                  "Already Completed\n", HostAdapter->HostNumber, TargetID);
2828           Result = SCSI_RESET_NOT_RUNNING;
2829           goto Done;
2830         }
2831       for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2832         if (CCB->Command == Command) break;
2833       if (CCB == NULL)
2834         {
2835           printk("scsi%d: Unable to Reset Command to Target %d - "
2836                  "No CCB Found\n", HostAdapter->HostNumber, TargetID);
2837           Result = SCSI_RESET_NOT_RUNNING;
2838           goto Done;
2839         }
2840       else if (CCB->Status == BusLogic_CCB_Completed)
2841         {
2842           printk("scsi%d: Unable to Reset Command to Target %d - "
2843                  "CCB Completed\n", HostAdapter->HostNumber, TargetID);
2844           Result = SCSI_RESET_NOT_RUNNING;
2845           goto Done;
2846         }
2847       else if (CCB->Status == BusLogic_CCB_Reset)
2848         {
2849           printk("scsi%d: Unable to Reset Command to Target %d - "
2850                  "Reset Pending\n", HostAdapter->HostNumber, TargetID);
2851           Result = SCSI_RESET_PENDING;
2852           goto Done;
2853         }
2854     }
2855   /*
2856     If this is a Synchronous Reset and a Bus Device Reset is already pending
2857     for this Target Device, do not send a second one.  Add this Command to
2858     the list of Commands for which completion processing must be performed
2859     when the Bus Device Reset CCB completes.
2860   */
2861   if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
2862     if ((CCB = HostAdapter->BusDeviceResetPendingCCB[TargetID]) != NULL)
2863       {
2864         Command->reset_chain = CCB->Command;
2865         CCB->Command = Command;
2866         Result = SCSI_RESET_PENDING;
2867         goto Done;
2868       }
2869   /*
2870     Firmware versions prior to 5.xx treat a Bus Device Reset as a non-tagged
2871     command.  Since non-tagged commands are not sent by the Host Adapter until
2872     the queue of outstanding tagged commands has completed, it is effectively
2873     impossible to send a Bus Device Reset while there are tagged commands
2874     outstanding.  Therefore, in that case a full Host Adapter Hard Reset and
2875     SCSI Bus Reset must be done.
2876   */
2877   if (HostAdapter->TaggedQueuingActive[TargetID] &&
2878       HostAdapter->ActiveCommandCount[TargetID] > 0 &&
2879       HostAdapter->FirmwareVersion[0] < '5')
2880     goto Done;
2881   /*
2882     Allocate a CCB from the Host Adapter's free list.  In the unlikely event
2883     that there are none available and memory allocation fails, attempt a full
2884     Host Adapter Hard Reset and SCSI Bus Reset.
2885   */
2886   CCB = BusLogic_AllocateCCB(HostAdapter);
2887   if (CCB == NULL) goto Done;
2888   printk("scsi%d: Sending Bus Device Reset CCB #%d to Target %d\n",
2889          HostAdapter->HostNumber, CCB->SerialNumber, TargetID);
2890   CCB->Opcode = BusLogic_BusDeviceReset;
2891   CCB->TargetID = TargetID;
2892   /*
2893     For Synchronous Resets, arrange for the interrupt handler to perform
2894     completion processing for the Command being Reset.
2895   */
2896   if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
2897     {
2898       Command->reset_chain = NULL;
2899       CCB->Command = Command;
2900     }
2901   /*
2902     Attempt to write an Outgoing Mailbox with the Bus Device Reset CCB.
2903     If sending a Bus Device Reset is impossible, attempt a full Host
2904     Adapter Hard Reset and SCSI Bus Reset.
2905   */
2906   if (!(BusLogic_WriteOutgoingMailbox(HostAdapter,
2907                                       BusLogic_MailboxStartCommand, CCB)))
2908     {
2909       printk("scsi%d: cannot write Outgoing Mailbox for Bus Device Reset\n",
2910              HostAdapter->HostNumber);
2911       BusLogic_DeallocateCCB(CCB);
2912       goto Done;
2913     }
2914   /*
2915     If there is a currently executing CCB in the Host Adapter for this Command
2916     (i.e. this is an Asynchronous Reset), then an Incoming Mailbox entry may be
2917     made with a completion code of BusLogic_HostAdapterAssertedBusDeviceReset.
2918     If there is no active CCB for this Command (i.e. this is a Synchronous
2919     Reset), then the Bus Device Reset CCB's Command field will have been set
2920     to the Command so that the interrupt for the completion of the Bus Device
2921     Reset can call the Completion Routine for the Command.  On successful
2922     execution of a Bus Device Reset, older firmware versions did return the
2923     pending CCBs with the appropriate completion code, but more recent firmware
2924     versions only return the Bus Device Reset CCB itself.  This driver handles
2925     both cases by marking all the currently executing CCBs to this Target
2926     Device as Reset.  When the Bus Device Reset CCB is processed by the
2927     interrupt handler, any remaining CCBs marked as Reset will have completion
2928     processing performed.
2929   */
2930   HostAdapter->BusDeviceResetPendingCCB[TargetID] = CCB;
2931   HostAdapter->LastResetTime[TargetID] = jiffies;
2932   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
2933     if (CCB->Status == BusLogic_CCB_Active && CCB->TargetID == TargetID)
2934       CCB->Status = BusLogic_CCB_Reset;
2935   Result = SCSI_RESET_PENDING;
2936   /*
2937     If a Bus Device Reset was not possible for some reason, force a full
2938     Host Adapter Hard Reset and SCSI Bus Reset.
2939   */
2940 Done:
2941   if (Result < 0)
2942     Result = BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
2943   /*
2944     Release exclusive access to Host Adapter.
2945   */
2946   BusLogic_ReleaseHostAdapterLock(HostAdapter, &Lock);
2947   return Result;
2948 }
2949 
2950 
2951 /*
2952   BusLogic_ResetCommand takes appropriate action to reset Command.
2953 */
2954 
2955 int BusLogic_ResetCommand(SCSI_Command_T *Command, unsigned int ResetFlags)
     /* [previous][next][first][last][top][bottom][index][help] */
2956 {
2957   BusLogic_HostAdapter_T *HostAdapter =
2958     (BusLogic_HostAdapter_T *) Command->host->hostdata;
2959   unsigned char TargetID = Command->target;
2960   unsigned char ErrorRecoveryStrategy =
2961     HostAdapter->ErrorRecoveryStrategy[TargetID];
2962   /*
2963     Disable Tagged Queuing if it is active for this Target Device and if
2964     it has been less than 10 minutes since the last reset occurred, or since
2965     the system was initialized if no prior resets have occurred.
2966   */
2967   if (HostAdapter->TaggedQueuingActive[TargetID] &&
2968       jiffies - HostAdapter->LastResetTime[TargetID] < 10*60*HZ)
2969     {
2970       HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2971       HostAdapter->TaggedQueuingActive[TargetID] = false;
2972       printk("scsi%d: Tagged Queuing now disabled for Target %d\n",
2973              HostAdapter->HostNumber, TargetID);
2974     }
2975   if (ErrorRecoveryStrategy == BusLogic_ErrorRecovery_Default)
2976     if (ResetFlags & SCSI_RESET_SUGGEST_HOST_RESET)
2977       ErrorRecoveryStrategy = BusLogic_ErrorRecovery_HardReset;
2978     else if (ResetFlags & SCSI_RESET_SUGGEST_BUS_RESET)
2979       ErrorRecoveryStrategy = BusLogic_ErrorRecovery_HardReset;
2980     else ErrorRecoveryStrategy = BusLogic_ErrorRecovery_BusDeviceReset;
2981   switch (ErrorRecoveryStrategy)
2982     {
2983     case BusLogic_ErrorRecovery_HardReset:
2984       return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
2985     case BusLogic_ErrorRecovery_BusDeviceReset:
2986       /*
2987         The Bus Device Reset Error Recovery Strategy only graduates to a Hard
2988         Reset when no commands have completed successfully since the last Bus
2989         Device Reset and it has been at least 100 milliseconds.  This prevents
2990         a sequence of commands that all timeout together from immediately
2991         forcing a Hard Reset before the Bus Device Reset has had a chance to
2992         clear the error condition.
2993       */
2994       if (HostAdapter->CommandSuccessfulFlag[TargetID] ||
2995           jiffies - HostAdapter->LastResetTime[TargetID] < HZ/10)
2996         {
2997           HostAdapter->CommandSuccessfulFlag[TargetID] = false;
2998           return BusLogic_SendBusDeviceReset(HostAdapter, Command, ResetFlags);
2999         }
3000       else return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
3001     }
3002   printk("scsi%d: Error Recovery for Target %d Suppressed\n",
3003          HostAdapter->HostNumber, TargetID);
3004   return SCSI_RESET_PUNT;
3005 }
3006 
3007 
3008 /*
3009   BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
3010   Parameters for Disk.  The default disk geometry is 64 heads, 32 sectors,
3011   and the appropriate number of cylinders so as not to exceed drive capacity.
3012   In order for disks equal to or larger than 1 GB to be addressable by the
3013   BIOS without exceeding the BIOS limitation of 1024 cylinders, Extended
3014   Translation may be enabled in AutoSCSI on "W" and "C" Series boards or by a
3015   dip switch setting on older boards.  With Extended Translation enabled,
3016   drives between 1 GB inclusive and 2 GB exclusive are given a disk geometry
3017   of 128 heads and 32 sectors, and drives above 2 GB inclusive are given a
3018   disk geometry of 255 heads and 63 sectors.  However, if the BIOS detects
3019   that the Extended Translation setting does not match the geometry in the
3020   partition table, then the translation inferred from the partition table
3021   will be used by the BIOS, and a warning may be displayed.
3022 */
3023 
3024 int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
     /* [previous][next][first][last][top][bottom][index][help] */
3025                                 int *Parameters)
3026 {
3027   BusLogic_HostAdapter_T *HostAdapter =
3028     (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
3029   BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
3030   struct buffer_head *BufferHead;
3031   if (HostAdapter->ExtendedTranslation &&
3032       Disk->capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */)
3033     if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
3034       {
3035         DiskParameters->Heads = 255;
3036         DiskParameters->Sectors = 63;
3037       }
3038     else
3039       {
3040         DiskParameters->Heads = 128;
3041         DiskParameters->Sectors = 32;
3042       }
3043   else
3044     {
3045       DiskParameters->Heads = 64;
3046       DiskParameters->Sectors = 32;
3047     }
3048   DiskParameters->Cylinders =
3049     Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3050   /*
3051     Attempt to read the first 1024 bytes from the disk device.
3052   */
3053   BufferHead = bread(MKDEV(MAJOR(Device), MINOR(Device) & ~0x0F), 0, 1024);
3054   if (BufferHead == NULL) return 0;
3055   /*
3056     If the boot sector partition table flag is valid, search for a partition
3057     table entry whose end_head matches one of the standard BusLogic geometry
3058     translations (64/32, 128/32, or 255/63).
3059   */
3060   if (*(unsigned short *) (BufferHead->b_data + 0x1FE) == 0xAA55)
3061     {
3062       struct partition *PartitionEntry =
3063         (struct partition *) (BufferHead->b_data + 0x1BE);
3064       int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
3065       for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++)
3066         {
3067           if (PartitionEntry->end_head == 64-1)
3068             {
3069               DiskParameters->Heads = 64;
3070               DiskParameters->Sectors = 32;
3071               break;
3072             }
3073           else if (PartitionEntry->end_head == 128-1)
3074             {
3075               DiskParameters->Heads = 128;
3076               DiskParameters->Sectors = 32;
3077               break;
3078             }
3079           else if (PartitionEntry->end_head == 255-1)
3080             {
3081               DiskParameters->Heads = 255;
3082               DiskParameters->Sectors = 63;
3083               break;
3084             }
3085           PartitionEntry++;
3086         }
3087       DiskParameters->Cylinders =
3088         Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3089       if (SavedCylinders != DiskParameters->Cylinders)
3090         printk("scsi%d: Warning: Extended Translation Setting "
3091                "(> 1GB Switch) does not match\n"
3092                "scsi%d: Partition Table - Adopting %d/%d Geometry "
3093                "from Partition Table\n",
3094                HostAdapter->HostNumber, HostAdapter->HostNumber,
3095                DiskParameters->Heads, DiskParameters->Sectors);
3096     }
3097   brelse(BufferHead);
3098   return 0;
3099 }
3100 
3101 
3102 /*
3103   BusLogic_Setup handles processing of Kernel Command Line Arguments.
3104 
3105   For the BusLogic driver, a Kernel command line entry comprises the driver
3106   identifier "BusLogic=" optionally followed by a comma-separated sequence of
3107   integers and then optionally followed by a comma-separated sequence of
3108   strings.  Each command line entry applies to one BusLogic Host Adapter.
3109   Multiple command line entries may be used in systems which contain multiple
3110   BusLogic Host Adapters.
3111 
3112   The first integer specified is the I/O Address at which the Host Adapter is
3113   located.  If unspecified, it defaults to 0 which means to apply this entry to
3114   the first BusLogic Host Adapter found during the default probe sequence.  If
3115   any I/O Address parameters are provided on the command line, then the default
3116   probe sequence is omitted.
3117 
3118   The second integer specified is the Tagged Queue Depth to use for Target
3119   Devices that support Tagged Queuing.  The Queue Depth is the number of SCSI
3120   commands that are allowed to be concurrently presented for execution.  If
3121   unspecified, it defaults to 0 which means to use a value determined
3122   automatically based on the Host Adapter's Total Queue Depth and the number,
3123   type, speed, and capabilities of the detected Target Devices.  For Host
3124   Adapters that require ISA Bounce Buffers, the Tagged Queue Depth is
3125   automatically set to BusLogic_TaggedQueueDepth_BB to avoid excessive
3126   preallocation of DMA Bounce Buffer memory.  Target Devices that do not
3127   support Tagged Queuing use a Queue Depth of BusLogic_UntaggedQueueDepth.
3128 
3129   The third integer specified is the Bus Settle Time in seconds.  This is
3130   the amount of time to wait between a Host Adapter Hard Reset which initiates
3131   a SCSI Bus Reset and issuing any SCSI Commands.  If unspecified, it defaults
3132   to 0 which means to use the value of BusLogic_DefaultBusSettleTime.
3133 
3134   The fourth integer specified is the Local Options.  If unspecified, it
3135   defaults to 0.  Note that Local Options are only applied to a specific Host
3136   Adapter.
3137 
3138   The fifth integer specified is the Global Options.  If unspecified, it
3139   defaults to 0.  Note that Global Options are applied across all Host
3140   Adapters.
3141 
3142   The string options are used to provide control over Tagged Queuing and Error
3143   Recovery. If both Tagged Queuing and Error Recovery strings are provided, the
3144   Tagged Queuing specification string must come first.
3145 
3146   The Tagged Queuing specification begins with "TQ:" and allows for explicitly
3147   specifying whether Tagged Queuing is permitted on Target Devices that support
3148   it.  The following specification options are available:
3149 
3150   TQ:Default            Tagged Queuing will be permitted based on the firmware
3151                         version of the BusLogic Host Adapter and based on
3152                         whether the Tagged Queue Depth value allows queuing
3153                         multiple commands.
3154 
3155   TQ:Enable             Tagged Queuing will be enabled for all Target Devices
3156                         on this Host Adapter overriding any limitation that
3157                         would otherwise be imposed based on the Host Adapter
3158                         firmware version.
3159 
3160   TQ:Disable            Tagged Queuing will be disabled for all Target Devices
3161                         on this Host Adapter.
3162 
3163   TQ:<Per-Target-Spec>  Tagged Queuing will be controlled individually for each
3164                         Target Device.  <Per-Target-Spec> is a sequence of "Y",
3165                         "N", and "X" characters.  "Y" enabled Tagged Queuing,
3166                         "N" disables Tagged Queuing, and "X" accepts the
3167                         default based on the firmware version.  The first
3168                         character refers to Target Device 0, the second to
3169                         Target Device 1, and so on; if the sequence of "Y",
3170                         "N", and "X" characters does not cover all the Target
3171                         Devices, unspecified characters are assumed to be "X".
3172 
3173   Note that explicitly requesting Tagged Queuing may lead to problems; this
3174   facility is provided primarily to allow disabling Tagged Queuing on Target
3175   Devices that do not implement it correctly.
3176 
3177   The Error Recovery Strategy specification begins with "ER:" and allows for
3178   explicitly specifying the Error Recovery action to be performed when
3179   ResetCommand is called due to a SCSI Command failing to complete
3180   successfully.  The following specification options are available:
3181 
3182   ER:Default            Error Recovery will select between the Hard Reset and
3183                         Bus Device Reset options based on the recommendation
3184                         of the SCSI Subsystem.
3185 
3186   ER:HardReset          Error Recovery will initiate a Host Adapter Hard Reset
3187                         which also causes a SCSI Bus Reset.
3188 
3189   ER:BusDeviceReset     Error Recovery will send a Bus Device Reset message to
3190                         the individual Target Device causing the error.  If
3191                         Error Recovery is again initiated for this Target
3192                         Device and no SCSI Command to this Target Device has
3193                         completed successfully since the Bus Device Reset
3194                         message was sent, then a Hard Reset will be attempted.
3195 
3196   ER:None               Error Recovery will be suppressed.  This option should
3197                         only be selected if a SCSI Bus Reset or Bus Device
3198                         Reset will cause the Target Device to fail completely
3199                         and unrecoverably.
3200 
3201   ER:<Per-Target-Spec>  Error Recovery will be controlled individually for each
3202                         Target Device.  <Per-Target-Spec> is a sequence of "D",
3203                         "H", "B", and "N" characters.  "D" selects Default, "H"
3204                         selects Hard Reset, "B" selects Bus Device Reset, and
3205                         "N" selects None.  The first character refers to Target
3206                         Device 0, the second to Target Device 1, and so on; if
3207                         the sequence of "D", "H", "B", and "N" characters does
3208                         not cover all the possible Target Devices, unspecified
3209                         characters are assumed to be "D".
3210 */
3211 
3212 void BusLogic_Setup(char *Strings, int *Integers)
     /* [previous][next][first][last][top][bottom][index][help] */
3213 {
3214   BusLogic_CommandLineEntry_T *CommandLineEntry =
3215     &BusLogic_CommandLineEntries[BusLogic_CommandLineEntryCount++];
3216   static int ProbeListIndex = 0;
3217   int IntegerCount = Integers[0], TargetID, i;
3218   CommandLineEntry->IO_Address = 0;
3219   CommandLineEntry->TaggedQueueDepth = 0;
3220   CommandLineEntry->BusSettleTime = 0;
3221   CommandLineEntry->LocalOptions = 0;
3222   CommandLineEntry->TaggedQueuingPermitted = 0;
3223   CommandLineEntry->TaggedQueuingPermittedMask = 0;
3224   memset(CommandLineEntry->ErrorRecoveryStrategy,
3225          BusLogic_ErrorRecovery_Default,
3226          sizeof(CommandLineEntry->ErrorRecoveryStrategy));
3227   if (IntegerCount > 5)
3228     printk("BusLogic: Unexpected Command Line Integers ignored\n");
3229   if (IntegerCount >= 1)
3230     {
3231       unsigned short IO_Address = Integers[1];
3232       if (IO_Address > 0)
3233         {
3234           for (i = 0; ; i++)
3235             if (BusLogic_IO_StandardAddresses[i] == 0)
3236               {
3237                 printk("BusLogic: Invalid Command Line Entry "
3238                        "(illegal I/O Address 0x%X)\n", IO_Address);
3239                 return;
3240               }
3241             else if (i < ProbeListIndex &&
3242                      IO_Address == BusLogic_IO_AddressProbeList[i])
3243               {
3244                 printk("BusLogic: Invalid Command Line Entry "
3245                        "(duplicate I/O Address 0x%X)\n", IO_Address);
3246                 return;
3247               }
3248             else if (IO_Address >= 0x400 ||
3249                      IO_Address == BusLogic_IO_StandardAddresses[i]) break;
3250           BusLogic_IO_AddressProbeList[ProbeListIndex++] = IO_Address;
3251           BusLogic_IO_AddressProbeList[ProbeListIndex] = 0;
3252         }
3253       CommandLineEntry->IO_Address = IO_Address;
3254     }
3255   if (IntegerCount >= 2)
3256     {
3257       unsigned short TaggedQueueDepth = Integers[2];
3258       if (TaggedQueueDepth > BusLogic_MaxTaggedQueueDepth)
3259         {
3260           printk("BusLogic: Invalid Command Line Entry "
3261                  "(illegal Tagged Queue Depth %d)\n", TaggedQueueDepth);
3262           return;
3263         }
3264       CommandLineEntry->TaggedQueueDepth = TaggedQueueDepth;
3265     }
3266   if (IntegerCount >= 3)
3267     CommandLineEntry->BusSettleTime = Integers[3];
3268   if (IntegerCount >= 4)
3269     CommandLineEntry->LocalOptions = Integers[4];
3270   if (IntegerCount >= 5)
3271     BusLogic_GlobalOptions |= Integers[5];
3272   if (!(BusLogic_CommandLineEntryCount == 0 || ProbeListIndex == 0 ||
3273         BusLogic_CommandLineEntryCount == ProbeListIndex))
3274     {
3275       printk("BusLogic: Invalid Command Line Entry "
3276              "(all or no I/O Addresses must be specified)\n");
3277       return;
3278     }
3279   if (Strings == NULL) return;
3280   if (strncmp(Strings, "TQ:", 3) == 0)
3281     {
3282       Strings += 3;
3283       if (strncmp(Strings, "Default", 7) == 0)
3284         Strings += 7;
3285       else if (strncmp(Strings, "Enable", 6) == 0)
3286         {
3287           Strings += 6;
3288           CommandLineEntry->TaggedQueuingPermitted = 0xFFFF;
3289           CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
3290         }
3291       else if (strncmp(Strings, "Disable", 7) == 0)
3292         {
3293           Strings += 7;
3294           CommandLineEntry->TaggedQueuingPermitted = 0x0000;
3295           CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
3296         }
3297       else
3298         for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
3299           switch (*Strings++)
3300             {
3301             case 'Y':
3302               CommandLineEntry->TaggedQueuingPermitted |= 1 << TargetID;
3303               CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
3304               break;
3305             case 'N':
3306               CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
3307               break;
3308             case 'X':
3309               break;
3310             default:
3311               Strings--;
3312               TargetID = BusLogic_MaxTargetDevices;
3313               break;
3314             }
3315     }
3316   if (*Strings == ',') Strings++;
3317   if (strncmp(Strings, "ER:", 3) == 0)
3318     {
3319       Strings += 3;
3320       if (strncmp(Strings, "Default", 7) == 0)
3321         Strings += 7;
3322       else if (strncmp(Strings, "HardReset", 9) == 0)
3323         {
3324           Strings += 9;
3325           memset(CommandLineEntry->ErrorRecoveryStrategy,
3326                  BusLogic_ErrorRecovery_HardReset,
3327                  sizeof(CommandLineEntry->ErrorRecoveryStrategy));
3328         }
3329       else if (strncmp(Strings, "BusDeviceReset", 14) == 0)
3330         {
3331           Strings += 14;
3332           memset(CommandLineEntry->ErrorRecoveryStrategy,
3333                  BusLogic_ErrorRecovery_BusDeviceReset,
3334                  sizeof(CommandLineEntry->ErrorRecoveryStrategy));
3335         }
3336       else if (strncmp(Strings, "None", 4) == 0)
3337         {
3338           Strings += 4;
3339           memset(CommandLineEntry->ErrorRecoveryStrategy,
3340                  BusLogic_ErrorRecovery_None,
3341                  sizeof(CommandLineEntry->ErrorRecoveryStrategy));
3342         }
3343       else
3344         for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
3345           switch (*Strings++)
3346             {
3347             case 'D':
3348               CommandLineEntry->ErrorRecoveryStrategy[TargetID] =
3349                 BusLogic_ErrorRecovery_Default;
3350               break;
3351             case 'H':
3352               CommandLineEntry->ErrorRecoveryStrategy[TargetID] =
3353                 BusLogic_ErrorRecovery_HardReset;
3354               break;
3355             case 'B':
3356               CommandLineEntry->ErrorRecoveryStrategy[TargetID] =
3357                 BusLogic_ErrorRecovery_BusDeviceReset;
3358               break;
3359             case 'N':
3360               CommandLineEntry->ErrorRecoveryStrategy[TargetID] =
3361                 BusLogic_ErrorRecovery_None;
3362               break;
3363             default:
3364               Strings--;
3365               TargetID = BusLogic_MaxTargetDevices;
3366               break;
3367             }
3368     }
3369   if (*Strings != '\0')
3370     printk("BusLogic: Unexpected Command Line String '%s' ignored\n", Strings);
3371 }
3372 
3373 
3374 /*
3375   Include Module support if requested.
3376 */
3377 
3378 #ifdef MODULE
3379 
3380 SCSI_Host_Template_T driver_template = BUSLOGIC;
3381 
3382 #include "scsi_module.c"
3383 
3384 #endif

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