buslogic958.c
来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 1,558 行 · 第 1/5 页
C
1,558 行
if (BusLogic_Command(HostAdapter,
BusLogic_InitializeExtendedMailbox,
&ExtendedMailboxRequest,
sizeof(ExtendedMailboxRequest),
NULL, 0)
< 0)
{
DebugPrint((ERROR, "\n BusLogic - Failure: MAILBOX INITIALIZATION\n"));
return FALSE;
}
// Enable Strict Round Robin Mode if supported by the Host Adapter. In
// Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
// Mailbox for each new command, rather than scanning through all the
// Outgoing Mailboxes to find any that have new commands in them. Strict
// Round Robin Mode is significantly more efficient.
if (HostAdapter->StrictRoundRobinModeSupport)
{
RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
if (BusLogic_Command(HostAdapter,
BusLogic_EnableStrictRoundRobinMode,
&RoundRobinModeRequest,
sizeof(RoundRobinModeRequest),
NULL,
0)
< 0)
{
DebugPrint((ERROR, "\n BusLogic - Failure: ENABLE STRICT ROUND ROBIN MODE\n"));
return FALSE;
}
}
// For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB
// Format command to allow 32 Logical Units per Target Device.
if (HostAdapter->ExtendedLUNSupport)
{
SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
if (BusLogic_Command(HostAdapter,
BusLogic_SetCCBFormat,
&SetCCBFormatRequest,
sizeof(SetCCBFormatRequest),
NULL,
0)
< 0)
{
DebugPrint((ERROR, "\n BusLogic - Failure: SET CCB FORMAT\n"));
return FALSE;
}
}
// Announce Successful Initialization.
if (!HostAdapter->HostAdapterInitialized)
{
DebugPrint((INFO, "\n BusLogic - %s Initialized Successfully\n",
HostAdapter, HostAdapter->FullModelName));
}
else
{
DebugPrint((WARNING, "\n BusLogic - %s not initialized Successfully\n",
HostAdapter, HostAdapter->FullModelName));
}
HostAdapter->HostAdapterInitialized = TRUE;
// Indicate the Host Adapter Initialization completed successfully.
return TRUE;
}// end BusLogic_InitializeHostAdapter
BOOLEAN
BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T *HostAdapter)
//_________________________________________________________________________________________
// Routine Description:
// BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
// through Host Adapter.
// Arguments:
// 1. Host Adpater structure
// 2.
// Return Value:
// TRUE : Inquiry successful
// FALSE : Inquiry failed
//_________________________________________________________________________
{
BusLogic_InstalledDevices_T InstalledDevices;
// BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
BusLogic_SetupInformation_T SetupInformation;
BusLogic_SynchronousPeriod_T SynchronousPeriod;
BusLogic_RequestedReplyLength_T RequestedReplyLength;
int TargetID;
// Wait a few seconds between the Host Adapter Hard Reset which initiates
// a SCSI Bus Reset and issuing any SCSI Commands. Some SCSI devices get
// confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
ScsiPortStallExecution(HostAdapter->BusSettleTime);
//
// Issue the Inquire Target Devices command for host adapters with firmware
// version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
// for older host adapters. This is necessary to force Synchronous Transfer
// Negotiation so that the Inquire Setup Information and Inquire Synchronous
// Period commands will return valid data. The Inquire Target Devices command
// is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
// Logical Unit 0 of each Target Device.
if (strcmp((char*)HostAdapter->FirmwareVersion, "4.25") >= 0)
{
if (BusLogic_Command(HostAdapter,
BusLogic_InquireTargetDevices,
NULL,
0,
&InstalledDevices,
sizeof(InstalledDevices))
!= sizeof(InstalledDevices))
{
DebugPrint((ERROR, "\n BusLogic - Failure: INQUIRE TARGET DEVICES\n"));
return FALSE;
}
for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
{
HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevices & (1 << TargetID) ? TRUE : 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;
}
for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
{
HostAdapter->SynchronousOffset[TargetID] = (TargetID < 8
? SetupInformation.SynchronousValuesID0to7[TargetID].Offset
: SetupInformation.SynchronousValuesID8to15[TargetID-8].Offset);
}
if (strcmp((char*)HostAdapter->FirmwareVersion, "5.06L") >= 0)
{
for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
{
HostAdapter->TargetFlags[TargetID].WideTransfersActive = (TargetID < 8
? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
? TRUE : FALSE)
: (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID-8))
? TRUE : FALSE));
}
}
// Issue the Inquire Synchronous Period command.
if (HostAdapter->FirmwareVersion[0] >= '3')
{
RequestedReplyLength = sizeof(SynchronousPeriod);
if (BusLogic_Command(HostAdapter,
BusLogic_InquireSynchronousPeriod,
&RequestedReplyLength,
sizeof(RequestedReplyLength),
&SynchronousPeriod,
sizeof(SynchronousPeriod))
!= sizeof(SynchronousPeriod))
{
DebugPrint((ERROR, "\n BusLogic - Failure: INQUIRE SYNCHRONOUS PERIOD\n"));
return FALSE;
}
for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
{
HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
}
}
// Indicate the Target Device Inquiry completed successfully.
return TRUE;
}// end BusLogic_TargetDeviceInquiry
VOID BusLogic_InitializeCCB( PBuslogic_CCB_T CCB)
{
CCB->Opcode = BusLogic_InitiatorCCB;
CCB->DataDirection = 0;
CCB->TagEnable = 0;
CCB->QueueTag = 0 ;
CCB->CDB_Length = 0;
CCB->SenseDataLength = 0;
CCB->DataLength = 0;
CCB->DataPointer = 0;
CCB->HostAdapterStatus = 0;
CCB->TargetDeviceStatus = 0;
CCB->TargetID = 0;
CCB->LogicalUnit = 0;
CCB->LegacyTagEnable = 0;
CCB->LegacyQueueTag = 0;
CCB->SenseDataPointer = 0;
// BusLogic Driver Defined Portion
CCB->Status = 0;
CCB->SerialNumber = 0;
CCB->Next = NULL;
CCB->HostAdapter = NULL;
CCB->CompletionCode = 0;
// Pointer to the CCB
CCB->SrbAddress = NULL;
CCB->AbortSrb = NULL;
}
BOOLEAN
STDCALL
BT958HwStartIO(IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
)
//__________________________________________________________________________________
// Routine Description:
// As soon as it receives the initial request for a
// target peripheral, the OS-specific port driver calls
// the HwScsiStartIo routine with an input SRB. After
// this call, the HBA miniport driver owns the request
// and is expected to complete it.
// Arguments:
// 1. DeviceExtension: Points to the miniport driver's per-HBA storage area.
// 2. Srb: Points to the SCSI request block to be started.
// Return Value:
// TRUE : HwScsiStartIo returns TRUE to acknowledge receipt of the SRB.
//__________________________________________________________________________________
{
PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
// PNONCACHED_EXTENSION noncachedExtension = deviceExtension->NoncachedExtension;
BusLogic_HostAdapter_T *HostAdapter = &(deviceExtension->hcs);
// BusLogic_OutgoingMailbox_T mailboxOut;
PSCSI_REQUEST_BLOCK AbortSRB;
PBuslogic_CCB_T ccb;
BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[Srb->TargetId];
DebugPrint((TRACE, "\n BusLogic - Inside Start IO routine\n"));
// Make sure that this request isn't too long for the adapter. If so
// bounce it back as an invalid request
if (BusLogic_CDB_MaxLength < Srb->CdbLength)
{
DebugPrint((WARNING, "\n BusLogic - Srb->CdbLength [%d] > MaxCdbLength [%d]."
" Invalid request\n", Srb->CdbLength, BusLogic_CDB_MaxLength));
Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
ScsiPortNotification(RequestComplete,deviceExtension,Srb);
ScsiPortNotification(NextRequest,deviceExtension,NULL);
return TRUE;
}
switch (Srb->Function)
{
/*
Sirish, 10th June 2002
// Check if command is a WMI request.
case SRB_FUNCTION_WMI:
// Process the WMI request and return.
return BT958WmiSrb(HwDeviceExtension, (PSCSI_WMI_REQUEST_BLOCK) Srb);
*/
case SRB_FUNCTION_EXECUTE_SCSI:
// get the ccb structure from the extension
ccb = Srb->SrbExtension;
BusLogic_InitializeCCB(ccb);
// Save SRB back pointer in CCB.
ccb->SrbAddress = Srb;
// Build CCB. - Have some way of knowing that a srb has already been
// completed and you just need to return from here
BusLogic_QueueCommand(HwDeviceExtension ,Srb, ccb);
// Place the CCB in an Outgoing Mailbox. The higher levels of the SCSI
// Subsystem should not attempt to queue more commands than can be placed
// in Outgoing Mailboxes, so there should always be one free. In the
// unlikely event that there are none available, wait 1 second and try
// again. If that fails, the Host Adapter is probably hung so signal an
// error as a Host Adapter Hard Reset should be initiated soon.
if (!BusLogic_WriteOutgoingMailbox(deviceExtension , BusLogic_MailboxStartCommand, ccb))
{
DebugPrint((ERROR, "\n BusLogic - Unable to write Outgoing Mailbox - "
"Pausing for 1 second\n"));
ScsiPortStallExecution(1000);
if (!BusLogic_WriteOutgoingMailbox(deviceExtension , BusLogic_MailboxStartCommand, ccb))
{
DebugPrint((ERROR, "\n BusLogic - Still unable to write Outgoing"
"Mailbox - Host Adapter Dead?\n"));
Srb->SrbStatus = SRB_STATUS_ERROR;
ScsiPortNotification(RequestComplete,deviceExtension,Srb);
ScsiPortNotification(NextRequest,deviceExtension,NULL);
}
}
else
{
/*
* Reverted to pre 1.1.0.0 control flow
* The 1.1.0.0 control flow causes the .NET Server freeze during installs/restarts
* And the fix for that in 1.1.0.1 causes BSODs in XP
* Side note: Ben: the Buslogic emulation never exports more than 1 lun
*/
if (TargetFlags->TaggedQueuingActive
&& HostAdapter->ActiveCommands
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?