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