buslogic958.c

来自「一个类似windows」· C语言 代码 · 共 1,684 行 · 第 1/5 页

C
1,684
字号
    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((0,"\n BusLogic -  Inside ProbeHostaAdapter funtion \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 = 5*10000;
  while (--TimeoutCounter >= 0)
  {
      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
      if (StatusRegister.Bits.DiagnosticActive) 
		  break;
      ScsiPortStallExecution(100);
  }
  
  // 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((0,"Failure - HOST ADAPTER STATUS REGISTER = %02X\n",  StatusRegister.All));
      
      if (StatusRegister.Bits.DataInRegisterReady)
	  {
		DebugPrint((0,"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((0,"\n BusLogic -  Inside BusLogic_CheckHostAdapter funtion \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
//						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);

⌨️ 快捷键说明

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