buslogic958.c

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

C
1,558
字号
//                      single byte Execute Mailbox Command operation code, which does not require
//                      waiting for the Host Adapter Ready bit to be set in the Status Register.
// Arguments:
//              1. HostAdapter - Host Adapter structure
//              2. OperationCode - Operation code for the command
//              3. ParameterData - Buffer containing parameters that needs to be passed as part 
//                 of the command
//              4. ParameterLength - Number of parameters
//              5. ReplyData - Buffer where reply data is copied
//              6. ReplyLength - The length of the reply data
// Return Value:
//              On success, this function returns the number of reply bytes read from
//              the Host Adapter (including any discarded data); on failure, it returns
//              -1 if the command was invalid, or -2 if a timeout occurred.
//_________________________________________________________________________________________________
{
  UCHAR *ParameterPointer = (UCHAR *) ParameterData;
  UCHAR *ReplyPointer = (UCHAR *) ReplyData;
  BusLogic_StatusRegister_T StatusRegister;
  BusLogic_InterruptRegister_T InterruptRegister;
  int ReplyBytes = 0, Result;
  long TimeoutCounter;

  //  Clear out the Reply Data if provided.
  if (ReplyLength > 0)
    memset(ReplyData, 0, ReplyLength);
  
  //  If the IRQ Channel has not yet been acquired, then interrupts must be
  //  disabled while issuing host adapter commands since a Command Complete
  //  interrupt could occur if the IRQ Channel was previously enabled by another
  //  BusLogic Host Adapter or another driver sharing the same IRQ Channel.
  
  //  Wait for the Host Adapter Ready bit to be set and the Command/Parameter
  //  Register Busy bit to be reset in the Status Register.  
  TimeoutCounter = 10000;
  while (--TimeoutCounter >= 0)
  {
      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
      if ( StatusRegister.Bits.HostAdapterReady &&
          !StatusRegister.Bits.CommandParameterRegisterBusy)
      {
            break;
      }
      ScsiPortStallExecution(100);
  }
  if (TimeoutCounter < 0)
  {
      //BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
      Result = -2;
      goto Done;
  }
  
  //  Write the OperationCode to the Command/Parameter Register.
  HostAdapter->HostAdapterCommandCompleted = FALSE;
  BusLogic_WriteCommandParameterRegister(HostAdapter, (UCHAR)OperationCode);
  
  //Write any additional Parameter Bytes.
  TimeoutCounter = 10000;
  while (ParameterLength > 0 && --TimeoutCounter >= 0)
  {
    //
    // Wait 100 microseconds to give the Host Adapter enough time to determine
    // whether the last value written to the Command/Parameter Register was
    // valid or not.  If the Command Complete bit is set in the Interrupt
    // Register, then the Command Invalid bit in the Status Register will be
    // reset if the Operation Code or Parameter was valid and the command
    // has completed, or set if the Operation Code or Parameter was invalid.
    // If the Data In Register Ready bit is set in the Status Register, then
    // the Operation Code was valid, and data is waiting to be read back
    // from the Host Adapter.  Otherwise, wait for the Command/Parameter
    // Register Busy bit in the Status Register to be reset.
      
      ScsiPortStallExecution(100);
      InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
      if (InterruptRegister.Bits.CommandComplete) 
          break;
      if (HostAdapter->HostAdapterCommandCompleted) 
          break;
      if (StatusRegister.Bits.DataInRegisterReady) 
          break;
      if (StatusRegister.Bits.CommandParameterRegisterBusy)
          continue;
      BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
      ParameterLength--;
  }
  if (TimeoutCounter < 0)
  {
      //BusLogic_CommandFailureReason =  "Timeout waiting for Parameter Acceptance";
      Result = -2;
      goto Done;
  }
  
  // The Modify I/O Address command does not cause a Command Complete Interrupt.
  if (OperationCode == BusLogic_ModifyIOAddress)
  {
    StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
    if (StatusRegister.Bits.CommandInvalid)
    {
      //BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
      Result = -1;
      goto Done;
    }
    Result = 0;
    goto Done;
  }
  
  //  Select an appropriate timeout value for awaiting command completion.
  switch (OperationCode)
  {
    case BusLogic_InquireInstalledDevicesID0to7:
    case BusLogic_InquireInstalledDevicesID8to15:
    case BusLogic_InquireTargetDevices:
      // Approximately 60 seconds. 
      TimeoutCounter = 60*10000;
      break;
    default:
      // Approximately 1 second. 
      TimeoutCounter = 10000;
      break;
  }

  //
  //  Receive any Reply Bytes, waiting for either the Command Complete bit to
  //  be set in the Interrupt Register, or for the Interrupt Handler to set the
  //  Host Adapter Command Completed bit in the Host Adapter structure.
  while (--TimeoutCounter >= 0)
  {
    InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
    StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
    if (InterruptRegister.Bits.CommandComplete) 
        break;
    if (HostAdapter->HostAdapterCommandCompleted) 
        break;
    if (StatusRegister.Bits.DataInRegisterReady)
    {
      if (++ReplyBytes <= ReplyLength)
      {
        *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
      }
      else
      {
          BusLogic_ReadDataInRegister(HostAdapter);
      }
    }
    if (OperationCode == BusLogic_FetchHostAdapterLocalRAM &&
        StatusRegister.Bits.HostAdapterReady) 
    {
      break;
    }
    ScsiPortStallExecution(100);
  }
  if (TimeoutCounter < 0)
  {
      //BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
      Result = -2;
      goto Done;
  }
  
  //  Clear any pending Command Complete Interrupt.
  BusLogic_InterruptReset(HostAdapter);
  
  //  Process Command Invalid conditions.
  if (StatusRegister.Bits.CommandInvalid)
  {
    //
    // Some early BusLogic Host Adapters may not recover properly from
    // a Command Invalid condition, so if this appears to be the case,
    // a Soft Reset is issued to the Host Adapter.  Potentially invalid
    // commands are never attempted after Mailbox Initialization is
    // performed, so there should be no Host Adapter state lost by a
    // Soft Reset in response to a Command Invalid condition.
      
    ScsiPortStallExecution(1000);
    StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
    if (StatusRegister.Bits.CommandInvalid             ||
      StatusRegister.Bits.Reserved                     ||
      StatusRegister.Bits.DataInRegisterReady          ||
      StatusRegister.Bits.CommandParameterRegisterBusy ||
      !StatusRegister.Bits.HostAdapterReady            ||
      !StatusRegister.Bits.InitializationRequired      ||
      StatusRegister.Bits.DiagnosticActive             ||
      StatusRegister.Bits.DiagnosticFailure)
    {
        BusLogic_SoftReset(HostAdapter);
        ScsiPortStallExecution(1000);
    }
    //BusLogic_CommandFailureReason = "Command Invalid";
    Result = -1;
    goto Done;
  }
  
  // Handle Excess Parameters Supplied conditions.
  if (ParameterLength > 0)
  {
      //BusLogic_CommandFailureReason = "Excess Parameters Supplied";
      Result = -1;
      goto Done;
  }
  
  //  Indicate the command completed successfully.
  Result = ReplyBytes;
  
  //  Restore the interrupt status if necessary and return.
Done:
  return Result;
}// end BusLogic_Command


