buslogic958.c

来自「winNT技术操作系统,国外开放的原代码和LIUX一样」· C语言 代码 · 共 1,558 行 · 第 1/5 页

C
1,558
字号

} // end BT958FindAdapter() 


BOOLEAN 
Buslogic_InitBT958(PHW_DEVICE_EXTENSION deviceExtension, 
                   PPORT_CONFIGURATION_INFORMATION ConfigInfo)
//_________________________________________________________________________
// Routine Description:
//              This routine is called from the driver's FindAdapter routine
//              On invocation this routine probes the host adapter to check 
//              if its hardware registers are responding correctly, and 
//              initializes the device and makes it ready for IO
// Arguments:
//              1. deviceExtension
//              2. Port Configuration info 
// Return Value:
//              TRUE : Device initialized properly
//              FALSE : Device failed to initialize
//_________________________________________________________________________
{
    CHAR ch;

    BusLogic_HostAdapter_T *HostAdapter = &(deviceExtension->hcs);
        
    // Probe the Host Adapter.  
    // If unsuccessful, abort further initialization.
    if (!BusLogic_ProbeHostAdapter(HostAdapter)) 
        return   FALSE; 
    
    // Hard Reset the Host Adapter.  
    // If unsuccessful, abort further initialization.
    if (!BusLogic_HardwareResetHostAdapter(HostAdapter, TRUE)) 
        return FALSE;

    /*
     * PR 40284 -- Disable interrupts until driver initialization is complete.
     */ 
    ch = 0;
    if (BusLogic_Command(HostAdapter, BusLogic_DisableHostAdapterInterrupt,
			 &ch, sizeof(ch), NULL, 0) < 0) {
        DebugPrint((WARNING, "\n BusLogic - Could not disable interrupts!\n"));
    } else {
        DebugPrint((INFO, "\n BusLogic - Disabled interrupts.\n"));
    }

    // Check the Host Adapter.  
    // If unsuccessful, abort further initialization.
    if (!BusLogic_CheckHostAdapter(HostAdapter)) 
        return FALSE;    
    
    // Allocate a Noncached Extension to use for mail boxes.
    deviceExtension->NoncachedExtension =  ScsiPortGetUncachedExtension(deviceExtension,
                                                                      ConfigInfo,
                                                                      sizeof(NONCACHED_EXTENSION));

    if (deviceExtension->NoncachedExtension == NULL) 
    {     
        // Log error.
        ScsiPortLogError(deviceExtension,
                             NULL,
                             0,
                             0,
                             0,
                             SP_INTERNAL_ADAPTER_ERROR,
                             7 << 8);

        // abort further initialization
        return FALSE;
    }

    // Read the Host Adapter Configuration, Configure the Host Adapter,
    // Acquire the System Resources necessary to use the Host Adapter, then
    // Create the Initial CCBs, Initialize the Host Adapter, and finally
    // perform Target Device Inquiry.
    if (BusLogic_ReadHostAdapterConfiguration(HostAdapter)           &&
        //BusLogic_ReportHostAdapterConfiguration(HostAdapter)       &&
        BusLogic_InitializeHostAdapter(deviceExtension, ConfigInfo)  &&
        BusLogic_TargetDeviceInquiry(HostAdapter))
    {
        // Fill in the:
        // 1.Maximum number of scsi target devices that are supported by our adapter
        ConfigInfo->MaximumNumberOfTargets = HostAdapter->MaxTargetDevices;
        // 2. Maximum number of logical units per target the HBA can control. 
        ConfigInfo->MaximumNumberOfLogicalUnits  = HostAdapter->MaxLogicalUnits;
        ConfigInfo->InitiatorBusId[0] = HostAdapter->SCSI_ID;
        // Maximum number of breaks between address ranges that a data buffer can 
        // have if the HBA supports scatter/gather. In other words, the number of 
        // scatter/gather lists minus one. 
        ConfigInfo->NumberOfPhysicalBreaks = HostAdapter->DriverScatterGatherLimit;     
    }
    else
    {
        // An error occurred during Host Adapter Configuration Querying, Host
        // Adapter Configuration, Host Adapter Initialization, or Target Device Inquiry,
        // so return FALSE
          
        return FALSE;     
    }   
    // Initialization completed successfully
    return TRUE;
} // end Buslogic_InitBT958


