buslogic958.c

来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 1,558 行 · 第 1/5 页

C
1,558
字号
  if (BusLogic_Command(HostAdapter,
                       BusLogic_InitializeExtendedMailbox,
                       &ExtendedMailboxRequest,
                       sizeof(ExtendedMailboxRequest), 
                       NULL, 0) 
       < 0)
  {
      DebugPrint((ERROR, "\n BusLogic - Failure: MAILBOX INITIALIZATION\n"));
      return FALSE;
  }
    
  //  Enable Strict Round Robin Mode if supported by the Host Adapter.  In
  //  Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
  //  Mailbox for each new command, rather than scanning through all the
  //  Outgoing Mailboxes to find any that have new commands in them.  Strict
  //  Round Robin Mode is significantly more efficient.
  if (HostAdapter->StrictRoundRobinModeSupport)
  {
        RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
        if (BusLogic_Command(HostAdapter, 
                             BusLogic_EnableStrictRoundRobinMode,
                             &RoundRobinModeRequest,
                             sizeof(RoundRobinModeRequest), 
                             NULL,
                             0)
            < 0)
        {
            DebugPrint((ERROR, "\n BusLogic - Failure: ENABLE STRICT ROUND ROBIN MODE\n"));
            return FALSE;
        }
   }
  
  //  For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB
  //  Format command to allow 32 Logical Units per Target Device.

  if (HostAdapter->ExtendedLUNSupport)
  {
      SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
      if (BusLogic_Command(HostAdapter,
                           BusLogic_SetCCBFormat,
                           &SetCCBFormatRequest,
                           sizeof(SetCCBFormatRequest),
                           NULL,
                           0)
          < 0)
      {
          DebugPrint((ERROR, "\n BusLogic - Failure: SET CCB FORMAT\n"));
          return FALSE;
      }
    }
 
  //  Announce Successful Initialization.  
  if (!HostAdapter->HostAdapterInitialized)
  {
      DebugPrint((INFO, "\n BusLogic - %s Initialized Successfully\n", 
                  HostAdapter, HostAdapter->FullModelName));      
  }
  else
  {
      DebugPrint((WARNING, "\n BusLogic - %s not initialized Successfully\n", 
                  HostAdapter, HostAdapter->FullModelName));
  }
  HostAdapter->HostAdapterInitialized = TRUE;  
  //  Indicate the Host Adapter Initialization completed successfully.
  return TRUE;
}// end BusLogic_InitializeHostAdapter