BOOLEAN 
BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T  *HostAdapter)
//___________________________________________________________________________________________
// Routine Description:
//                  BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
//                  from Host Adapter and initializes the Host Adapter structure.
// Arguments:
//              1. Host adapter structure
// Return Value:
//              TRUE : Configuration read properly
//              FALSE : Encounter failure
//___________________________________________________________________________________________
{
  BusLogic_BoardID_T BoardID;
  BusLogic_Configuration_T Configuration;
  BusLogic_SetupInformation_T SetupInformation;
  BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
  BusLogic_HostAdapterModelNumber_T HostAdapterModelNumber;
  BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
  BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
  BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
  BusLogic_FetchHostAdapterLocalRAMRequest_T FetchHostAdapterLocalRAMRequest;
  BusLogic_AutoSCSIData_T AutoSCSIData;
  BusLogic_GeometryRegister_T GeometryRegister;
  BusLogic_RequestedReplyLength_T RequestedReplyLength;
  UCHAR *TargetPointer, Character;
  ULONG /*TargetID,*/ i;
  
 
  //  Issue the Inquire Board ID command.  
  if (BusLogic_Command(HostAdapter, 
                       BusLogic_InquireBoardID,
                       NULL,
                       0,
                       &BoardID, sizeof(BoardID))  
      != sizeof(BoardID))
  {
        DebugPrint((ERROR, "\n BusLogic - Failure: INQUIRE BOARD ID\n"));
        return FALSE;
  }

  //  Issue the Inquire Configuration command.
  if (BusLogic_Command(HostAdapter, 
                       BusLogic_InquireConfiguration, 
                       NULL, 
                       0,
                       &Configuration, sizeof(Configuration))
      != sizeof(Configuration))
  {
      DebugPrint((ERROR, "\n BusLogic - Failure: INQUIRE CONFIGURATION\n"));
      return 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;
  }
  
  //  Issue the Inquire Extended Setup Information command.
  RequestedReplyLength = sizeof(ExtendedSetupInformation);
  if (BusLogic_Command(HostAdapter, 
                       BusLogic_InquireExtendedSetupInformation,
                       &RequestedReplyLength, 
                       sizeof(RequestedReplyLength),
                       &ExtendedSetupInformation,
                       sizeof(ExtendedSetupInformation))
      != sizeof(ExtendedSetupInformation))
  {
      DebugPrint((ERROR, "\n BusLogic - Failure: INQUIRE EXTENDED SETUP INFORMATION\n"));
      return FALSE;
  }
  
  //  Issue the Inquire Firmware Version 3rd Digit command.
  FirmwareVersion3rdDigit = '\0';
  if (BoardID.FirmwareVersion1stDigit > '0')
  {
    if (BusLogic_Command(HostAdapter,
                         BusLogic_InquireFirmwareVersion3rdDigit,
                         NULL,
                         0,
                         &FirmwareVersion3rdDigit,
                         sizeof(FirmwareVersion3rdDigit))
        != sizeof(FirmwareVersion3rdDigit))
    {
        DebugPrint((ERROR, "\n BusLogic - Failure: INQUIRE FIRMWARE 3RD DIGIT\n"));
        return FALSE;
    }
  }
  
  //  Issue the Inquire Host Adapter Model Number command.
  RequestedReplyLength = sizeof(HostAdapterModelNumber);
  if (BusLogic_Command(HostAdapter, 
                       BusLogic_InquireHostAdapterModelNumber,
                       &RequestedReplyLength, 

⌨️ 快捷键说明

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