buslogic958.c
来自「一个类似windows」· C语言 代码 · 共 1,684 行 · 第 1/5 页
C
1,684 行
&RequestedReplyLength,
sizeof(RequestedReplyLength),
&SetupInformation, sizeof(SetupInformation))
!= sizeof(SetupInformation))
{
DebugPrint((0, "BusLogic_Failure: INQUIRE SETUP INFORMATION"));
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((0, "BusLogic_Failure: INQUIRE SYNCHRONOUS PERIOD"));
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((0,"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 &&
(BusLogic_CDB_MaxLength< Srb->CdbLength))
{
DebugPrint((0,"DebugPrint: 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((0,"Unable to write Outgoing Mailbox - " "Pausing for 1 second\n"));
ScsiPortStallExecution(1000);
if (!BusLogic_WriteOutgoingMailbox(deviceExtension , BusLogic_MailboxStartCommand, ccb))
{
DebugPrint((0,"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->ActiveCommandsPerLun[Srb->TargetId][Srb->Lun] < BUSLOGIC_MAXIMUM_TAGS) {
ScsiPortNotification(NextLuRequest, HwDeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun);
}
else {
ScsiPortNotification(NextRequest,deviceExtension,NULL);
}
}
return TRUE;
case SRB_FUNCTION_ABORT_COMMAND:
// Get CCB to abort.
ccb = Srb->NextSrb->SrbExtension;
// Set abort SRB for completion.
ccb->AbortSrb = Srb;
AbortSRB = ScsiPortGetSrb(HwDeviceExtension,
Srb->PathId,
Srb->TargetId,
Srb->Lun,
Srb->QueueTag);
if ((AbortSRB != Srb->NextSrb) || (AbortSRB->SrbStatus != SRB_STATUS_PENDING))
{
Srb->SrbStatus = SRB_STATUS_ABORT_FAILED;
ScsiPortNotification(RequestComplete, HwDeviceExtension, Srb);
ScsiPortNotification(NextRequest, HwDeviceExtension, NULL);
return TRUE;
}
// write the abort information into a mailbox
if (BusLogic_WriteOutgoingMailbox( deviceExtension, BusLogic_MailboxAbortCommand, ccb))
{
DebugPrint((0, "BusLogic_Warning: Aborting CCB #%ld to Target %d\n",ccb->SerialNumber, Srb->TargetId));
// Adapter ready for next request.
/*
* 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->ActiveCommandsPerLun[Srb->TargetId][Srb->Lun] < BUSLOGIC_MAXIMUM_TAGS) {
ScsiPortNotification(NextLuRequest, HwDeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun);
}
else {
ScsiPortNotification(NextRequest,deviceExtension,NULL);
}
}
else
{
DebugPrint((0,"BusLogic_Warning: Unable to Abort CCB #%ld to Target %d - ""No Outgoing Mailboxes\n",ccb->SerialNumber, Srb->TargetId));
Srb->SrbStatus = SRB_STATUS_ERROR;
ScsiPortNotification(RequestComplete, HwDeviceExtension, Srb);
ScsiPortNotification(NextRequest, HwDeviceExtension, NULL);
}
return TRUE;
case SRB_FUNCTION_RESET_BUS:
// Reset SCSI bus.
DebugPrint((0,"BusLogic - SRB_FUNCTION_RESET_BUS,srb=%x \n",Srb));
BT958HwResetBus(HwDeviceExtension, Srb->PathId);
Srb->SrbStatus = SRB_STATUS_SUCCESS;
ScsiPortNotification(RequestComplete, HwDeviceExtension, Srb);
ScsiPortNotification(NextRequest, HwDeviceExtension, NULL);
return TRUE;
case SRB_FUNCTION_RESET_DEVICE:
ccb = Srb->SrbExtension;
BusLogic_InitializeCCB(ccb);
// Save SRB back pointer in CCB.
ccb->SrbAddress = Srb;
if(!BusLogic_SendBusDeviceReset(HostAdapter, Srb))
{
BT958HwResetBus(HwDeviceExtension, SP_UNTAGGED);
Srb->SrbStatus = SRB_STATUS_SUCCESS;
ScsiPortNotification(RequestComplete, HwDeviceExtension, Srb);
ScsiPortNotification(NextRequest, HwDeviceExtension, NULL);
return TRUE;
}
/*
* 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->ActiveCommandsPerLun[Srb->TargetId][Srb->Lun] < BUSLOGIC_MAXIMUM_TAGS) {
ScsiPortNotification(NextLuRequest, HwDeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun);
}
else {
ScsiPortNotification(NextRequest,deviceExtension,NULL);
}
return TRUE;
default:
// Set error, complete request and signal ready for next request.
Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
ScsiPortNotification(RequestComplete,deviceExtension,Srb);
ScsiPortNotification(NextRequest,deviceExtension,NULL);
return TRUE;
} // end switch
}// end BusLogic_TargetDeviceInquiry
BOOLEAN
BusLogic_WriteOutgoingMailbox(PHW_DEVICE_EXTENSION deviceExtension ,
BusLogic_ActionCode_T ActionCode,
BusLogic_CCB_T *CCB)
//______________________________________________________________________________________________
// Routine Description:
// BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
// Mailbox for execution by Host Adapter. The Host Adapter's Lock should
// already have been acquired by the caller.
// Arguments:
// 1. deviceExtension: device extension
// 2. ActionCode : action code for the mailbox which can be
// BusLogic_OutgoingMailboxFree = 0x00,
// BusLogic_MailboxStartCommand = 0x01,
// BusLogic_MailboxAbortCommand = 0x02
// 3. CCB :The CCB that has to be written into the mailbox
// Return Value:
// TRUE : write to the mailbox was successful
// FALSE : write failed
//______________________________________________________________________________________________
{
BusLogic_HostAdapter_T *HostAdapter = &(deviceExtension->hcs);
BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
ULONG length;
NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
{
CCB->Status
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?