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 + -
显示快捷键?