BOOLEAN
BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
//____________________________________________________________________________________
// Routine Description: BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
//                      The routine reads the status, interrupt and geometry regiter and
//                      checks if their contents are valid
// Arguments:
//              1. Host Adapter structure 
//
// Return Value:
//              TRUE: Probe completed successfully
//              FALSE: Probe failed
//____________________________________________________________________________________
{
  BusLogic_StatusRegister_T StatusRegister;
  BusLogic_InterruptRegister_T InterruptRegister;
  BusLogic_GeometryRegister_T GeometryRegister;
  
  DebugPrint((TRACE,"\n BusLogic -  Inside ProbeHostaAdapter function \n"));
  //  Read the Status, Interrupt, and Geometry Registers to test if there are I/O
  //  ports that respond, and to check the values to determine if they are from a
  //  BusLogic Host Adapter.  A nonexistent I/O port will return 0xFF, in which
  //  case there is definitely no BusLogic Host Adapter at this base I/O Address.
  //  The test here is a subset of that used by the BusLogic Host Adapter BIOS.
  
  InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
  GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
  StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
  
  if (StatusRegister.All == 0 ||
      StatusRegister.Bits.DiagnosticActive ||
      StatusRegister.Bits.CommandParameterRegisterBusy ||
      StatusRegister.Bits.Reserved ||
      StatusRegister.Bits.CommandInvalid ||
      InterruptRegister.Bits.Reserved != 0)
    return FALSE;
  
  //  Check the undocumented Geometry Register to test if there is an I/O port
  //  that responded.  Adaptec Host Adapters do not implement the Geometry
  //  Register, so this test helps serve to avoid incorrectly recognizing an
  //  Adaptec 1542A or 1542B as a BusLogic.  Unfortunately, the Adaptec 1542C
  //  series does respond to the Geometry Register I/O port, but it will be
  //  rejected later when the Inquire Extended Setup Information command is
  //  issued in BusLogic_CheckHostAdapter.  The AMI FastDisk Host Adapter is a
  //  BusLogic clone that implements the same interface as earlier BusLogic
  //  Host Adapters, including the undocumented commands, and is therefore
  //  supported by this driver.  However, the AMI FastDisk always returns 0x00
  //  upon reading the Geometry Register, so the extended translation option
  //  should always be left disabled on the AMI FastDisk.
  
  if (GeometryRegister.All == 0xFF) return FALSE;
  return TRUE;
}// end BusLogic_ProbeHostAdapter

BOOLEAN 
BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T  *HostAdapter, 
                                  BOOLEAN HardReset)