BOOLEAN 
BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T *HostAdapter)
//_________________________________________________________________________________________
// Routine Description:
//                  BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
//                  through Host Adapter.
// Arguments:
//              1. Host Adpater structure
//              2. 
// Return Value:
//              TRUE : Inquiry successful
//              FALSE : Inquiry failed
//_________________________________________________________________________
{
  BusLogic_InstalledDevices_T InstalledDevices;
//  BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
  BusLogic_SetupInformation_T SetupInformation;
  BusLogic_SynchronousPeriod_T SynchronousPeriod;
  BusLogic_RequestedReplyLength_T RequestedReplyLength;
  int TargetID;
  
  //  Wait a few seconds between the Host Adapter Hard Reset which initiates
  //  a SCSI Bus Reset and issuing any SCSI Commands.  Some SCSI devices get
  //  confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
  ScsiPortStallExecution(HostAdapter->BusSettleTime);

  //
  //  Issue the Inquire Target Devices command for host adapters with firmware
  //  version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
  //  for older host adapters.  This is necessary to force Synchronous Transfer
  //  Negotiation so that the Inquire Setup Information and Inquire Synchronous
  //  Period commands will return valid data.  The Inquire Target Devices command
  //  is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
  //  Logical Unit 0 of each Target Device.
  if (strcmp((char*)HostAdapter->FirmwareVersion, "4.25") >= 0)
  {
      if (BusLogic_Command(HostAdapter,
                           BusLogic_InquireTargetDevices, 
                           NULL,
                           0,
                           &InstalledDevices,
                           sizeof(InstalledDevices))
            != sizeof(InstalledDevices))
      {
          DebugPrint((ERROR, "\n BusLogic - Failure: INQUIRE TARGET DEVICES\n"));
          return FALSE;
      }
      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
      {
            HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevices & (1 << TargetID) ? TRUE : FALSE);
      }
  }
  
  //  Issue the Inquire Setup Information command.
  RequestedReplyLength = sizeof(SetupInformation);
  if (BusLogic_Command(HostAdapter, 
                       BusLogic_InquireSetupInformation,
                       &RequestedReplyLength,
                       sizeof(RequestedReplyLength),
               &SetupInformation, sizeof(SetupInformation))
      != sizeof(SetupInformation))
  {
      DebugPrint((ERROR, "\n BusLogic - Failure: INQUIRE SETUP INFORMATION\n"));
      return FALSE;
  }

  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  {
      HostAdapter->SynchronousOffset[TargetID] = (TargetID < 8
                                                  ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset
                                                  : SetupInformation.SynchronousValuesID8to15[TargetID-8].Offset);
  }
  if (strcmp((char*)HostAdapter->FirmwareVersion, "5.06L") >= 0)
  {
    for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
    {
      HostAdapter->TargetFlags[TargetID].WideTransfersActive = (TargetID < 8
                                                                ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
                                                                    ? TRUE : FALSE)
                                                                : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID-8))
                                                                    ? TRUE : FALSE));
    }
  }

  
  //  Issue the Inquire Synchronous Period command.
  if (HostAdapter->FirmwareVersion[0] >= '3')
  {
      RequestedReplyLength = sizeof(SynchronousPeriod);
      if (BusLogic_Command(HostAdapter,
                           BusLogic_InquireSynchronousPeriod,
                           &RequestedReplyLength,
                           sizeof(RequestedReplyLength),
                           &SynchronousPeriod, 
                           sizeof(SynchronousPeriod))
        != sizeof(SynchronousPeriod))
      {
          DebugPrint((ERROR, "\n BusLogic - Failure: INQUIRE SYNCHRONOUS PERIOD\n"));
          return FALSE;
      }
      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
      {
        HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
      }
  }
  
  //  Indicate the Target Device Inquiry completed successfully.
  return TRUE;
}// end BusLogic_TargetDeviceInquiry

VOID BusLogic_InitializeCCB( PBuslogic_CCB_T CCB)
{
  CCB->Opcode = BusLogic_InitiatorCCB;
  CCB->DataDirection = 0;       
  CCB->TagEnable = 0;           
  CCB->QueueTag = 0 ;           
  CCB->CDB_Length = 0;          
  CCB->SenseDataLength = 0;     
  CCB->DataLength = 0;
  CCB->DataPointer = 0;
  CCB->HostAdapterStatus = 0;
  CCB->TargetDeviceStatus = 0;
  CCB->TargetID = 0;        
  CCB->LogicalUnit = 0;     
  CCB->LegacyTagEnable = 0; 
  CCB->LegacyQueueTag = 0;  
    
  CCB->SenseDataPointer = 0;

  // BusLogic Driver Defined Portion
  CCB->Status = 0;
  CCB->SerialNumber = 0;
  CCB->Next = NULL;
  CCB->HostAdapter = NULL;
  
  CCB->CompletionCode = 0;
  // Pointer to the CCB
  CCB->SrbAddress = NULL;
  CCB->AbortSrb = NULL;
}

BOOLEAN
STDCALL
BT958HwStartIO(IN PVOID HwDeviceExtension,
               IN PSCSI_REQUEST_BLOCK Srb
              )
