BusLogic.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:180k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1.   */
  2.   if (HostAdapter->FirmwareVersion[0] >= '3')
  3.     {
  4.       RequestedReplyLength = sizeof(SynchronousPeriod);
  5.       if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod,
  6.    &RequestedReplyLength, sizeof(RequestedReplyLength),
  7.    &SynchronousPeriod, sizeof(SynchronousPeriod))
  8.   != sizeof(SynchronousPeriod))
  9. return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
  10.       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  11. HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
  12.     }
  13.   else
  14.     for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  15.       if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
  16. HostAdapter->SynchronousPeriod[TargetID] =
  17.   20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
  18.    .TransferPeriod;
  19.   /*
  20.     Indicate the Target Device Inquiry completed successfully.
  21.   */
  22.   return true;
  23. }
  24. /*
  25.   BusLogic_ReportTargetDeviceInfo reports about the Target Devices accessible
  26.   through Host Adapter.
  27. */
  28. static void BusLogic_ReportTargetDeviceInfo(BusLogic_HostAdapter_T
  29.     *HostAdapter)
  30. {
  31.   int TargetID;
  32.   /*
  33.     Inhibit the Target Device Inquiry and Reporting if requested.
  34.   */
  35.   if (BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
  36.       HostAdapter->DriverOptions != NULL &&
  37.       HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
  38.     return;
  39.   /*
  40.     Report on the Target Devices found.
  41.   */
  42.   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  43.     {
  44.       BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
  45.       if (TargetFlags->TargetExists && !TargetFlags->TargetInfoReported)
  46. {
  47.   int SynchronousTransferRate = 0;
  48.   if (BusLogic_FlashPointHostAdapterP(HostAdapter))
  49.     {
  50.       unsigned char WideTransfersActive;
  51.       FlashPoint_InquireTargetInfo(
  52. HostAdapter->CardHandle, TargetID,
  53. &HostAdapter->SynchronousPeriod[TargetID],
  54. &HostAdapter->SynchronousOffset[TargetID],
  55. &WideTransfersActive);
  56.       TargetFlags->WideTransfersActive = WideTransfersActive;
  57.     }
  58.   else if (TargetFlags->WideTransfersSupported &&
  59.    (HostAdapter->WidePermitted & (1 << TargetID)) &&
  60.    strcmp(HostAdapter->FirmwareVersion, "5.06L") < 0)
  61.     TargetFlags->WideTransfersActive = true;
  62.   if (HostAdapter->SynchronousPeriod[TargetID] > 0)
  63.     SynchronousTransferRate =
  64.       100000 / HostAdapter->SynchronousPeriod[TargetID];
  65.   if (TargetFlags->WideTransfersActive)
  66.     SynchronousTransferRate <<= 1;
  67.   if (SynchronousTransferRate >= 9950)
  68.     {
  69.       SynchronousTransferRate = (SynchronousTransferRate + 50) / 100;
  70.       BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
  71.     "%d.%01d MB/sec, offset %dn",
  72.     HostAdapter, TargetID,
  73.     HostAdapter->QueueDepth[TargetID],
  74.     (TargetFlags->WideTransfersActive ? "Wide " : ""),
  75.     SynchronousTransferRate / 10,
  76.     SynchronousTransferRate % 10,
  77.     HostAdapter->SynchronousOffset[TargetID]);
  78.     }
  79.   else if (SynchronousTransferRate > 0)
  80.     {
  81.       SynchronousTransferRate = (SynchronousTransferRate + 5) / 10;
  82.       BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
  83.     "%d.%02d MB/sec, offset %dn",
  84.     HostAdapter, TargetID,
  85.     HostAdapter->QueueDepth[TargetID],
  86.     (TargetFlags->WideTransfersActive ? "Wide " : ""),
  87.     SynchronousTransferRate / 100,
  88.     SynchronousTransferRate % 100,
  89.     HostAdapter->SynchronousOffset[TargetID]);
  90.     }
  91.   else BusLogic_Info("Target %d: Queue Depth %d, Asynchronousn",
  92.      HostAdapter, TargetID,
  93.      HostAdapter->QueueDepth[TargetID]);
  94.   TargetFlags->TargetInfoReported = true;
  95. }
  96.     }
  97. }
  98. /*
  99.   BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
  100.   structure.  The base, io_port, n_io_ports, irq, and dma_channel fields in the
  101.   SCSI Host structure are intentionally left uninitialized, as this driver
  102.   handles acquisition and release of these resources explicitly, as well as
  103.   ensuring exclusive access to the Host Adapter hardware and data structures
  104.   through explicit acquisition and release of the Host Adapter's Lock.
  105. */
  106. static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T
  107.        *HostAdapter,
  108.      SCSI_Host_T *Host)
  109. {
  110.   Host->max_id = HostAdapter->MaxTargetDevices;
  111.   Host->max_lun = HostAdapter->MaxLogicalUnits;
  112.   Host->max_channel = 0;
  113.   Host->unique_id = HostAdapter->IO_Address;
  114.   Host->this_id = HostAdapter->SCSI_ID;
  115.   Host->can_queue = HostAdapter->DriverQueueDepth;
  116.   Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
  117.   Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
  118.   Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
  119. }
  120. /*
  121.   BusLogic_SelectQueueDepths selects Queue Depths for each Target Device based
  122.   on the Host Adapter's Total Queue Depth and the number, type, speed, and
  123.   capabilities of the Target Devices.  When called for the last Host Adapter,
  124.   it reports on the Target Device Information for all BusLogic Host Adapters
  125.   since all the Target Devices have now been probed.
  126. */
  127. static void BusLogic_SelectQueueDepths(SCSI_Host_T *Host,
  128.        SCSI_Device_T *DeviceList)
  129. {
  130.   BusLogic_HostAdapter_T *HostAdapter =
  131.     (BusLogic_HostAdapter_T *) Host->hostdata;
  132.   int TaggedDeviceCount = 0, AutomaticTaggedDeviceCount = 0;
  133.   int UntaggedDeviceCount = 0, AutomaticTaggedQueueDepth = 0;
  134.   int AllocatedQueueDepth = 0;
  135.   SCSI_Device_T *Device;
  136.   int TargetID;
  137.   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  138.     if (HostAdapter->TargetFlags[TargetID].TargetExists)
  139.       {
  140. int QueueDepth = HostAdapter->QueueDepth[TargetID];
  141. if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported &&
  142.     (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
  143.   {
  144.     TaggedDeviceCount++;
  145.     if (QueueDepth == 0) AutomaticTaggedDeviceCount++;
  146.   }
  147. else
  148.   {
  149.     UntaggedDeviceCount++;
  150.     if (QueueDepth == 0 ||
  151. QueueDepth > HostAdapter->UntaggedQueueDepth)
  152.       {
  153. QueueDepth = HostAdapter->UntaggedQueueDepth;
  154. HostAdapter->QueueDepth[TargetID] = QueueDepth;
  155.       }
  156.   }
  157. AllocatedQueueDepth += QueueDepth;
  158. if (QueueDepth == 1)
  159.   HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
  160.       }
  161.   HostAdapter->TargetDeviceCount = TaggedDeviceCount + UntaggedDeviceCount;
  162.   if (AutomaticTaggedDeviceCount > 0)
  163.     {
  164.       AutomaticTaggedQueueDepth =
  165. (HostAdapter->HostAdapterQueueDepth - AllocatedQueueDepth)
  166. / AutomaticTaggedDeviceCount;
  167.       if (AutomaticTaggedQueueDepth > BusLogic_MaxAutomaticTaggedQueueDepth)
  168. AutomaticTaggedQueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
  169.       if (AutomaticTaggedQueueDepth < BusLogic_MinAutomaticTaggedQueueDepth)
  170. AutomaticTaggedQueueDepth = BusLogic_MinAutomaticTaggedQueueDepth;
  171.       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  172. if (HostAdapter->TargetFlags[TargetID].TargetExists &&
  173.     HostAdapter->QueueDepth[TargetID] == 0)
  174.   {
  175.     AllocatedQueueDepth += AutomaticTaggedQueueDepth;
  176.     HostAdapter->QueueDepth[TargetID] = AutomaticTaggedQueueDepth;
  177.   }
  178.     }
  179.   for (Device = DeviceList; Device != NULL; Device = Device->next)
  180.     if (Device->host == Host)
  181.       Device->queue_depth = HostAdapter->QueueDepth[Device->id];
  182.   /* Allocate an extra CCB for each Target Device for a Bus Device Reset. */
  183.   AllocatedQueueDepth += HostAdapter->TargetDeviceCount;
  184.   if (AllocatedQueueDepth > HostAdapter->DriverQueueDepth)
  185.     AllocatedQueueDepth = HostAdapter->DriverQueueDepth;
  186.   BusLogic_CreateAdditionalCCBs(HostAdapter,
  187. AllocatedQueueDepth
  188. - HostAdapter->AllocatedCCBs,
  189. false);
  190.   if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
  191.     for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
  192.  HostAdapter != NULL;
  193.  HostAdapter = HostAdapter->Next)
  194.       BusLogic_ReportTargetDeviceInfo(HostAdapter);
  195. }
  196. /*
  197.   BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
  198.   I/O Addresses where they may be located, initializing, registering, and
  199.   reporting the configuration of each BusLogic Host Adapter it finds.  It
  200.   returns the number of BusLogic Host Adapters successfully initialized and
  201.   registered.
  202. */
  203. int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)
  204. {
  205.   int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
  206.   BusLogic_HostAdapter_T *PrototypeHostAdapter;
  207.   if (BusLogic_ProbeOptions.NoProbe) return 0;
  208.   BusLogic_ProbeInfoList = (BusLogic_ProbeInfo_T *)
  209.     kmalloc(BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T),
  210.     GFP_ATOMIC);
  211.   if (BusLogic_ProbeInfoList == NULL)
  212.     {
  213.       BusLogic_Error("BusLogic: Unable to allocate Probe Info Listn", NULL);
  214.       return 0;
  215.     }
  216.   memset(BusLogic_ProbeInfoList, 0,
  217.  BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T));
  218.   PrototypeHostAdapter = (BusLogic_HostAdapter_T *)
  219.     kmalloc(sizeof(BusLogic_HostAdapter_T), GFP_ATOMIC);
  220.   if (PrototypeHostAdapter == NULL)
  221.     {
  222.       kfree(BusLogic_ProbeInfoList);
  223.       BusLogic_Error("BusLogic: Unable to allocate Prototype "
  224.      "Host Adaptern", NULL);
  225.       return 0;
  226.     }
  227.   memset(PrototypeHostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
  228. #ifdef MODULE
  229.   if (BusLogic != NULL)
  230.     BusLogic_Setup(BusLogic);
  231. #endif
  232.   BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
  233.   for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++)
  234.     {
  235.       BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
  236.       BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
  237.       SCSI_Host_T *Host;
  238.       if (ProbeInfo->IO_Address == 0) continue;
  239.       memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
  240.       HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
  241.       HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
  242.       HostAdapter->IO_Address = ProbeInfo->IO_Address;
  243.       HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
  244.       HostAdapter->Bus = ProbeInfo->Bus;
  245.       HostAdapter->Device = ProbeInfo->Device;
  246.       HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
  247.       HostAdapter->AddressCount =
  248. BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
  249.       /*
  250. Probe the Host Adapter.  If unsuccessful, abort further initialization.
  251.       */
  252.       if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
  253.       /*
  254. Hard Reset the Host Adapter.  If unsuccessful, abort further
  255. initialization.
  256.       */
  257.       if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) continue;
  258.       /*
  259. Check the Host Adapter.  If unsuccessful, abort further initialization.
  260.       */
  261.       if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
  262.       /*
  263. Initialize the Driver Options field if provided.
  264.       */
  265.       if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
  266. HostAdapter->DriverOptions =
  267.   &BusLogic_DriverOptions[DriverOptionsIndex++];
  268.       /*
  269. Announce the Driver Version and Date, Author's Name, Copyright Notice,
  270. and Electronic Mail Address.
  271.       */
  272.       BusLogic_AnnounceDriver(HostAdapter);
  273.       /*
  274. Register usage of the I/O Address range.  From this point onward, any
  275. failure will be assumed to be due to a problem with the Host Adapter,
  276. rather than due to having mistakenly identified this port as belonging
  277. to a BusLogic Host Adapter.  The I/O Address range will not be
  278. released, thereby preventing it from being incorrectly identified as
  279. any other type of Host Adapter.
  280.       */
  281.       request_region(HostAdapter->IO_Address, HostAdapter->AddressCount,
  282.      "BusLogic");
  283.       /*
  284. Register the SCSI Host structure.
  285.       */
  286.       Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T));
  287.       if(Host==NULL)
  288.       {
  289.        release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
  290.        continue;
  291.       }
  292.       HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata;
  293.       memcpy(HostAdapter, PrototypeHostAdapter, sizeof(BusLogic_HostAdapter_T));
  294.       HostAdapter->SCSI_Host = Host;
  295.       HostAdapter->HostNumber = Host->host_no;
  296.       Host->select_queue_depths = BusLogic_SelectQueueDepths;
  297.       /*
  298. Add Host Adapter to the end of the list of registered BusLogic
  299. Host Adapters.
  300.       */
  301.       BusLogic_RegisterHostAdapter(HostAdapter);
  302.       /*
  303. Read the Host Adapter Configuration, Configure the Host Adapter,
  304. Acquire the System Resources necessary to use the Host Adapter, then
  305. Create the Initial CCBs, Initialize the Host Adapter, and finally
  306. perform Target Device Inquiry.
  307.       */
  308.       if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
  309.   BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
  310.   BusLogic_AcquireResources(HostAdapter) &&
  311.   BusLogic_CreateInitialCCBs(HostAdapter) &&
  312.   BusLogic_InitializeHostAdapter(HostAdapter) &&
  313.   BusLogic_TargetDeviceInquiry(HostAdapter))
  314. {
  315.   /*
  316.     Initialization has been completed successfully.  Release and
  317.     re-register usage of the I/O Address range so that the Model
  318.     Name of the Host Adapter will appear, and initialize the SCSI
  319.     Host structure.
  320.   */
  321.   release_region(HostAdapter->IO_Address,
  322.  HostAdapter->AddressCount);
  323.   request_region(HostAdapter->IO_Address,
  324.  HostAdapter->AddressCount,
  325.  HostAdapter->FullModelName);
  326.   BusLogic_InitializeHostStructure(HostAdapter, Host);
  327.   BusLogicHostAdapterCount++;
  328. }
  329.       else
  330. {
  331.   /*
  332.     An error occurred during Host Adapter Configuration Querying, Host
  333.     Adapter Configuration, Resource Acquisition, CCB Creation, Host
  334.     Adapter Initialization, or Target Device Inquiry, so remove Host
  335.     Adapter from the list of registered BusLogic Host Adapters, destroy
  336.     the CCBs, Release the System Resources, and Unregister the SCSI
  337.     Host.
  338.   */
  339.   BusLogic_DestroyCCBs(HostAdapter);
  340.   BusLogic_ReleaseResources(HostAdapter);
  341.   BusLogic_UnregisterHostAdapter(HostAdapter);
  342.   scsi_unregister(Host);
  343. }
  344.     }
  345.   kfree(PrototypeHostAdapter);
  346.   kfree(BusLogic_ProbeInfoList);
  347.   BusLogic_ProbeInfoList = NULL;
  348.   return BusLogicHostAdapterCount;
  349. }
  350. /*
  351.   BusLogic_ReleaseHostAdapter releases all resources previously acquired to
  352.   support a specific Host Adapter, including the I/O Address range, and
  353.   unregisters the BusLogic Host Adapter.
  354. */
  355. int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host)
  356. {
  357.   BusLogic_HostAdapter_T *HostAdapter =
  358.     (BusLogic_HostAdapter_T *) Host->hostdata;
  359.   /*
  360.     FlashPoint Host Adapters must first be released by the FlashPoint
  361.     SCCB Manager.
  362.   */
  363.   if (BusLogic_FlashPointHostAdapterP(HostAdapter))
  364.     FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
  365.   /*
  366.     Destroy the CCBs and release any system resources acquired to
  367.     support Host Adapter.
  368.   */
  369.   BusLogic_DestroyCCBs(HostAdapter);
  370.   BusLogic_ReleaseResources(HostAdapter);
  371.   /*
  372.     Release usage of the I/O Address range.
  373.   */
  374.   release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
  375.   /*
  376.     Remove Host Adapter from the list of registered BusLogic Host Adapters.
  377.   */
  378.   BusLogic_UnregisterHostAdapter(HostAdapter);
  379.   return 0;
  380. }
  381. /*
  382.   BusLogic_QueueCompletedCCB queues CCB for completion processing.
  383. */
  384. static void BusLogic_QueueCompletedCCB(BusLogic_CCB_T *CCB)
  385. {
  386.   BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
  387.   CCB->Status = BusLogic_CCB_Completed;
  388.   CCB->Next = NULL;
  389.   if (HostAdapter->FirstCompletedCCB == NULL)
  390.     {
  391.       HostAdapter->FirstCompletedCCB = CCB;
  392.       HostAdapter->LastCompletedCCB = CCB;
  393.     }
  394.   else
  395.     {
  396.       HostAdapter->LastCompletedCCB->Next = CCB;
  397.       HostAdapter->LastCompletedCCB = CCB;
  398.     }
  399.   HostAdapter->ActiveCommands[CCB->TargetID]--;
  400. }
  401. /*
  402.   BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
  403.   the Host Adapter Status and Target Device Status.
  404. */
  405. static int BusLogic_ComputeResultCode(BusLogic_HostAdapter_T *HostAdapter,
  406.       BusLogic_HostAdapterStatus_T
  407. HostAdapterStatus,
  408.       BusLogic_TargetDeviceStatus_T
  409. TargetDeviceStatus)
  410. {
  411.   int HostStatus;
  412.   switch (HostAdapterStatus)
  413.     {
  414.     case BusLogic_CommandCompletedNormally:
  415.     case BusLogic_LinkedCommandCompleted:
  416.     case BusLogic_LinkedCommandCompletedWithFlag:
  417.       HostStatus = DID_OK;
  418.       break;
  419.     case BusLogic_SCSISelectionTimeout:
  420.       HostStatus = DID_TIME_OUT;
  421.       break;
  422.     case BusLogic_InvalidOutgoingMailboxActionCode:
  423.     case BusLogic_InvalidCommandOperationCode:
  424.     case BusLogic_InvalidCommandParameter:
  425.       BusLogic_Warning("BusLogic Driver Protocol Error 0x%02Xn",
  426.        HostAdapter, HostAdapterStatus);
  427.     case BusLogic_DataUnderRun:
  428.     case BusLogic_DataOverRun:
  429.     case BusLogic_UnexpectedBusFree:
  430.     case BusLogic_LinkedCCBhasInvalidLUN:
  431.     case BusLogic_AutoRequestSenseFailed:
  432.     case BusLogic_TaggedQueuingMessageRejected:
  433.     case BusLogic_UnsupportedMessageReceived:
  434.     case BusLogic_HostAdapterHardwareFailed:
  435.     case BusLogic_TargetDeviceReconnectedImproperly:
  436.     case BusLogic_AbortQueueGenerated:
  437.     case BusLogic_HostAdapterSoftwareError:
  438.     case BusLogic_HostAdapterHardwareTimeoutError:
  439.     case BusLogic_SCSIParityErrorDetected:
  440.       HostStatus = DID_ERROR;
  441.       break;
  442.     case BusLogic_InvalidBusPhaseRequested:
  443.     case BusLogic_TargetFailedResponseToATN:
  444.     case BusLogic_HostAdapterAssertedRST:
  445.     case BusLogic_OtherDeviceAssertedRST:
  446.     case BusLogic_HostAdapterAssertedBusDeviceReset:
  447.       HostStatus = DID_RESET;
  448.       break;
  449.     default:
  450.       BusLogic_Warning("Unknown Host Adapter Status 0x%02Xn",
  451.        HostAdapter, HostAdapterStatus);
  452.       HostStatus = DID_ERROR;
  453.       break;
  454.     }
  455.   return (HostStatus << 16) | TargetDeviceStatus;
  456. }
  457. /*
  458.   BusLogic_ScanIncomingMailboxes scans the Incoming Mailboxes saving any
  459.   Incoming Mailbox entries for completion processing.
  460. */
  461. static void BusLogic_ScanIncomingMailboxes(BusLogic_HostAdapter_T *HostAdapter)
  462. {
  463.   /*
  464.     Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving
  465.     any completed CCBs for further processing.  It is essential that for each
  466.     CCB and SCSI Command issued, command completion processing is performed
  467.     exactly once.  Therefore, only Incoming Mailboxes with completion code
  468.     Command Completed Without Error, Command Completed With Error, or Command
  469.     Aborted At Host Request are saved for completion processing.  When an
  470.     Incoming Mailbox has a completion code of Aborted Command Not Found, the
  471.     CCB had already completed or been aborted before the current Abort request
  472.     was processed, and so completion processing has already occurred and no
  473.     further action should be taken.
  474.   */
  475.   BusLogic_IncomingMailbox_T *NextIncomingMailbox =
  476.     HostAdapter->NextIncomingMailbox;
  477.   BusLogic_CompletionCode_T CompletionCode;
  478.   while ((CompletionCode = NextIncomingMailbox->CompletionCode) !=
  479.  BusLogic_IncomingMailboxFree)
  480.     {
  481.       BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
  482. Bus_to_Virtual(NextIncomingMailbox->CCB);
  483.       if (CompletionCode != BusLogic_AbortedCommandNotFound)
  484. {
  485.   if (CCB->Status == BusLogic_CCB_Active ||
  486.       CCB->Status == BusLogic_CCB_Reset)
  487.     {
  488.       /*
  489. Save the Completion Code for this CCB and queue the CCB
  490. for completion processing.
  491.       */
  492.       CCB->CompletionCode = CompletionCode;
  493.       BusLogic_QueueCompletedCCB(CCB);
  494.     }
  495.   else
  496.     {
  497.       /*
  498. If a CCB ever appears in an Incoming Mailbox and is not marked
  499. as status Active or Reset, then there is most likely a bug in
  500. the Host Adapter firmware.
  501.       */
  502.       BusLogic_Warning("Illegal CCB #%ld status %d in "
  503.        "Incoming Mailboxn", HostAdapter,
  504.        CCB->SerialNumber, CCB->Status);
  505.     }
  506. }
  507.       NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
  508.       if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
  509. NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
  510.     }
  511.   HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
  512. }
  513. /*
  514.   BusLogic_ProcessCompletedCCBs iterates over the completed CCBs for Host
  515.   Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
  516.   calling the SCSI Subsystem Completion Routines.  The Host Adapter's Lock
  517.   should already have been acquired by the caller.
  518. */
  519. static void BusLogic_ProcessCompletedCCBs(BusLogic_HostAdapter_T *HostAdapter)
  520. {
  521.   if (HostAdapter->ProcessCompletedCCBsActive) return;
  522.   HostAdapter->ProcessCompletedCCBsActive = true;
  523.   while (HostAdapter->FirstCompletedCCB != NULL)
  524.     {
  525.       BusLogic_CCB_T *CCB = HostAdapter->FirstCompletedCCB;
  526.       SCSI_Command_T *Command = CCB->Command;
  527.       HostAdapter->FirstCompletedCCB = CCB->Next;
  528.       if (HostAdapter->FirstCompletedCCB == NULL)
  529. HostAdapter->LastCompletedCCB = NULL;
  530.       /*
  531. Process the Completed CCB.
  532.       */
  533.       if (CCB->Opcode == BusLogic_BusDeviceReset)
  534. {
  535.   int TargetID = CCB->TargetID;
  536.   BusLogic_Warning("Bus Device Reset CCB #%ld to Target "
  537.    "%d Completedn", HostAdapter,
  538.    CCB->SerialNumber, TargetID);
  539.   BusLogic_IncrementErrorCounter(
  540.     &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
  541.   HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
  542.   HostAdapter->CommandsSinceReset[TargetID] = 0;
  543.   HostAdapter->LastResetCompleted[TargetID] = jiffies;
  544.   /*
  545.     Place CCB back on the Host Adapter's free list.
  546.   */
  547.   BusLogic_DeallocateCCB(CCB);
  548.   /*
  549.     Bus Device Reset CCBs have the Command field non-NULL only when a
  550.     Bus Device Reset was requested for a Command that did not have a
  551.     currently active CCB in the Host Adapter (i.e., a Synchronous
  552.     Bus Device Reset), and hence would not have its Completion Routine
  553.     called otherwise.
  554.   */
  555.   while (Command != NULL)
  556.     {
  557.       SCSI_Command_T *NextCommand = Command->reset_chain;
  558.       Command->reset_chain = NULL;
  559.       Command->result = DID_RESET << 16;
  560.       Command->scsi_done(Command);
  561.       Command = NextCommand;
  562.     }
  563.   /*
  564.     Iterate over the CCBs for this Host Adapter performing completion
  565.     processing for any CCBs marked as Reset for this Target.
  566.   */
  567.   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
  568.     if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID)
  569.       {
  570. Command = CCB->Command;
  571. BusLogic_DeallocateCCB(CCB);
  572. HostAdapter->ActiveCommands[TargetID]--;
  573. Command->result = DID_RESET << 16;
  574. Command->scsi_done(Command);
  575.       }
  576.   HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
  577. }
  578.       else
  579. {
  580.   /*
  581.     Translate the Completion Code, Host Adapter Status, and Target
  582.     Device Status into a SCSI Subsystem Result Code.
  583.   */
  584.   switch (CCB->CompletionCode)
  585.     {
  586.     case BusLogic_IncomingMailboxFree:
  587.     case BusLogic_AbortedCommandNotFound:
  588.     case BusLogic_InvalidCCB:
  589.       BusLogic_Warning("CCB #%ld to Target %d Impossible Staten",
  590.        HostAdapter, CCB->SerialNumber, CCB->TargetID);
  591.       break;
  592.     case BusLogic_CommandCompletedWithoutError:
  593.       HostAdapter->TargetStatistics[CCB->TargetID]
  594.    .CommandsCompleted++;
  595.       HostAdapter->TargetFlags[CCB->TargetID]
  596.    .CommandSuccessfulFlag = true;
  597.       Command->result = DID_OK << 16;
  598.       break;
  599.     case BusLogic_CommandAbortedAtHostRequest:
  600.       BusLogic_Warning("CCB #%ld to Target %d Abortedn",
  601.        HostAdapter, CCB->SerialNumber, CCB->TargetID);
  602.       BusLogic_IncrementErrorCounter(
  603. &HostAdapter->TargetStatistics[CCB->TargetID]
  604.       .CommandAbortsCompleted);
  605.       Command->result = DID_ABORT << 16;
  606.       break;
  607.     case BusLogic_CommandCompletedWithError:
  608.       Command->result =
  609. BusLogic_ComputeResultCode(HostAdapter,
  610.    CCB->HostAdapterStatus,
  611.    CCB->TargetDeviceStatus);
  612.       if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
  613. {
  614.   HostAdapter->TargetStatistics[CCB->TargetID]
  615.        .CommandsCompleted++;
  616.   if (BusLogic_GlobalOptions.TraceErrors)
  617.     {
  618.       int i;
  619.       BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
  620.       "Adapter Status %02X "
  621.       "Target Status %02Xn",
  622.       HostAdapter, CCB->SerialNumber,
  623.       CCB->TargetID, Command->result,
  624.       CCB->HostAdapterStatus,
  625.       CCB->TargetDeviceStatus);
  626.       BusLogic_Notice("CDB   ", HostAdapter);
  627.       for (i = 0; i < CCB->CDB_Length; i++)
  628. BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
  629.       BusLogic_Notice("n", HostAdapter);
  630.       BusLogic_Notice("Sense ", HostAdapter);
  631.       for (i = 0; i < CCB->SenseDataLength; i++)
  632. BusLogic_Notice(" %02X", HostAdapter,
  633. Command->sense_buffer[i]);
  634.       BusLogic_Notice("n", HostAdapter);
  635.     }
  636. }
  637.       break;
  638.     }
  639.   /*
  640.     When an INQUIRY command completes normally, save the
  641.     CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
  642.     Wide Data Transfers Supported) bits.
  643.   */
  644.   if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 &&
  645.       CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally)
  646.     {
  647.       BusLogic_TargetFlags_T *TargetFlags =
  648. &HostAdapter->TargetFlags[CCB->TargetID];
  649.       SCSI_Inquiry_T *InquiryResult =
  650. (SCSI_Inquiry_T *) Command->request_buffer;
  651.       TargetFlags->TargetExists = true;
  652.       TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
  653.       TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
  654.     }
  655.   /*
  656.     Place CCB back on the Host Adapter's free list.
  657.   */
  658.   BusLogic_DeallocateCCB(CCB);
  659.   /*
  660.     Call the SCSI Command Completion Routine.
  661.   */
  662.   Command->scsi_done(Command);
  663. }
  664.     }
  665.   HostAdapter->ProcessCompletedCCBsActive = false;
  666. }
  667. /*
  668.   BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
  669.   Adapters.
  670. */
  671. static void BusLogic_InterruptHandler(int IRQ_Channel,
  672.       void *DeviceIdentifier,
  673.       Registers_T *InterruptRegisters)
  674. {
  675.   BusLogic_HostAdapter_T *HostAdapter =
  676.     (BusLogic_HostAdapter_T *) DeviceIdentifier;
  677.   ProcessorFlags_T ProcessorFlags;
  678.   /*
  679.     Acquire exclusive access to Host Adapter.
  680.   */
  681.   BusLogic_AcquireHostAdapterLockIH(HostAdapter, &ProcessorFlags);
  682.   /*
  683.     Handle Interrupts appropriately for each Host Adapter type.
  684.   */
  685.   if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
  686.     {
  687.       BusLogic_InterruptRegister_T InterruptRegister;
  688.       /*
  689. Read the Host Adapter Interrupt Register.
  690.       */
  691.       InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
  692.       if (InterruptRegister.Bits.InterruptValid)
  693. {
  694.   /*
  695.     Acknowledge the interrupt and reset the Host Adapter
  696.     Interrupt Register.
  697.   */
  698.   BusLogic_InterruptReset(HostAdapter);
  699.   /*
  700.     Process valid External SCSI Bus Reset and Incoming Mailbox
  701.     Loaded Interrupts.  Command Complete Interrupts are noted,
  702.     and Outgoing Mailbox Available Interrupts are ignored, as
  703.     they are never enabled.
  704.   */
  705.   if (InterruptRegister.Bits.ExternalBusReset)
  706.     HostAdapter->HostAdapterExternalReset = true;
  707.   else if (InterruptRegister.Bits.IncomingMailboxLoaded)
  708.     BusLogic_ScanIncomingMailboxes(HostAdapter);
  709.   else if (InterruptRegister.Bits.CommandComplete)
  710.     HostAdapter->HostAdapterCommandCompleted = true;
  711. }
  712.     }
  713.   else
  714.     {
  715.       /*
  716. Check if there is a pending interrupt for this Host Adapter.
  717.       */
  718.       if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
  719. switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle))
  720.   {
  721.   case FlashPoint_NormalInterrupt:
  722.     break;
  723.   case FlashPoint_ExternalBusReset:
  724.     HostAdapter->HostAdapterExternalReset = true;
  725.     break;
  726.   case FlashPoint_InternalError:
  727.     BusLogic_Warning("Internal FlashPoint Error detected"
  728.      " - Resetting Host Adaptern", HostAdapter);
  729.     HostAdapter->HostAdapterInternalError = true;
  730.     break;
  731.   }
  732.     }
  733.   /*
  734.     Process any completed CCBs.
  735.   */
  736.   if (HostAdapter->FirstCompletedCCB != NULL)
  737.     BusLogic_ProcessCompletedCCBs(HostAdapter);
  738.   /*
  739.     Reset the Host Adapter if requested.
  740.   */
  741.   if (HostAdapter->HostAdapterExternalReset ||
  742.       HostAdapter->HostAdapterInternalError)
  743.     {
  744.       BusLogic_ResetHostAdapter(HostAdapter, NULL, 0);
  745.       HostAdapter->HostAdapterExternalReset = false;
  746.       HostAdapter->HostAdapterInternalError = false;
  747.       scsi_mark_host_reset(HostAdapter->SCSI_Host);
  748.     }
  749.   /*
  750.     Release exclusive access to Host Adapter.
  751.   */
  752.   BusLogic_ReleaseHostAdapterLockIH(HostAdapter, &ProcessorFlags);
  753. }
  754. /*
  755.   BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
  756.   Mailbox for execution by Host Adapter.  The Host Adapter's Lock should
  757.   already have been acquired by the caller.
  758. */
  759. static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T
  760.        *HostAdapter,
  761.      BusLogic_ActionCode_T ActionCode,
  762.      BusLogic_CCB_T *CCB)
  763. {
  764.   BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
  765.   NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
  766.   if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
  767.     {
  768.       CCB->Status = BusLogic_CCB_Active;
  769.       /*
  770. The CCB field must be written before the Action Code field since
  771. the Host Adapter is operating asynchronously and the locking code
  772. does not protect against simultaneous access by the Host Adapter.
  773.       */
  774.       NextOutgoingMailbox->CCB = Virtual_to_Bus(CCB);
  775.       NextOutgoingMailbox->ActionCode = ActionCode;
  776.       BusLogic_StartMailboxCommand(HostAdapter);
  777.       if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
  778. NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
  779.       HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
  780.       if (ActionCode == BusLogic_MailboxStartCommand)
  781. {
  782.   HostAdapter->ActiveCommands[CCB->TargetID]++;
  783.   if (CCB->Opcode != BusLogic_BusDeviceReset)
  784.     HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
  785. }
  786.       return true;
  787.     }
  788.   return false;
  789. }
  790. /*
  791.   BusLogic_QueueCommand creates a CCB for Command and places it into an
  792.   Outgoing Mailbox for execution by the associated Host Adapter.
  793. */
  794. int BusLogic_QueueCommand(SCSI_Command_T *Command,
  795.   void (*CompletionRoutine)(SCSI_Command_T *))
  796. {
  797.   BusLogic_HostAdapter_T *HostAdapter =
  798.     (BusLogic_HostAdapter_T *) Command->host->hostdata;
  799.   BusLogic_TargetFlags_T *TargetFlags =
  800.     &HostAdapter->TargetFlags[Command->target];
  801.   BusLogic_TargetStatistics_T *TargetStatistics =
  802.     HostAdapter->TargetStatistics;
  803.   unsigned char *CDB = Command->cmnd;
  804.   int CDB_Length = Command->cmd_len;
  805.   int TargetID = Command->target;
  806.   int LogicalUnit = Command->lun;
  807.   void *BufferPointer = Command->request_buffer;
  808.   int BufferLength = Command->request_bufflen;
  809.   int SegmentCount = Command->use_sg;
  810.   ProcessorFlags_T ProcessorFlags;
  811.   BusLogic_CCB_T *CCB;
  812.   /*
  813.     SCSI REQUEST_SENSE commands will be executed automatically by the Host
  814.     Adapter for any errors, so they should not be executed explicitly unless
  815.     the Sense Data is zero indicating that no error occurred.
  816.   */
  817.   if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
  818.     {
  819.       Command->result = DID_OK << 16;
  820.       CompletionRoutine(Command);
  821.       return 0;
  822.     }
  823.   /*
  824.     Acquire exclusive access to Host Adapter.
  825.   */
  826.   BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
  827.   /*
  828.     Allocate a CCB from the Host Adapter's free list.  In the unlikely event
  829.     that there are none available and memory allocation fails, wait 1 second
  830.     and try again.  If that fails, the Host Adapter is probably hung so signal
  831.     an error as a Host Adapter Hard Reset should be initiated soon.
  832.   */
  833.   CCB = BusLogic_AllocateCCB(HostAdapter);
  834.   if (CCB == NULL)
  835.     {
  836.       BusLogic_Delay(1);
  837.       CCB = BusLogic_AllocateCCB(HostAdapter);
  838.       if (CCB == NULL)
  839. {
  840.   Command->result = DID_ERROR << 16;
  841.   CompletionRoutine(Command);
  842.   goto Done;
  843. }
  844.     }
  845.   /*
  846.     Initialize the fields in the BusLogic Command Control Block (CCB).
  847.   */
  848.   if (SegmentCount == 0)
  849.     {
  850.       CCB->Opcode = BusLogic_InitiatorCCB;
  851.       CCB->DataLength = BufferLength;
  852.       CCB->DataPointer = Virtual_to_Bus(BufferPointer);
  853.     }
  854.   else
  855.     {
  856.       SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
  857.       int Segment;
  858.       CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
  859.       CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
  860.       if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
  861. CCB->DataPointer = Virtual_to_Bus(CCB->ScatterGatherList);
  862.       else CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
  863.       for (Segment = 0; Segment < SegmentCount; Segment++)
  864. {
  865.   CCB->ScatterGatherList[Segment].SegmentByteCount =
  866.     ScatterList[Segment].length;
  867.   CCB->ScatterGatherList[Segment].SegmentDataPointer =
  868.     Virtual_to_Bus(ScatterList[Segment].address);
  869. }
  870.     }
  871.   switch (CDB[0])
  872.     {
  873.     case READ_6:
  874.     case READ_10:
  875.       CCB->DataDirection = BusLogic_DataInLengthChecked;
  876.       TargetStatistics[TargetID].ReadCommands++;
  877.       BusLogic_IncrementByteCounter(
  878. &TargetStatistics[TargetID].TotalBytesRead, BufferLength);
  879.       BusLogic_IncrementSizeBucket(
  880. TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
  881.       break;
  882.     case WRITE_6:
  883.     case WRITE_10:
  884.       CCB->DataDirection = BusLogic_DataOutLengthChecked;
  885.       TargetStatistics[TargetID].WriteCommands++;
  886.       BusLogic_IncrementByteCounter(
  887. &TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
  888.       BusLogic_IncrementSizeBucket(
  889. TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
  890.       break;
  891.     default:
  892.       CCB->DataDirection = BusLogic_UncheckedDataTransfer;
  893.       break;
  894.     }
  895.   CCB->CDB_Length = CDB_Length;
  896.   CCB->SenseDataLength = sizeof(Command->sense_buffer);
  897.   CCB->HostAdapterStatus = 0;
  898.   CCB->TargetDeviceStatus = 0;
  899.   CCB->TargetID = TargetID;
  900.   CCB->LogicalUnit = LogicalUnit;
  901.   CCB->TagEnable = false;
  902.   CCB->LegacyTagEnable = false;
  903.   /*
  904.     BusLogic recommends that after a Reset the first couple of commands that
  905.     are sent to a Target Device be sent in a non Tagged Queue fashion so that
  906.     the Host Adapter and Target Device can establish Synchronous and Wide
  907.     Transfer before Queue Tag messages can interfere with the Synchronous and
  908.     Wide Negotiation messages.  By waiting to enable Tagged Queuing until after
  909.     the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is
  910.     assured that after a Reset any pending commands are requeued before Tagged
  911.     Queuing is enabled and that the Tagged Queuing message will not occur while
  912.     the partition table is being printed.  In addition, some devices do not
  913.     properly handle the transition from non-tagged to tagged commands, so it is
  914.     necessary to wait until there are no pending commands for a target device
  915.     before queuing tagged commands.
  916.   */
  917.   if (HostAdapter->CommandsSinceReset[TargetID]++ >=
  918. BusLogic_MaxTaggedQueueDepth &&
  919.       !TargetFlags->TaggedQueuingActive &&
  920.       HostAdapter->ActiveCommands[TargetID] == 0 &&
  921.       TargetFlags->TaggedQueuingSupported &&
  922.       (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
  923.     {
  924.       TargetFlags->TaggedQueuingActive = true;
  925.       BusLogic_Notice("Tagged Queuing now active for Target %dn",
  926.       HostAdapter, TargetID);
  927.     }
  928.   if (TargetFlags->TaggedQueuingActive)
  929.     {
  930.       BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
  931.       /*
  932. When using Tagged Queuing with Simple Queue Tags, it appears that disk
  933. drive controllers do not guarantee that a queued command will not
  934. remain in a disconnected state indefinitely if commands that read or
  935. write nearer the head position continue to arrive without interruption.
  936. Therefore, for each Target Device this driver keeps track of the last
  937. time either the queue was empty or an Ordered Queue Tag was issued.  If
  938. more than 4 seconds (one fifth of the 20 second disk timeout) have
  939. elapsed since this last sequence point, this command will be issued
  940. with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
  941. the Target Device to complete all previously queued commands before
  942. this command may be executed.
  943.       */
  944.       if (HostAdapter->ActiveCommands[TargetID] == 0)
  945. HostAdapter->LastSequencePoint[TargetID] = jiffies;
  946.       else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 4*HZ)
  947. {
  948.   HostAdapter->LastSequencePoint[TargetID] = jiffies;
  949.   QueueTag = BusLogic_OrderedQueueTag;
  950. }
  951.       if (HostAdapter->ExtendedLUNSupport)
  952. {
  953.   CCB->TagEnable = true;
  954.   CCB->QueueTag = QueueTag;
  955. }
  956.       else
  957. {
  958.   CCB->LegacyTagEnable = true;
  959.   CCB->LegacyQueueTag = QueueTag;
  960. }
  961.     }
  962.   memcpy(CCB->CDB, CDB, CDB_Length);
  963.   CCB->SenseDataPointer = Virtual_to_Bus(&Command->sense_buffer);
  964.   CCB->Command = Command;
  965.   Command->scsi_done = CompletionRoutine;
  966.   if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
  967.     {
  968.       /*
  969. Place the CCB in an Outgoing Mailbox.  The higher levels of the SCSI
  970. Subsystem should not attempt to queue more commands than can be placed
  971. in Outgoing Mailboxes, so there should always be one free.  In the
  972. unlikely event that there are none available, wait 1 second and try
  973. again.  If that fails, the Host Adapter is probably hung so signal an
  974. error as a Host Adapter Hard Reset should be initiated soon.
  975.       */
  976.       if (!BusLogic_WriteOutgoingMailbox(
  977.      HostAdapter, BusLogic_MailboxStartCommand, CCB))
  978. {
  979.   BusLogic_Warning("Unable to write Outgoing Mailbox - "
  980.    "Pausing for 1 secondn", HostAdapter);
  981.   BusLogic_Delay(1);
  982.   if (!BusLogic_WriteOutgoingMailbox(
  983.  HostAdapter, BusLogic_MailboxStartCommand, CCB))
  984.     {
  985.       BusLogic_Warning("Still unable to write Outgoing Mailbox - "
  986.        "Host Adapter Dead?n", HostAdapter);
  987.       BusLogic_DeallocateCCB(CCB);
  988.       Command->result = DID_ERROR << 16;
  989.       Command->scsi_done(Command);
  990.     }
  991. }
  992.     }
  993.   else
  994.     {
  995.       /*
  996. Call the FlashPoint SCCB Manager to start execution of the CCB.
  997.       */
  998.       CCB->Status = BusLogic_CCB_Active;
  999.       HostAdapter->ActiveCommands[TargetID]++;
  1000.       TargetStatistics[TargetID].CommandsAttempted++;
  1001.       FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
  1002.       /*
  1003. The Command may have already completed and BusLogic_QueueCompletedCCB
  1004. been called, or it may still be pending.
  1005.       */
  1006.       if (CCB->Status == BusLogic_CCB_Completed)
  1007. BusLogic_ProcessCompletedCCBs(HostAdapter);
  1008.     }
  1009.   /*
  1010.     Release exclusive access to Host Adapter.
  1011.   */
  1012. Done:
  1013.   BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
  1014.   return 0;
  1015. }
  1016. /*
  1017.   BusLogic_AbortCommand aborts Command if possible.
  1018. */
  1019. int BusLogic_AbortCommand(SCSI_Command_T *Command)
  1020. {
  1021.   BusLogic_HostAdapter_T *HostAdapter =
  1022.     (BusLogic_HostAdapter_T *) Command->host->hostdata;
  1023.   int TargetID = Command->target;
  1024.   ProcessorFlags_T ProcessorFlags;
  1025.   BusLogic_CCB_T *CCB;
  1026.   int Result;
  1027.   BusLogic_IncrementErrorCounter(
  1028.     &HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
  1029.   /*
  1030.     Acquire exclusive access to Host Adapter.
  1031.   */
  1032.   BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
  1033.   /*
  1034.     If this Command has already completed, then no Abort is necessary.
  1035.   */
  1036.   if (Command->serial_number != Command->serial_number_at_timeout)
  1037.     {
  1038.       BusLogic_Warning("Unable to Abort Command to Target %d - "
  1039.        "Already Completedn", HostAdapter, TargetID);
  1040.       Result = SCSI_ABORT_NOT_RUNNING;
  1041.       goto Done;
  1042.     }
  1043.   /*
  1044.     Attempt to find an Active CCB for this Command.  If no Active CCB for this
  1045.     Command is found, then no Abort is necessary.
  1046.   */
  1047.   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
  1048.     if (CCB->Command == Command) break;
  1049.   if (CCB == NULL)
  1050.     {
  1051.       BusLogic_Warning("Unable to Abort Command to Target %d - "
  1052.        "No CCB Foundn", HostAdapter, TargetID);
  1053.       Result = SCSI_ABORT_NOT_RUNNING;
  1054.       goto Done;
  1055.     }
  1056.   else if (CCB->Status == BusLogic_CCB_Completed)
  1057.     {
  1058.       BusLogic_Warning("Unable to Abort Command to Target %d - "
  1059.        "CCB Completedn", HostAdapter, TargetID);
  1060.       Result = SCSI_ABORT_NOT_RUNNING;
  1061.       goto Done;
  1062.     }
  1063.   else if (CCB->Status == BusLogic_CCB_Reset)
  1064.     {
  1065.       BusLogic_Warning("Unable to Abort Command to Target %d - "
  1066.        "CCB Resetn", HostAdapter, TargetID);
  1067.       Result = SCSI_ABORT_PENDING;
  1068.       goto Done;
  1069.     }
  1070.   if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
  1071.     {
  1072.       /*
  1073. Attempt to Abort this CCB.  MultiMaster Firmware versions prior to 5.xx
  1074. do not generate Abort Tag messages, but only generate the non-tagged
  1075. Abort message.  Since non-tagged commands are not sent by the Host
  1076. Adapter until the queue of outstanding tagged commands has completed,
  1077. and the Abort message is treated as a non-tagged command, it is
  1078. effectively impossible to abort commands when Tagged Queuing is active.
  1079. Firmware version 5.xx does generate Abort Tag messages, so it is
  1080. possible to abort commands when Tagged Queuing is active.
  1081.       */
  1082.       if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
  1083.   HostAdapter->FirmwareVersion[0] < '5')
  1084. {
  1085.   BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
  1086.    "Abort Tag Not Supportedn",
  1087.    HostAdapter, CCB->SerialNumber, TargetID);
  1088.   Result = SCSI_ABORT_SNOOZE;
  1089. }
  1090.       else if (BusLogic_WriteOutgoingMailbox(
  1091.  HostAdapter, BusLogic_MailboxAbortCommand, CCB))
  1092. {
  1093.   BusLogic_Warning("Aborting CCB #%ld to Target %dn",
  1094.    HostAdapter, CCB->SerialNumber, TargetID);
  1095.   BusLogic_IncrementErrorCounter(
  1096.     &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
  1097.   Result = SCSI_ABORT_PENDING;
  1098. }
  1099.       else
  1100. {
  1101.   BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
  1102.    "No Outgoing Mailboxesn",
  1103.     HostAdapter, CCB->SerialNumber, TargetID);
  1104.   Result = SCSI_ABORT_BUSY;
  1105. }
  1106.     }
  1107.   else
  1108.     {
  1109.       /*
  1110. Call the FlashPoint SCCB Manager to abort execution of the CCB.
  1111.       */
  1112.       BusLogic_Warning("Aborting CCB #%ld to Target %dn",
  1113.        HostAdapter, CCB->SerialNumber, TargetID);
  1114.       BusLogic_IncrementErrorCounter(
  1115. &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
  1116.       FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB);
  1117.       /*
  1118. The Abort may have already been completed and
  1119. BusLogic_QueueCompletedCCB been called, or it
  1120. may still be pending.
  1121.       */
  1122.       Result = SCSI_ABORT_PENDING;
  1123.       if (CCB->Status == BusLogic_CCB_Completed)
  1124. {
  1125.   BusLogic_ProcessCompletedCCBs(HostAdapter);
  1126.   Result = SCSI_ABORT_SUCCESS;
  1127. }
  1128.     }
  1129.   /*
  1130.     Release exclusive access to Host Adapter.
  1131.   */
  1132. Done:
  1133.   BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
  1134.   return Result;
  1135. }
  1136. /*
  1137.   BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
  1138.   currently executing SCSI Commands as having been Reset.
  1139. */
  1140. static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
  1141.      SCSI_Command_T *Command,
  1142.      unsigned int ResetFlags)
  1143. {
  1144.   ProcessorFlags_T ProcessorFlags;
  1145.   BusLogic_CCB_T *CCB;
  1146.   int TargetID, Result;
  1147.   boolean HardReset;
  1148.   if (HostAdapter->HostAdapterExternalReset)
  1149.     {
  1150.       BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
  1151.       HardReset = false;
  1152.     }
  1153.   else if (HostAdapter->HostAdapterInternalError)
  1154.     {
  1155.       BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
  1156.       HardReset = true;
  1157.     }
  1158.   else
  1159.     {
  1160.       BusLogic_IncrementErrorCounter(
  1161. &HostAdapter->TargetStatistics[Command->target]
  1162.       .HostAdapterResetsRequested);
  1163.       HardReset = true;
  1164.     }
  1165.   /*
  1166.     Acquire exclusive access to Host Adapter.
  1167.   */
  1168.   BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
  1169.   /*
  1170.     If this is an Asynchronous Reset and this Command has already completed,
  1171.     then no Reset is necessary.
  1172.   */
  1173.   if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
  1174.     {
  1175.       TargetID = Command->target;
  1176.       if (Command->serial_number != Command->serial_number_at_timeout)
  1177. {
  1178.   BusLogic_Warning("Unable to Reset Command to Target %d - "
  1179.    "Already Completed or Resetn",
  1180.    HostAdapter, TargetID);
  1181.   Result = SCSI_RESET_NOT_RUNNING;
  1182.   goto Done;
  1183.       }
  1184.       for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
  1185. if (CCB->Command == Command) break;
  1186.       if (CCB == NULL)
  1187. {
  1188.   BusLogic_Warning("Unable to Reset Command to Target %d - "
  1189.    "No CCB Foundn", HostAdapter, TargetID);
  1190.   Result = SCSI_RESET_NOT_RUNNING;
  1191.   goto Done;
  1192. }
  1193.       else if (CCB->Status == BusLogic_CCB_Completed)
  1194. {
  1195.   BusLogic_Warning("Unable to Reset Command to Target %d - "
  1196.    "CCB Completedn", HostAdapter, TargetID);
  1197.   Result = SCSI_RESET_NOT_RUNNING;
  1198.   goto Done;
  1199. }
  1200.       else if (CCB->Status == BusLogic_CCB_Reset &&
  1201.        HostAdapter->BusDeviceResetPendingCCB[TargetID] == NULL)
  1202. {
  1203.   BusLogic_Warning("Unable to Reset Command to Target %d - "
  1204.    "Reset Pendingn", HostAdapter, TargetID);
  1205.   Result = SCSI_RESET_PENDING;
  1206.   goto Done;
  1207. }
  1208.     }
  1209.   if (Command == NULL)
  1210.     {
  1211.       if (HostAdapter->HostAdapterInternalError)
  1212. BusLogic_Warning("Resetting %s due to Host Adapter Internal Errorn",
  1213.  HostAdapter, HostAdapter->FullModelName);
  1214.       else BusLogic_Warning("Resetting %s due to External SCSI Bus Resetn",
  1215.     HostAdapter, HostAdapter->FullModelName);
  1216.     }
  1217.   else
  1218.     {
  1219.       BusLogic_Warning("Resetting %s due to Target %dn", HostAdapter,
  1220.        HostAdapter->FullModelName, Command->target);
  1221.       BusLogic_IncrementErrorCounter(
  1222. &HostAdapter->TargetStatistics[Command->target]
  1223.       .HostAdapterResetsAttempted);
  1224.     }
  1225.   /*
  1226.     Attempt to Reset and Reinitialize the Host Adapter.
  1227.   */
  1228.   if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) &&
  1229. BusLogic_InitializeHostAdapter(HostAdapter)))
  1230.     {
  1231.       BusLogic_Error("Resetting %s Failedn", HostAdapter,
  1232.      HostAdapter->FullModelName);
  1233.       Result = SCSI_RESET_ERROR;
  1234.       goto Done;
  1235.     }
  1236.   if (Command != NULL)
  1237.     BusLogic_IncrementErrorCounter(
  1238.       &HostAdapter->TargetStatistics[Command->target]
  1239.     .HostAdapterResetsCompleted);
  1240.   /*
  1241.     Mark all currently executing CCBs as having been Reset.
  1242.   */
  1243.   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
  1244.     if (CCB->Status == BusLogic_CCB_Active)
  1245.       CCB->Status = BusLogic_CCB_Reset;
  1246.   /*
  1247.     Wait a few seconds between the Host Adapter Hard Reset which initiates
  1248.     a SCSI Bus Reset and issuing any SCSI Commands.  Some SCSI devices get
  1249.     confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
  1250.     Note that a timer interrupt may occur here, but all active CCBs have
  1251.     already been marked Reset and so a reentrant call will return Pending.
  1252.   */
  1253.   if (HardReset)
  1254.     BusLogic_Delay(HostAdapter->BusSettleTime);
  1255.   /*
  1256.     If this is a Synchronous Reset, perform completion processing for
  1257.     the Command being Reset.
  1258.   */
  1259.   if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
  1260.     {
  1261.       Command->result = DID_RESET << 16;
  1262.       Command->scsi_done(Command);
  1263.     }
  1264.   /*
  1265.     Perform completion processing for all CCBs marked as Reset.
  1266.   */
  1267.   for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
  1268.     if (CCB->Status == BusLogic_CCB_Reset)
  1269.       {
  1270. Command = CCB->Command;
  1271. BusLogic_DeallocateCCB(CCB);
  1272. while (Command != NULL)
  1273.   {
  1274.     SCSI_Command_T *NextCommand = Command->reset_chain;
  1275.     Command->reset_chain = NULL;
  1276.     Command->result = DID_RESET << 16;
  1277.     Command->scsi_done(Command);
  1278.     Command = NextCommand;
  1279.   }
  1280.       }
  1281.   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  1282.     {
  1283.       HostAdapter->LastResetAttempted[TargetID] = jiffies;
  1284.       HostAdapter->LastResetCompleted[TargetID] = jiffies;
  1285.     }
  1286.   Result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET;
  1287.   /*
  1288.     Release exclusive access to Host Adapter.
  1289.   */
  1290. Done:
  1291.   BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
  1292.   return Result;
  1293. }
  1294. /*
  1295.   BusLogic_SendBusDeviceReset sends a Bus Device Reset to the Target
  1296.   Device associated with Command.
  1297. */
  1298. static int BusLogic_SendBusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
  1299.        SCSI_Command_T *Command,
  1300.        unsigned int ResetFlags)
  1301. {
  1302.   int TargetID = Command->target;
  1303.   BusLogic_CCB_T *CCB, *XCCB;
  1304.   ProcessorFlags_T ProcessorFlags;
  1305.   int Result = -1;
  1306.   BusLogic_IncrementErrorCounter(
  1307.     &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsRequested);
  1308.   /*
  1309.     Acquire exclusive access to Host Adapter.
  1310.   */
  1311.   BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
  1312.   /*
  1313.     If this is an Asynchronous Reset and this Command has already completed,
  1314.     then no Reset is necessary.
  1315.   */
  1316.   if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
  1317.     {
  1318.       if (Command->serial_number != Command->serial_number_at_timeout)
  1319. {
  1320.   BusLogic_Warning("Unable to Reset Command to Target %d - "
  1321.    "Already Completedn", HostAdapter, TargetID);
  1322.   Result = SCSI_RESET_NOT_RUNNING;
  1323.   goto Done;
  1324. }
  1325.       for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
  1326. if (CCB->Command == Command) break;
  1327.       if (CCB == NULL)
  1328. {
  1329.   BusLogic_Warning("Unable to Reset Command to Target %d - "
  1330.    "No CCB Foundn", HostAdapter, TargetID);
  1331.   Result = SCSI_RESET_NOT_RUNNING;
  1332.   goto Done;
  1333. }
  1334.       else if (CCB->Status == BusLogic_CCB_Completed)
  1335. {
  1336.   BusLogic_Warning("Unable to Reset Command to Target %d - "
  1337.    "CCB Completedn", HostAdapter, TargetID);
  1338.   Result = SCSI_RESET_NOT_RUNNING;
  1339.   goto Done;
  1340. }
  1341.       else if (CCB->Status == BusLogic_CCB_Reset)
  1342. {
  1343.   BusLogic_Warning("Unable to Reset Command to Target %d - "
  1344.    "Reset Pendingn", HostAdapter, TargetID);
  1345.   Result = SCSI_RESET_PENDING;
  1346.   goto Done;
  1347. }
  1348.       else if (HostAdapter->BusDeviceResetPendingCCB[TargetID] != NULL)
  1349. {
  1350.   BusLogic_Warning("Bus Device Reset already pending to Target %dn",
  1351.    HostAdapter, TargetID);
  1352.   goto Done;
  1353. }
  1354.     }
  1355.   /*
  1356.     If this is a Synchronous Reset and a Bus Device Reset is already pending
  1357.     for this Target Device, do not send a second one.  Add this Command to
  1358.     the list of Commands for which completion processing must be performed
  1359.     when the Bus Device Reset CCB completes.
  1360.   */
  1361.   if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
  1362.     if ((CCB = HostAdapter->BusDeviceResetPendingCCB[TargetID]) != NULL)
  1363.       {
  1364. Command->reset_chain = CCB->Command;
  1365. CCB->Command = Command;
  1366. BusLogic_Warning("Unable to Reset Command to Target %d - "
  1367.  "Reset Pendingn", HostAdapter, TargetID);
  1368. Result = SCSI_RESET_PENDING;
  1369. goto Done;
  1370.       }
  1371.   if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
  1372.     {
  1373.       /*
  1374. MultiMaster Firmware versions prior to 5.xx treat a Bus Device Reset as
  1375. a non-tagged command.  Since non-tagged commands are not sent by the
  1376. Host Adapter until the queue of outstanding tagged commands has
  1377. completed, it is effectively impossible to send a Bus Device Reset
  1378. while there are tagged commands outstanding.  Therefore, in that case a
  1379. full Host Adapter Hard Reset and SCSI Bus Reset must be done.
  1380.       */
  1381.       if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
  1382.   HostAdapter->ActiveCommands[TargetID] > 0 &&
  1383.   HostAdapter->FirmwareVersion[0] < '5')
  1384. goto Done;
  1385.     }
  1386.   /*
  1387.     Allocate a CCB from the Host Adapter's free list.  In the unlikely event
  1388.     that there are none available and memory allocation fails, attempt a full
  1389.     Host Adapter Hard Reset and SCSI Bus Reset.
  1390.   */
  1391.   CCB = BusLogic_AllocateCCB(HostAdapter);
  1392.   if (CCB == NULL) goto Done;
  1393.   BusLogic_Warning("Sending Bus Device Reset CCB #%ld to Target %dn",
  1394.    HostAdapter, CCB->SerialNumber, TargetID);
  1395.   CCB->Opcode = BusLogic_BusDeviceReset;
  1396.   CCB->TargetID = TargetID;
  1397.   /*
  1398.     For Synchronous Resets, arrange for the interrupt handler to perform
  1399.     completion processing for the Command being Reset.
  1400.   */
  1401.   if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
  1402.     {
  1403.       Command->reset_chain = NULL;
  1404.       CCB->Command = Command;
  1405.     }
  1406.   if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
  1407.     {
  1408.       /*
  1409. Attempt to write an Outgoing Mailbox with the Bus Device Reset CCB.
  1410. If sending a Bus Device Reset is impossible, attempt a full Host
  1411. Adapter Hard Reset and SCSI Bus Reset.
  1412.       */
  1413.       if (!(BusLogic_WriteOutgoingMailbox(
  1414.       HostAdapter, BusLogic_MailboxStartCommand, CCB)))
  1415. {
  1416.   BusLogic_Warning("Unable to write Outgoing Mailbox for "
  1417.    "Bus Device Resetn", HostAdapter);
  1418.   BusLogic_DeallocateCCB(CCB);
  1419.   goto Done;
  1420. }
  1421.     }
  1422.   else
  1423.     {
  1424.       /*
  1425. Call the FlashPoint SCCB Manager to start execution of the CCB.
  1426.       */
  1427.       CCB->Status = BusLogic_CCB_Active;
  1428.       HostAdapter->ActiveCommands[TargetID]++;
  1429.       FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
  1430.     }
  1431.   /*
  1432.     If there is a currently executing CCB in the Host Adapter for this Command
  1433.     (i.e. this is an Asynchronous Reset), then an Incoming Mailbox entry may be
  1434.     made with a completion code of BusLogic_HostAdapterAssertedBusDeviceReset.
  1435.     If there is no active CCB for this Command (i.e. this is a Synchronous
  1436.     Reset), then the Bus Device Reset CCB's Command field will have been set
  1437.     to the Command so that the interrupt for the completion of the Bus Device
  1438.     Reset can call the Completion Routine for the Command.  On successful
  1439.     execution of a Bus Device Reset, older firmware versions did return the
  1440.     pending CCBs with the appropriate completion code, but more recent firmware
  1441.     versions only return the Bus Device Reset CCB itself.  This driver handles
  1442.     both cases by marking all the currently executing CCBs to this Target
  1443.     Device as Reset.  When the Bus Device Reset CCB is processed by the
  1444.     interrupt handler, any remaining CCBs marked as Reset will have completion
  1445.     processing performed.
  1446.   */
  1447.   BusLogic_IncrementErrorCounter(
  1448.     &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsAttempted);
  1449.   HostAdapter->BusDeviceResetPendingCCB[TargetID] = CCB;
  1450.   HostAdapter->LastResetAttempted[TargetID] = jiffies;
  1451.   for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll)
  1452.     if (XCCB->Status == BusLogic_CCB_Active && XCCB->TargetID == TargetID)
  1453.       XCCB->Status = BusLogic_CCB_Reset;
  1454.   /*
  1455.     FlashPoint Host Adapters may have already completed the Bus Device
  1456.     Reset and BusLogic_QueueCompletedCCB been called, or it may still be
  1457.     pending.
  1458.   */
  1459.   Result = SCSI_RESET_PENDING;
  1460.   if (BusLogic_FlashPointHostAdapterP(HostAdapter))
  1461.     if (CCB->Status == BusLogic_CCB_Completed)
  1462.       {
  1463. BusLogic_ProcessCompletedCCBs(HostAdapter);
  1464. Result = SCSI_RESET_SUCCESS;
  1465.       }
  1466.   /*
  1467.     If a Bus Device Reset was not possible for some reason, force a full
  1468.     Host Adapter Hard Reset and SCSI Bus Reset.
  1469.   */
  1470. Done:
  1471.   if (Result < 0)
  1472.     Result = BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
  1473.   /*
  1474.     Release exclusive access to Host Adapter.
  1475.   */
  1476.   BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
  1477.   return Result;
  1478. }
  1479. /*
  1480.   BusLogic_ResetCommand takes appropriate action to reset Command.
  1481. */
  1482. int BusLogic_ResetCommand(SCSI_Command_T *Command, unsigned int ResetFlags)
  1483. {
  1484.   BusLogic_HostAdapter_T *HostAdapter =
  1485.     (BusLogic_HostAdapter_T *) Command->host->hostdata;
  1486.   int TargetID = Command->target;
  1487.   BusLogic_ErrorRecoveryStrategy_T
  1488.     ErrorRecoveryStrategy = HostAdapter->ErrorRecoveryStrategy[TargetID];
  1489.   /*
  1490.     Disable Tagged Queuing if it is active for this Target Device and if
  1491.     it has been less than 10 minutes since the last reset occurred, or since
  1492.     the system was initialized if no prior resets have occurred.
  1493.   */
  1494.   if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
  1495.       jiffies - HostAdapter->LastResetCompleted[TargetID] < 10*60*HZ)
  1496.     {
  1497.       HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
  1498.       HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
  1499.       BusLogic_Warning("Tagged Queuing now disabled for Target %dn",
  1500.        HostAdapter, TargetID);
  1501.     }
  1502.   switch (ErrorRecoveryStrategy)
  1503.     {
  1504.     case BusLogic_ErrorRecovery_Default:
  1505.       if (ResetFlags & SCSI_RESET_SUGGEST_HOST_RESET)
  1506. return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
  1507.       else if (ResetFlags & SCSI_RESET_SUGGEST_BUS_RESET)
  1508. return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
  1509.       /* Fall through to Bus Device Reset case. */
  1510.     case BusLogic_ErrorRecovery_BusDeviceReset:
  1511.       /*
  1512. The Bus Device Reset Error Recovery Strategy only graduates to a Hard
  1513. Reset when no commands have completed successfully since the last Bus
  1514. Device Reset and it has been at least 100 milliseconds.  This prevents
  1515. a sequence of commands that all timeout together from immediately
  1516. forcing a Hard Reset before the Bus Device Reset has had a chance to
  1517. clear the error condition.
  1518.       */
  1519.       if (HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag ||
  1520.   jiffies - HostAdapter->LastResetAttempted[TargetID] < HZ/10)
  1521. {
  1522.   HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
  1523.   return BusLogic_SendBusDeviceReset(HostAdapter, Command, ResetFlags);
  1524. }
  1525.       /* Fall through to Hard Reset case. */
  1526.     case BusLogic_ErrorRecovery_HardReset:
  1527.       return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
  1528.     case BusLogic_ErrorRecovery_None:
  1529.       BusLogic_Warning("Error Recovery for Target %d Suppressedn",
  1530.        HostAdapter, TargetID);
  1531.       break;
  1532.     }
  1533.   return SCSI_RESET_PUNT;
  1534. }
  1535. /*
  1536.   BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
  1537.   Parameters for Disk.  The default disk geometry is 64 heads, 32 sectors, and
  1538.   the appropriate number of cylinders so as not to exceed drive capacity.  In
  1539.   order for disks equal to or larger than 1 GB to be addressable by the BIOS
  1540.   without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
  1541.   may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
  1542.   series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
  1543.   series MultiMaster Host Adapters.  With Extended Translation enabled, drives
  1544.   between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
  1545.   heads and 32 sectors, and drives above 2 GB inclusive are given a disk
  1546.   geometry of 255 heads and 63 sectors.  However, if the BIOS detects that the
  1547.   Extended Translation setting does not match the geometry in the partition
  1548.   table, then the translation inferred from the partition table will be used by
  1549.   the BIOS, and a warning may be displayed.
  1550. */
  1551. int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
  1552. int *Parameters)
  1553. {
  1554.   BusLogic_HostAdapter_T *HostAdapter =
  1555.     (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
  1556.   BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
  1557.   struct buffer_head *BufferHead;
  1558.   if (HostAdapter->ExtendedTranslationEnabled &&
  1559.       Disk->capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */)
  1560.     {
  1561.       if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
  1562. {
  1563.   DiskParameters->Heads = 255;
  1564.   DiskParameters->Sectors = 63;
  1565. }
  1566.       else
  1567. {
  1568.   DiskParameters->Heads = 128;
  1569.   DiskParameters->Sectors = 32;
  1570. }
  1571.     }
  1572.   else
  1573.     {
  1574.       DiskParameters->Heads = 64;
  1575.       DiskParameters->Sectors = 32;
  1576.     }
  1577.   DiskParameters->Cylinders =
  1578.     Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
  1579.   /*
  1580.     Attempt to read the first 1024 bytes from the disk device.
  1581.   */
  1582.   BufferHead = bread(MKDEV(MAJOR(Device), MINOR(Device) & ~0x0F), 0, block_size(Device));
  1583.   if (BufferHead == NULL) return 0;
  1584.   /*
  1585.     If the boot sector partition table flag is valid, search for a partition
  1586.     table entry whose end_head matches one of the standard BusLogic geometry
  1587.     translations (64/32, 128/32, or 255/63).
  1588.   */
  1589.   if (*(unsigned short *) (BufferHead->b_data + 0x1FE) == 0xAA55)
  1590.     {
  1591.       PartitionTable_T *FirstPartitionEntry =
  1592. (PartitionTable_T *) (BufferHead->b_data + 0x1BE);
  1593.       PartitionTable_T *PartitionEntry = FirstPartitionEntry;
  1594.       int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
  1595.       unsigned char PartitionEntryEndHead, PartitionEntryEndSector;
  1596.       for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++)
  1597. {
  1598.   PartitionEntryEndHead = PartitionEntry->end_head;
  1599.   PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
  1600.   if (PartitionEntryEndHead == 64-1)
  1601.     {
  1602.       DiskParameters->Heads = 64;
  1603.       DiskParameters->Sectors = 32;
  1604.       break;
  1605.     }
  1606.   else if (PartitionEntryEndHead == 128-1)
  1607.     {
  1608.       DiskParameters->Heads = 128;
  1609.       DiskParameters->Sectors = 32;
  1610.       break;
  1611.     }
  1612.   else if (PartitionEntryEndHead == 255-1)
  1613.     {
  1614.       DiskParameters->Heads = 255;
  1615.       DiskParameters->Sectors = 63;
  1616.       break;
  1617.     }
  1618.   PartitionEntry++;
  1619. }
  1620.       if (PartitionNumber == 4)
  1621. {
  1622.   PartitionEntryEndHead = FirstPartitionEntry->end_head;
  1623.   PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
  1624. }
  1625.       DiskParameters->Cylinders =
  1626. Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
  1627.       if (PartitionNumber < 4 &&
  1628.   PartitionEntryEndSector == DiskParameters->Sectors)
  1629. {
  1630.   if (DiskParameters->Cylinders != SavedCylinders)
  1631.     BusLogic_Warning("Adopting Geometry %d/%d from Partition Tablen",
  1632.      HostAdapter,
  1633.      DiskParameters->Heads, DiskParameters->Sectors);
  1634. }
  1635.       else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0)
  1636. {
  1637.   BusLogic_Warning("Warning: Partition Table appears to "
  1638.    "have Geometry %d/%d which isn", HostAdapter,
  1639.    PartitionEntryEndHead + 1,
  1640.    PartitionEntryEndSector);
  1641.   BusLogic_Warning("not compatible with current BusLogic "
  1642.    "Host Adapter Geometry %d/%dn", HostAdapter,
  1643.    DiskParameters->Heads, DiskParameters->Sectors);
  1644. }
  1645.     }
  1646.   brelse(BufferHead);
  1647.   return 0;
  1648. }
  1649. /*
  1650.   BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
  1651. */
  1652. int BusLogic_ProcDirectoryInfo(char *ProcBuffer, char **StartPointer,
  1653.        off_t Offset, int BytesAvailable,
  1654.        int HostNumber, int WriteFlag)
  1655. {
  1656.   BusLogic_HostAdapter_T *HostAdapter;
  1657.   BusLogic_TargetStatistics_T *TargetStatistics;
  1658.   int TargetID, Length;
  1659.   char *Buffer;
  1660.   for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
  1661.        HostAdapter != NULL;
  1662.        HostAdapter = HostAdapter->Next)
  1663.     if (HostAdapter->HostNumber == HostNumber) break;
  1664.   if (HostAdapter == NULL)
  1665.     {
  1666.       BusLogic_Error("Cannot find Host Adapter for SCSI Host %dn",
  1667.      NULL, HostNumber);
  1668.       return 0;
  1669.     }
  1670.   TargetStatistics = HostAdapter->TargetStatistics;
  1671.   if (WriteFlag)
  1672.     {
  1673.       HostAdapter->ExternalHostAdapterResets = 0;
  1674.       HostAdapter->HostAdapterInternalErrors = 0;
  1675.       memset(TargetStatistics, 0,
  1676.      BusLogic_MaxTargetDevices * sizeof(BusLogic_TargetStatistics_T));
  1677.       return 0;
  1678.     }
  1679.   Buffer = HostAdapter->MessageBuffer;
  1680.   Length = HostAdapter->MessageBufferLength;
  1681.   Length += sprintf(&Buffer[Length], "n
  1682. Current Driver Queue Depth: %dn
  1683. Currently Allocated CCBs: %dn",
  1684.     HostAdapter->DriverQueueDepth,
  1685.     HostAdapter->AllocatedCCBs);
  1686.   Length += sprintf(&Buffer[Length], "nn
  1687.    DATA TRANSFER STATISTICSn
  1688. n
  1689. Target Tagged Queuing Queue Depth  Active  Attempted Completedn
  1690. ====== ============== ===========  ======  ========= =========n");
  1691.   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  1692.     {
  1693.       BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
  1694.       if (!TargetFlags->TargetExists) continue;
  1695.       Length +=
  1696. sprintf(&Buffer[Length], "  %2d %s", TargetID,
  1697. (TargetFlags->TaggedQueuingSupported
  1698.  ? (TargetFlags->TaggedQueuingActive
  1699.     ? "    Active"
  1700.     : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
  1701.        ? "  Permitted" : "   Disabled"))
  1702.  : "Not Supported"));
  1703.       Length += sprintf(&Buffer[Length],
  1704. "     %3d       %3u    %9u %9un",
  1705. HostAdapter->QueueDepth[TargetID],
  1706. HostAdapter->ActiveCommands[TargetID],
  1707. TargetStatistics[TargetID].CommandsAttempted,
  1708. TargetStatistics[TargetID].CommandsCompleted);
  1709.     }
  1710.   Length += sprintf(&Buffer[Length], "n
  1711. Target  Read Commands  Write Commands   Total Bytes Read    Total Bytes Writtenn
  1712. ======  =============  ==============  ===================  ===================n");
  1713.   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  1714.     {
  1715.       BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
  1716.       if (!TargetFlags->TargetExists) continue;
  1717.       Length +=
  1718. sprintf(&Buffer[Length], "  %2d   %9u  %9u", TargetID,
  1719. TargetStatistics[TargetID].ReadCommands,
  1720. TargetStatistics[TargetID].WriteCommands);
  1721.       if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
  1722. Length +=
  1723.   sprintf(&Buffer[Length], "     %9u%09u",
  1724.   TargetStatistics[TargetID].TotalBytesRead.Billions,
  1725.   TargetStatistics[TargetID].TotalBytesRead.Units);
  1726.       else
  1727. Length +=
  1728.   sprintf(&Buffer[Length], " %9u",
  1729.   TargetStatistics[TargetID].TotalBytesRead.Units);
  1730.       if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
  1731. Length +=
  1732.   sprintf(&Buffer[Length], "   %9u%09un",
  1733.   TargetStatistics[TargetID].TotalBytesWritten.Billions,
  1734.   TargetStatistics[TargetID].TotalBytesWritten.Units);
  1735.       else
  1736. Length +=
  1737.   sprintf(&Buffer[Length], "      %9un",
  1738.   TargetStatistics[TargetID].TotalBytesWritten.Units);
  1739.     }
  1740.   Length += sprintf(&Buffer[Length], "n
  1741. Target  Command    0-1KB      1-2KB      2-4KB      4-8KB     8-16KBn
  1742. ======  =======  =========  =========  =========  =========  =========n");
  1743.   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  1744.     {
  1745.       BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
  1746.       if (!TargetFlags->TargetExists) continue;
  1747.       Length +=
  1748. sprintf(&Buffer[Length],
  1749. "  %2d  Read  %9u  %9u  %9u  %9u  %9un", TargetID,
  1750. TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
  1751. TargetStatistics[TargetID].ReadCommandSizeBuckets[1],
  1752. TargetStatistics[TargetID].ReadCommandSizeBuckets[2],
  1753. TargetStatistics[TargetID].ReadCommandSizeBuckets[3],
  1754. TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
  1755.       Length +=
  1756. sprintf(&Buffer[Length],
  1757. "  %2d  Write  %9u  %9u  %9u  %9u  %9un", TargetID,
  1758. TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
  1759. TargetStatistics[TargetID].WriteCommandSizeBuckets[1],
  1760. TargetStatistics[TargetID].WriteCommandSizeBuckets[2],
  1761. TargetStatistics[TargetID].WriteCommandSizeBuckets[3],
  1762. TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
  1763.     }
  1764.   Length += sprintf(&Buffer[Length], "n
  1765. Target  Command   16-32KB    32-64KB   64-128KB   128-256KB   256KB+n
  1766. ======  =======  =========  =========  =========  =========  =========n");
  1767.   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  1768.     {
  1769.       BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
  1770.       if (!TargetFlags->TargetExists) continue;
  1771.       Length +=
  1772. sprintf(&Buffer[Length],
  1773. "  %2d  Read  %9u  %9u  %9u  %9u  %9un", TargetID,
  1774. TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
  1775. TargetStatistics[TargetID].ReadCommandSizeBuckets[6],
  1776. TargetStatistics[TargetID].ReadCommandSizeBuckets[7],
  1777. TargetStatistics[TargetID].ReadCommandSizeBuckets[8],
  1778. TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
  1779.       Length +=
  1780. sprintf(&Buffer[Length],
  1781. "  %2d  Write  %9u  %9u  %9u  %9u  %9un", TargetID,
  1782. TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
  1783. TargetStatistics[TargetID].WriteCommandSizeBuckets[6],
  1784. TargetStatistics[TargetID].WriteCommandSizeBuckets[7],
  1785. TargetStatistics[TargetID].WriteCommandSizeBuckets[8],
  1786. TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
  1787.     }
  1788.   Length += sprintf(&Buffer[Length], "nn
  1789.    ERROR RECOVERY STATISTICSn
  1790. n
  1791.   Command Aborts      Bus Device Resets   Host Adapter Resetsn
  1792. Target Requested Completed  Requested Completed  Requested Completedn
  1793.   ID \\\\ Attempted ////  \\\\ Attempted ////  \\\\ Attempted ////n
  1794. ======  ===== ===== =====    ===== ===== =====    ===== ===== =====n");
  1795.   for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  1796.     {
  1797.       BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
  1798.       if (!TargetFlags->TargetExists) continue;
  1799.       Length +=
  1800. sprintf(&Buffer[Length], "
  1801.   %2d  %5d %5d %5d    %5d %5d %5d    %5d %5d %5dn", TargetID,
  1802. TargetStatistics[TargetID].CommandAbortsRequested,
  1803. TargetStatistics[TargetID].CommandAbortsAttempted,
  1804. TargetStatistics[TargetID].CommandAbortsCompleted,
  1805. TargetStatistics[TargetID].BusDeviceResetsRequested,
  1806. TargetStatistics[TargetID].BusDeviceResetsAttempted,
  1807. TargetStatistics[TargetID].BusDeviceResetsCompleted,
  1808. TargetStatistics[TargetID].HostAdapterResetsRequested,
  1809. TargetStatistics[TargetID].HostAdapterResetsAttempted,
  1810. TargetStatistics[TargetID].HostAdapterResetsCompleted);
  1811.     }
  1812.   Length += sprintf(&Buffer[Length], "nExternal Host Adapter Resets: %dn",
  1813.     HostAdapter->ExternalHostAdapterResets);
  1814.   Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %dn",
  1815.     HostAdapter->HostAdapterInternalErrors);
  1816.   if (Length >= BusLogic_MessageBufferSize)
  1817.     BusLogic_Error("Message Buffer length %d exceeds size %dn",
  1818.    HostAdapter, Length, BusLogic_MessageBufferSize);
  1819.   if ((Length -= Offset) <= 0) return 0;
  1820.   if (Length >= BytesAvailable) Length = BytesAvailable;
  1821.   memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length);
  1822.   *StartPointer = ProcBuffer;
  1823.   return Length;
  1824. }
  1825. /*
  1826.   BusLogic_Message prints Driver Messages.
  1827. */
  1828. static void BusLogic_Message(BusLogic_MessageLevel_T MessageLevel,
  1829.      char *Format,
  1830.      BusLogic_HostAdapter_T *HostAdapter,
  1831.      ...)
  1832. {
  1833.   static char Buffer[BusLogic_LineBufferSize];
  1834.   static boolean BeginningOfLine = true;
  1835.   va_list Arguments;
  1836.   int Length = 0;
  1837.   va_start(Arguments, HostAdapter);
  1838.   Length = vsprintf(Buffer, Format, Arguments);
  1839.   va_end(Arguments);
  1840.   if (MessageLevel == BusLogic_AnnounceLevel)
  1841.     {
  1842.       static int AnnouncementLines = 0;
  1843.       strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
  1844.      Buffer);
  1845.       HostAdapter->MessageBufferLength += Length;
  1846.       if (++AnnouncementLines <= 2)
  1847. printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
  1848.     }
  1849.   else if (MessageLevel == BusLogic_InfoLevel)
  1850.     {
  1851.       strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
  1852.      Buffer);
  1853.       HostAdapter->MessageBufferLength += Length;
  1854.       if (BeginningOfLine)
  1855. {
  1856.   if (Buffer[0] != 'n' || Length > 1)
  1857.     printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
  1858.    HostAdapter->HostNumber, Buffer);
  1859. }
  1860.       else printk("%s", Buffer);
  1861.     }
  1862.   else
  1863.     {
  1864.       if (BeginningOfLine)
  1865. {
  1866.   if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
  1867.     printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
  1868.    HostAdapter->HostNumber, Buffer);
  1869.   else printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
  1870. }
  1871.       else printk("%s", Buffer);
  1872.     }
  1873.   BeginningOfLine = (Buffer[Length-1] == 'n');
  1874. }
  1875. /*
  1876.   BusLogic_ParseKeyword parses an individual option keyword.  It returns true
  1877.   and updates the pointer if the keyword is recognized and false otherwise.
  1878. */
  1879. static boolean BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
  1880. {
  1881.   char *Pointer = *StringPointer;
  1882.   while (*Keyword != '')
  1883.     {
  1884.       char StringChar = *Pointer++;
  1885.       char KeywordChar = *Keyword++;
  1886.       if (StringChar >= 'A' && StringChar <= 'Z')
  1887. StringChar += 'a' - 'Z';
  1888.       if (KeywordChar >= 'A' && KeywordChar <= 'Z')
  1889. KeywordChar += 'a' - 'Z';
  1890.       if (StringChar != KeywordChar) return false;
  1891.     }
  1892.   *StringPointer = Pointer;
  1893.   return true;
  1894. }
  1895. /*
  1896.   BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options
  1897.   specifications.
  1898.   BusLogic Driver Options may be specified either via the Linux Kernel Command
  1899.   Line or via the Loadable Kernel Module Installation Facility.  Driver Options
  1900.   for multiple host adapters may be specified either by separating the option
  1901.   strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
  1902.   command line.  Individual option specifications for a single host adapter are
  1903.   separated by commas.  The Probing and Debugging Options apply to all host
  1904.   adapters whereas the remaining options apply individually only to the
  1905.   selected host adapter.
  1906.   The BusLogic Driver Probing Options comprise the following:
  1907.   IO:<integer>
  1908.     The "IO:" option specifies an ISA I/O Address to be probed for a non-PCI
  1909.     MultiMaster Host Adapter.  If neither "IO:" nor "NoProbeISA" options are
  1910.     specified, then the standard list of BusLogic MultiMaster ISA I/O Addresses
  1911.     will be probed (0x330, 0x334, 0x230, 0x234, 0x130, and 0x134).  Multiple
  1912.     "IO:" options may be specified to precisely determine the I/O Addresses to
  1913.     be probed, but the probe order will always follow the standard list.
  1914.   NoProbe
  1915.     The "NoProbe" option disables all probing and therefore no BusLogic Host
  1916.     Adapters will be detected.
  1917.   NoProbeISA
  1918.     The "NoProbeISA" option disables probing of the standard BusLogic ISA I/O
  1919.     Addresses and therefore only PCI MultiMaster and FlashPoint Host Adapters
  1920.     will be detected.
  1921.   NoProbePCI
  1922.     The "NoProbePCI" options disables the interrogation of PCI Configuration
  1923.     Space and therefore only ISA Multimaster Host Adapters will be detected, as
  1924.     well as PCI Multimaster Host Adapters that have their ISA Compatible I/O
  1925.     Port set to "Primary" or "Alternate".
  1926.   NoSortPCI
  1927.     The "NoSortPCI" option forces PCI MultiMaster Host Adapters to be
  1928.     enumerated in the order provided by the PCI BIOS, ignoring any setting of
  1929.     the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option.
  1930.   MultiMasterFirst
  1931.     The "MultiMasterFirst" option forces MultiMaster Host Adapters to be probed
  1932.     before FlashPoint Host Adapters.  By default, if both FlashPoint and PCI
  1933.     MultiMaster Host Adapters are present, this driver will probe for
  1934.     FlashPoint Host Adapters first unless the BIOS primary disk is controlled
  1935.     by the first PCI MultiMaster Host Adapter, in which case MultiMaster Host
  1936.     Adapters will be probed first.
  1937.   FlashPointFirst
  1938.     The "FlashPointFirst" option forces FlashPoint Host Adapters to be probed
  1939.     before MultiMaster Host Adapters.
  1940.   The BusLogic Driver Tagged Queuing Options allow for explicitly specifying
  1941.   the Queue Depth and whether Tagged Queuing is permitted for each Target
  1942.   Device (assuming that the Target Device supports Tagged Queuing).  The Queue
  1943.   Depth is the number of SCSI Commands that are allowed to be concurrently
  1944.   presented for execution (either to the Host Adapter or Target Device).  Note
  1945.   that explicitly enabling Tagged Queuing may lead to problems; the option to
  1946.   enable or disable Tagged Queuing is provided primarily to allow disabling
  1947.   Tagged Queuing on Target Devices that do not implement it correctly.  The
  1948.   following options are available:
  1949.   QueueDepth:<integer>
  1950.     The "QueueDepth:" or QD:" option specifies the Queue Depth to use for all
  1951.     Target Devices that support Tagged Queuing, as well as the maximum Queue
  1952.     Depth for devices that do not support Tagged Queuing.  If no Queue Depth
  1953.     option is provided, the Queue Depth will be determined automatically based
  1954.     on the Host Adapter's Total Queue Depth and the number, type, speed, and
  1955.     capabilities of the detected Target Devices.  For Host Adapters that
  1956.     require ISA Bounce Buffers, the Queue Depth is automatically set by default
  1957.     to BusLogic_TaggedQueueDepthBB or BusLogic_UntaggedQueueDepthBB to avoid
  1958.     excessive preallocation of DMA Bounce Buffer memory.  Target Devices that
  1959.     do not support Tagged Queuing always have their Queue Depth set to
  1960.     BusLogic_UntaggedQueueDepth or BusLogic_UntaggedQueueDepthBB, unless a
  1961.     lower Queue Depth option is provided.  A Queue Depth of 1 automatically
  1962.     disables Tagged Queuing.
  1963.   QueueDepth:[<integer>,<integer>...]
  1964.     The "QueueDepth:[...]" or "QD:[...]" option specifies the Queue Depth
  1965.     individually for each Target Device.  If an <integer> is omitted, the
  1966.     associated Target Device will have its Queue Depth selected automatically.
  1967.   TaggedQueuing:Default
  1968.     The "TaggedQueuing:Default" or "TQ:Default" option permits Tagged Queuing
  1969.     based on the firmware version of the BusLogic Host Adapter and based on
  1970.     whether the Queue Depth allows queuing multiple commands.
  1971.   TaggedQueuing:Enable
  1972.     The "TaggedQueuing:Enable" or "TQ:Enable" option enables Tagged Queuing for
  1973.     all Target Devices on this Host Adapter, overriding any limitation that
  1974.     would otherwise be imposed based on the Host Adapter firmware version.
  1975.   TaggedQueuing:Disable
  1976.     The "TaggedQueuing:Disable" or "TQ:Disable" option disables Tagged Queuing
  1977.     for all Target Devices on this Host Adapter.
  1978.   TaggedQueuing:<Target-Spec>
  1979.     The "TaggedQueuing:<Target-Spec>" or "TQ:<Target-Spec>" option controls
  1980.     Tagged Queuing individually for each Target Device.  <Target-Spec> is a
  1981.     sequence of "Y", "N", and "X" characters.  "Y" enables Tagged Queuing, "N"
  1982.     disables Tagged Queuing, and "X" accepts the default based on the firmware
  1983.     version.  The first character refers to Target Device 0, the second to
  1984.     Target Device 1, and so on; if the sequence of "Y", "N", and "X" characters
  1985.     does not cover all the Target Devices, unspecified characters are assumed
  1986.     to be "X".
  1987.   The BusLogic Driver Error Recovery Option allows for explicitly specifying
  1988.   the Error Recovery action to be performed when BusLogic_ResetCommand is
  1989.   called due to a SCSI Command failing to complete successfully.  The following
  1990.   options are available:
  1991.   ErrorRecovery:Default
  1992.     The "ErrorRecovery:Default" or "ER:Default" option selects between the Hard
  1993.     Reset and Bus Device Reset options based on the recommendation of the SCSI
  1994.     Subsystem.
  1995.   ErrorRecovery:HardReset
  1996.     The "ErrorRecovery:HardReset" or "ER:HardReset" option will initiate a Host
  1997.     Adapter Hard Reset which also causes a SCSI Bus Reset.
  1998.   ErrorRecovery:BusDeviceReset
  1999.     The "ErrorRecovery:BusDeviceReset" or "ER:BusDeviceReset" option will send
  2000.     a Bus Device Reset message to the individual Target Device causing the
  2001.     error.  If Error Recovery is again initiated for this Target Device and no
  2002.     SCSI Command to this Target Device has completed successfully since the Bus
  2003.     Device Reset message was sent, then a Hard Reset will be attempted.
  2004.   ErrorRecovery:None
  2005.     The "ErrorRecovery:None" or "ER:None" option suppresses Error Recovery.
  2006.     This option should only be selected if a SCSI Bus Reset or Bus Device Reset
  2007.     will cause the Target Device or a critical operation to suffer a complete
  2008.     and unrecoverable failure.
  2009.   ErrorRecovery:<Target-Spec>
  2010.     The "ErrorRecovery:<Target-Spec>" or "ER:<Target-Spec>" option controls
  2011.     Error Recovery individually for each Target Device.  <Target-Spec> is a
  2012.     sequence of "D", "H", "B", and "N" characters.  "D" selects Default, "H"
  2013.     selects Hard Reset, "B" selects Bus Device Reset, and "N" selects None.
  2014.     The first character refers to Target Device 0, the second to Target Device
  2015.     1, and so on; if the sequence of "D", "H", "B", and "N" characters does not
  2016.     cover all the possible Target Devices, unspecified characters are assumed
  2017.     to be "D".
  2018.   The BusLogic Driver Miscellaneous Options comprise the following:
  2019.   BusSettleTime:<seconds>
  2020.     The "BusSettleTime:" or "BST:" option specifies the Bus Settle Time in
  2021.     seconds.  The Bus Settle Time is the amount of time to wait between a Host
  2022.     Adapter Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI
  2023.     Commands.  If unspecified, it defaults to BusLogic_DefaultBusSettleTime.
  2024.   InhibitTargetInquiry
  2025.     The "InhibitTargetInquiry" option inhibits the execution of an Inquire
  2026.     Target Devices or Inquire Installed Devices command on MultiMaster Host
  2027.     Adapters.  This may be necessary with some older Target Devices that do not
  2028.     respond correctly when Logical Units above 0 are addressed.
  2029.   The BusLogic Driver Debugging Options comprise the following:
  2030.   TraceProbe
  2031.     The "TraceProbe" option enables tracing of Host Adapter Probing.
  2032.   TraceHardwareReset
  2033.     The "TraceHardwareReset" option enables tracing of Host Adapter Hardware
  2034.     Reset.
  2035.   TraceConfiguration
  2036.     The "TraceConfiguration" option enables tracing of Host Adapter
  2037.     Configuration.
  2038.   TraceErrors
  2039.     The "TraceErrors" option enables tracing of SCSI Commands that return an
  2040.     error from the Target Device.  The CDB and Sense Data will be printed for
  2041.     each SCSI Command that fails.
  2042.   Debug
  2043.     The "Debug" option enables all debugging options.
  2044.   The following examples demonstrate setting the Queue Depth for Target Devices
  2045.   1 and 2 on the first host adapter to 7 and 15, the Queue Depth for all Target
  2046.   Devices on the second host adapter to 31, and the Bus Settle Time on the
  2047.   second host adapter to 30 seconds.
  2048.   Linux Kernel Command Line:
  2049.     linux BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30
  2050.   LILO Linux Boot Loader (in /etc/lilo.conf):
  2051.     append = "BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"
  2052.   INSMOD Loadable Kernel Module Installation Facility:
  2053.     insmod BusLogic.o 
  2054. 'BusLogic="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"'
  2055.   NOTE: Module Utilities 2.1.71 or later is required for correct parsing
  2056. of driver options containing commas.
  2057. */
  2058. static int __init BusLogic_ParseDriverOptions(char *OptionsString)
  2059. {
  2060.   while (true)
  2061.     {
  2062.       BusLogic_DriverOptions_T *DriverOptions =
  2063. &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
  2064.       int TargetID;
  2065.       memset(DriverOptions, 0, sizeof(BusLogic_DriverOptions_T));
  2066.       for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
  2067. DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2068.   BusLogic_ErrorRecovery_Default;
  2069.       while (*OptionsString != '' && *OptionsString != ';')
  2070. {
  2071.   /* Probing Options. */
  2072.   if (BusLogic_ParseKeyword(&OptionsString, "IO:"))
  2073.     {
  2074.       BusLogic_IO_Address_T IO_Address =
  2075. simple_strtoul(OptionsString, &OptionsString, 0);
  2076.       BusLogic_ProbeOptions.LimitedProbeISA = true;
  2077.       switch (IO_Address)
  2078. {
  2079. case 0x330:
  2080.   BusLogic_ProbeOptions.Probe330 = true;
  2081.   break;
  2082. case 0x334:
  2083.   BusLogic_ProbeOptions.Probe334 = true;
  2084.   break;
  2085. case 0x230:
  2086.   BusLogic_ProbeOptions.Probe230 = true;
  2087.   break;
  2088. case 0x234:
  2089.   BusLogic_ProbeOptions.Probe234 = true;
  2090.   break;
  2091. case 0x130:
  2092.   BusLogic_ProbeOptions.Probe130 = true;
  2093.   break;
  2094. case 0x134:
  2095.   BusLogic_ProbeOptions.Probe134 = true;
  2096.   break;
  2097. default:
  2098.   BusLogic_Error("BusLogic: Invalid Driver Options "
  2099.  "(illegal I/O Address 0x%X)n",
  2100.  NULL, IO_Address);
  2101.   return 0;
  2102. }
  2103.     }
  2104.   else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
  2105.     BusLogic_ProbeOptions.NoProbeISA = true;
  2106.   else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
  2107.     BusLogic_ProbeOptions.NoProbePCI = true;
  2108.   else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
  2109.     BusLogic_ProbeOptions.NoProbe = true;
  2110.   else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
  2111.     BusLogic_ProbeOptions.NoSortPCI = true;
  2112.   else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
  2113.     BusLogic_ProbeOptions.MultiMasterFirst = true;
  2114.   else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
  2115.     BusLogic_ProbeOptions.FlashPointFirst = true;
  2116.   /* Tagged Queuing Options. */
  2117.   else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") ||
  2118.    BusLogic_ParseKeyword(&OptionsString, "QD:["))
  2119.     {
  2120.       for (TargetID = 0;
  2121.    TargetID < BusLogic_MaxTargetDevices;
  2122.    TargetID++)
  2123. {
  2124.   unsigned short QueueDepth =
  2125.     simple_strtoul(OptionsString, &OptionsString, 0);
  2126.   if (QueueDepth > BusLogic_MaxTaggedQueueDepth)
  2127.     {
  2128.       BusLogic_Error("BusLogic: Invalid Driver Options "
  2129.      "(illegal Queue Depth %d)n",
  2130.      NULL, QueueDepth);
  2131.       return 0;
  2132.     }
  2133.   DriverOptions->QueueDepth[TargetID] = QueueDepth;
  2134.   if (*OptionsString == ',')
  2135.     OptionsString++;
  2136.   else if (*OptionsString == ']')
  2137.     break;
  2138.   else
  2139.     {
  2140.       BusLogic_Error("BusLogic: Invalid Driver Options "
  2141.      "(',' or ']' expected at '%s')n",
  2142.      NULL, OptionsString);
  2143.       return 0;
  2144.     }
  2145. }
  2146.       if (*OptionsString != ']')
  2147. {
  2148.   BusLogic_Error("BusLogic: Invalid Driver Options "
  2149.  "(']' expected at '%s')n",
  2150.  NULL, OptionsString);
  2151.   return 0;
  2152. }
  2153.       else OptionsString++;
  2154.     }
  2155.   else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") ||
  2156.    BusLogic_ParseKeyword(&OptionsString, "QD:"))
  2157.     {
  2158.       unsigned short QueueDepth =
  2159. simple_strtoul(OptionsString, &OptionsString, 0);
  2160.       if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth)
  2161. {
  2162.   BusLogic_Error("BusLogic: Invalid Driver Options "
  2163.  "(illegal Queue Depth %d)n",
  2164.  NULL, QueueDepth);
  2165.   return 0;
  2166. }
  2167.       DriverOptions->CommonQueueDepth = QueueDepth;
  2168.       for (TargetID = 0;
  2169.    TargetID < BusLogic_MaxTargetDevices;
  2170.    TargetID++)
  2171. DriverOptions->QueueDepth[TargetID] = QueueDepth;
  2172.     }
  2173.   else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") ||
  2174.    BusLogic_ParseKeyword(&OptionsString, "TQ:"))
  2175.     {
  2176.       if (BusLogic_ParseKeyword(&OptionsString, "Default"))
  2177. {
  2178.   DriverOptions->TaggedQueuingPermitted = 0x0000;
  2179.   DriverOptions->TaggedQueuingPermittedMask = 0x0000;
  2180. }
  2181.       else if (BusLogic_ParseKeyword(&OptionsString, "Enable"))
  2182. {
  2183.   DriverOptions->TaggedQueuingPermitted = 0xFFFF;
  2184.   DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
  2185. }
  2186.       else if (BusLogic_ParseKeyword(&OptionsString, "Disable"))
  2187. {
  2188.   DriverOptions->TaggedQueuingPermitted = 0x0000;
  2189.   DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
  2190. }
  2191.       else
  2192. {
  2193.   unsigned short TargetBit;
  2194.   for (TargetID = 0, TargetBit = 1;
  2195.        TargetID < BusLogic_MaxTargetDevices;
  2196.        TargetID++, TargetBit <<= 1)
  2197.     switch (*OptionsString++)
  2198.       {
  2199.       case 'Y':
  2200. DriverOptions->TaggedQueuingPermitted |= TargetBit;
  2201. DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
  2202. break;
  2203.       case 'N':
  2204. DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
  2205. DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
  2206. break;
  2207.       case 'X':
  2208. break;
  2209.       default:
  2210. OptionsString--;
  2211. TargetID = BusLogic_MaxTargetDevices;
  2212. break;
  2213.       }
  2214. }
  2215.     }
  2216.   /* Error Recovery Option. */
  2217.   else if (BusLogic_ParseKeyword(&OptionsString, "ErrorRecovery:") ||
  2218.    BusLogic_ParseKeyword(&OptionsString, "ER:"))
  2219.     {
  2220.       if (BusLogic_ParseKeyword(&OptionsString, "Default"))
  2221. for (TargetID = 0;
  2222.      TargetID < BusLogic_MaxTargetDevices;
  2223.      TargetID++)
  2224.   DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2225.     BusLogic_ErrorRecovery_Default;
  2226.       else if (BusLogic_ParseKeyword(&OptionsString, "HardReset"))
  2227. for (TargetID = 0;
  2228.      TargetID < BusLogic_MaxTargetDevices;
  2229.      TargetID++)
  2230.   DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2231.     BusLogic_ErrorRecovery_HardReset;
  2232.       else if (BusLogic_ParseKeyword(&OptionsString, "BusDeviceReset"))
  2233. for (TargetID = 0;
  2234.      TargetID < BusLogic_MaxTargetDevices;
  2235.      TargetID++)
  2236.   DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2237.     BusLogic_ErrorRecovery_BusDeviceReset;
  2238.       else if (BusLogic_ParseKeyword(&OptionsString, "None"))
  2239. for (TargetID = 0;
  2240.      TargetID < BusLogic_MaxTargetDevices;
  2241.      TargetID++)
  2242.   DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2243.     BusLogic_ErrorRecovery_None;
  2244.       else
  2245. for (TargetID = 0;
  2246.      TargetID < BusLogic_MaxTargetDevices;
  2247.      TargetID++)
  2248.   switch (*OptionsString++)
  2249.     {
  2250.     case 'D':
  2251.       DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2252. BusLogic_ErrorRecovery_Default;
  2253.       break;
  2254.     case 'H':
  2255.       DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2256. BusLogic_ErrorRecovery_HardReset;
  2257.       break;
  2258.     case 'B':
  2259.       DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2260. BusLogic_ErrorRecovery_BusDeviceReset;
  2261.       break;
  2262.     case 'N':
  2263.       DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2264. BusLogic_ErrorRecovery_None;
  2265.       break;
  2266.     default:
  2267.       OptionsString--;
  2268.       TargetID = BusLogic_MaxTargetDevices;
  2269.       break;
  2270.     }
  2271.     }
  2272.   /* Miscellaneous Options. */
  2273.   else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") ||
  2274.    BusLogic_ParseKeyword(&OptionsString, "BST:"))
  2275.     {
  2276.       unsigned short BusSettleTime =
  2277. simple_strtoul(OptionsString, &OptionsString, 0);
  2278.       if (BusSettleTime > 5 * 60)
  2279. {
  2280.   BusLogic_Error("BusLogic: Invalid Driver Options "
  2281.  "(illegal Bus Settle Time %d)n",
  2282.  NULL, BusSettleTime);
  2283.   return 0;
  2284. }
  2285.       DriverOptions->BusSettleTime = BusSettleTime;
  2286.     }
  2287.   else if (BusLogic_ParseKeyword(&OptionsString,
  2288.  "InhibitTargetInquiry"))
  2289.     DriverOptions->LocalOptions.InhibitTargetInquiry = true;
  2290.   /* Debugging Options. */
  2291.   else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
  2292.       BusLogic_GlobalOptions.TraceProbe = true;
  2293.   else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
  2294.       BusLogic_GlobalOptions.TraceHardwareReset = true;
  2295.   else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
  2296.       BusLogic_GlobalOptions.TraceConfiguration = true;
  2297.   else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
  2298.       BusLogic_GlobalOptions.TraceErrors = true;
  2299.   else if (BusLogic_ParseKeyword(&OptionsString, "Debug"))
  2300.     {
  2301.       BusLogic_GlobalOptions.TraceProbe = true;
  2302.       BusLogic_GlobalOptions.TraceHardwareReset = true;
  2303.       BusLogic_GlobalOptions.TraceConfiguration = true;
  2304.       BusLogic_GlobalOptions.TraceErrors = true;
  2305.     }
  2306.   if (*OptionsString == ',')
  2307.     OptionsString++;
  2308.   else if (*OptionsString != ';' && *OptionsString != '')
  2309.     {
  2310.       BusLogic_Error("BusLogic: Unexpected Driver Option '%s' "
  2311.      "ignoredn", NULL, OptionsString);
  2312.       *OptionsString = '';
  2313.     }
  2314. }
  2315.       if (!(BusLogic_DriverOptionsCount == 0 ||
  2316.     BusLogic_ProbeInfoCount == 0 ||
  2317.     BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount))
  2318. {
  2319.   BusLogic_Error("BusLogic: Invalid Driver Options "
  2320.  "(all or no I/O Addresses must be specified)n", NULL);
  2321.   return 0;
  2322. }
  2323.       /*
  2324. Tagged Queuing is disabled when the Queue Depth is 1 since queuing
  2325. multiple commands is not possible.
  2326.       */
  2327.       for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
  2328. if (DriverOptions->QueueDepth[TargetID] == 1)
  2329.   {
  2330.     unsigned short TargetBit = 1 << TargetID;
  2331.     DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
  2332.     DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
  2333.   }
  2334.       if (*OptionsString == ';') OptionsString++;
  2335.       if (*OptionsString == '') return 0;
  2336.     }
  2337.     return 1;
  2338. }
  2339. /*
  2340.   BusLogic_Setup handles processing of Kernel Command Line Arguments.
  2341. */
  2342. static int __init 
  2343. BusLogic_Setup(char *str)
  2344. {
  2345. int ints[3];
  2346. (void)get_options(str, ARRAY_SIZE(ints), ints);
  2347. if (ints[0] != 0) {
  2348. BusLogic_Error("BusLogic: Obsolete Command Line Entry "
  2349. "Format Ignoredn", NULL);
  2350. return 0;
  2351. }
  2352. if (str == NULL || *str == '')
  2353. return 0;
  2354. return BusLogic_ParseDriverOptions(str);
  2355. }
  2356. __setup("BusLogic=", BusLogic_Setup);
  2357. /*
  2358.   Get it all started
  2359. */
  2360. MODULE_LICENSE("GPL");
  2361. static SCSI_Host_Template_T driver_template = BUSLOGIC;
  2362. #include "scsi_module.c"