//_________________________________________________________________________
// Routine Description: BusLogic_HardwareResetHostAdapter issues a Hardware 
//                      Reset to the Host Adapter and waits for Host Adapter 
//                      Diagnostics to complete.  If HardReset is TRUE, a
//                      Hard Reset is performed which also initiates a SCSI 
//                      Bus Reset.  Otherwise, a Soft Reset is performed which 
//                      only resets the Host Adapter without forcing a SCSI 
//                      Bus Reset.
// Arguments:
//              1. Host Adapter structure 
//              2. Boolean HardReset - True: Do hard reset
// Return Value:
//              TRUE : Reset completed successfully
//              FALSE : Reset failed
//_________________________________________________________________________
{
  BusLogic_StatusRegister_T StatusRegister;
  int TimeoutCounter;
  
  //  Issue a Hard Reset or Soft Reset Command to the Host Adapter.  The Host
  //  Adapter should respond by setting Diagnostic Active in the Status Register.
  if (HardReset)
    BusLogic_HardReset(HostAdapter);
  else 
    BusLogic_SoftReset(HostAdapter);
  
  // Wait until Diagnostic Active is set in the Status Register.
  TimeoutCounter = 100;
  while (--TimeoutCounter >= 0)
  {
      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
      if (StatusRegister.Bits.DiagnosticActive) 
          break;
  }
  
  // if inspite of waiting for time out period , if it didn't et set, then something is wrong-- so just return.
  if (TimeoutCounter < 0) 
      return FALSE;
  
  //
  //  Wait 100 microseconds to allow completion of any initial diagnostic
  //  activity which might leave the contents of the Status Register
  //  unpredictable.
  ScsiPortStallExecution(100);
  
  //  Wait until Diagnostic Active is reset in the Status Register.
  TimeoutCounter = 10*10000;
  while (--TimeoutCounter >= 0)
  {
      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
      if (!StatusRegister.Bits.DiagnosticActive) 
          break;
      ScsiPortStallExecution(100);
  }
  
  if (TimeoutCounter < 0) 
      return FALSE;
  
  //  Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
  //  or Data In Register Ready bits is set in the Status Register.  
  TimeoutCounter = 10000;
  while (--TimeoutCounter >= 0)
  {
      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
      if (StatusRegister.Bits.DiagnosticFailure ||
          StatusRegister.Bits.HostAdapterReady ||
          StatusRegister.Bits.DataInRegisterReady)
      {
        break;
      }
      ScsiPortStallExecution(100);
   }
  
  //device didn't respond to reset
  if (TimeoutCounter < 0)
      return FALSE;
  
  //  If Diagnostic Failure is set or Host Adapter Ready is reset, then an
  //  error occurred during the Host Adapter diagnostics.  If Data In Register
  //  Ready is set, then there is an Error Code available.
  if (StatusRegister.Bits.DiagnosticFailure || !StatusRegister.Bits.HostAdapterReady)
  {
      DebugPrint((ERROR, "\n BusLogic - Failure - HOST ADAPTER STATUS REGISTER = %02X\n", StatusRegister.All));
      
      if (StatusRegister.Bits.DataInRegisterReady)
      {
        DebugPrint((ERROR, "HOST ADAPTER ERROR CODE = %d\n", BusLogic_ReadDataInRegister(HostAdapter)));
      }
      return FALSE;
  } 
  
  //  Indicate the Host Adapter Hard Reset completed successfully.  
  return TRUE;
}// end BusLogic_HardwareResetHostAdapter


BOOLEAN 
BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
//_________________________________________________________________________
// Routine Description: BusLogic_CheckHostAdapter checks to be sure this 
//                      really is a BusLogic
// Arguments:
//              1. Host Adapter Structure
// Return Value:
//              TRUE : Buslogic adapter detected
//              FALSE : Card is not a Buslogic adapter
//_________________________________________________________________________
{
  BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
  BusLogic_RequestedReplyLength_T RequestedReplyLength;
  BOOLEAN Result = TRUE;

  DebugPrint((TRACE, "\n BusLogic -  Inside BusLogic_CheckHostAdapter function \n"));
 
  //
  //  Issue the Inquire Extended Setup Information command.  Only genuine
  //  BusLogic Host Adapters and TRUE clones support this command.  Adaptec 1542C
  //  series Host Adapters that respond to the Geometry Register I/O port will
  //  fail this command.
  RequestedReplyLength = sizeof(ExtendedSetupInformation);
  if (BusLogic_Command(HostAdapter,
                       BusLogic_InquireExtendedSetupInformation,
                       &RequestedReplyLength,
                       sizeof(RequestedReplyLength),
                       &ExtendedSetupInformation,
                       sizeof(ExtendedSetupInformation))
      != sizeof(ExtendedSetupInformation))
  {
    Result = FALSE;
  }
  return Result;
}// end BusLogic_CheckHostAdapter

int 
BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
                 BusLogic_OperationCode_T OperationCode,
                 void *ParameterData,
                 int ParameterLength,
                 void *ReplyData,
                 int ReplyLength)
//______________________________________________________________________________________________
// Routine Description:
//                      BusLogic_Command sends the command OperationCode to HostAdapter, optionally
//                      providing ParameterLength bytes of ParameterData and receiving at most
//                      ReplyLength bytes of ReplyData; any excess reply data is received but
//                      discarded.
//
//                      BusLogic_Command is called exclusively during host adapter detection and
//                      initialization, so performance and latency are not critical, and exclusive
//                      access to the Host Adapter hardware is assumed.  Once the host adapter and
//                      driver are initialized, the only Host Adapter command that is issued is the

⌨️ 快捷键说明

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