//__________________________________________________________________________________
// Routine Description:
//                    As soon as it receives the initial request for a 
//                    target peripheral, the OS-specific port driver calls 
//                    the HwScsiStartIo routine with an input SRB. After 
//                    this call, the HBA miniport driver owns the request 
//                     and is expected to complete it.
// Arguments:
//           1. DeviceExtension: Points to the miniport driver's per-HBA storage area. 
//           2. Srb: Points to the SCSI request block to be started. 
// Return Value:
//              TRUE : HwScsiStartIo returns TRUE to acknowledge receipt of the SRB.
//__________________________________________________________________________________
{
    PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
//    PNONCACHED_EXTENSION noncachedExtension =   deviceExtension->NoncachedExtension;
    BusLogic_HostAdapter_T *HostAdapter = &(deviceExtension->hcs);
//    BusLogic_OutgoingMailbox_T mailboxOut;
    PSCSI_REQUEST_BLOCK AbortSRB;

    PBuslogic_CCB_T ccb;
    BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[Srb->TargetId];
  
        
    DebugPrint((TRACE, "\n BusLogic - Inside Start IO routine\n"));
  
    // Make sure that this request isn't too long for the adapter.  If so
    // bounce it back as an invalid request
    if (BusLogic_CDB_MaxLength < Srb->CdbLength)
    {

        DebugPrint((WARNING, "\n BusLogic - Srb->CdbLength [%d] > MaxCdbLength [%d]."
                    " Invalid request\n", Srb->CdbLength, BusLogic_CDB_MaxLength));

        Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
        ScsiPortNotification(RequestComplete,deviceExtension,Srb);
        ScsiPortNotification(NextRequest,deviceExtension,NULL);
        return TRUE;
    }

    switch (Srb->Function) 
    { 
        /*
        Sirish, 10th June 2002 
        // Check if command is a WMI request.
        case SRB_FUNCTION_WMI:
            // Process the WMI request and return.
            return BT958WmiSrb(HwDeviceExtension, (PSCSI_WMI_REQUEST_BLOCK) Srb);
        */
        
        case SRB_FUNCTION_EXECUTE_SCSI:

            // get the ccb structure from the extension
            ccb = Srb->SrbExtension;
            BusLogic_InitializeCCB(ccb);

            // Save SRB back pointer in CCB.
            ccb->SrbAddress = Srb;

            // Build CCB. - Have some way of knowing that a srb has already been 
            // completed and you just need to return from here
            BusLogic_QueueCommand(HwDeviceExtension ,Srb,   ccb);   

            // Place the CCB in an Outgoing Mailbox.  The higher levels of the SCSI
            // Subsystem should not attempt to queue more commands than can be placed
            // in Outgoing Mailboxes, so there should always be one free.  In the
            // unlikely event that there are none available, wait 1 second and try
            // again.  If that fails, the Host Adapter is probably hung so signal an
            // error as a Host Adapter Hard Reset should be initiated soon.

            if (!BusLogic_WriteOutgoingMailbox(deviceExtension , BusLogic_MailboxStartCommand, ccb))
            {
                DebugPrint((ERROR, "\n BusLogic - Unable to write Outgoing Mailbox - " 
                            "Pausing for 1 second\n"));
                ScsiPortStallExecution(1000);
                if (!BusLogic_WriteOutgoingMailbox(deviceExtension , BusLogic_MailboxStartCommand, ccb))
                {
                      DebugPrint((ERROR, "\n BusLogic - Still unable to write Outgoing"
                                  "Mailbox - Host Adapter Dead?\n"));

                      Srb->SrbStatus = SRB_STATUS_ERROR;
                      ScsiPortNotification(RequestComplete,deviceExtension,Srb);
                      ScsiPortNotification(NextRequest,deviceExtension,NULL);

                }
            }
            else 
            {
                /*
                 * Reverted to pre 1.1.0.0 control flow
                 * The 1.1.0.0 control flow causes the .NET Server freeze during installs/restarts
                 * And the fix for that in 1.1.0.1 causes BSODs in XP
                 * Side note: Ben: the Buslogic emulation never exports more than 1 lun
                 */
                if (TargetFlags->TaggedQueuingActive
                    && HostAdapter->ActiveCommands

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?