buslogic958.c
来自「一个类似windows」· C语言 代码 · 共 1,684 行 · 第 1/5 页
C
1,684 行
// Determine whether Extended LUN Format CCBs are supported and save the
// information in the Host Adapter structure.
if (HostAdapter->FirmwareVersion[0] == '5' ||
(HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
{
HostAdapter->ExtendedLUNSupport = TRUE;
}
// Issue the Inquire PCI Host Adapter Information command to read the
// Termination Information from "W" series MultiMaster Host Adapters.
if (HostAdapter->FirmwareVersion[0] == '5')
{
if (BusLogic_Command(HostAdapter,
BusLogic_InquirePCIHostAdapterInformation,
NULL,
0,
&PCIHostAdapterInformation,
sizeof(PCIHostAdapterInformation))
!= sizeof(PCIHostAdapterInformation))
{
DebugPrint((0, "BusLogic_Failure: INQUIRE PCI HOST ADAPTER INFORMATION"));
return FALSE;
}
// Save the Termination Information in the Host Adapter structure.
if (PCIHostAdapterInformation.GenericInfoValid)
{
HostAdapter->TerminationInfoValid = TRUE;
HostAdapter->LowByteTerminated = PCIHostAdapterInformation.LowByteTerminated;
HostAdapter->HighByteTerminated = PCIHostAdapterInformation.HighByteTerminated;
}
}
// Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data
// from "W" and "C" series MultiMaster Host Adapters.
if (HostAdapter->FirmwareVersion[0] >= '4')
{
FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset;
FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
if (BusLogic_Command(HostAdapter,
BusLogic_FetchHostAdapterLocalRAM,
&FetchHostAdapterLocalRAMRequest,
sizeof(FetchHostAdapterLocalRAMRequest),
&AutoSCSIData,
sizeof(AutoSCSIData))
!= sizeof(AutoSCSIData))
{
DebugPrint((0, "BusLogic_Failure: FETCH HOST ADAPTER LOCAL RAM"));
return FALSE;
}
// Save the Parity Checking Enabled, Bus Reset Enabled, and Termination
// Information in the Host Adapter structure.
HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
// Save the Wide Permitted, Fast Permitted, Synchronous Permitted,
// Disconnect Permitted, Ultra Permitted, and SCAM Information in the
// Host Adapter structure.
HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
HostAdapter->SynchronousPermitted = AutoSCSIData.SynchronousPermitted;
HostAdapter->DisconnectPermitted = AutoSCSIData.DisconnectPermitted;
if (HostAdapter->HostUltraSCSI)
{
HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
}
if (HostAdapter->HostSupportsSCAM)
{
HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
}
}
// Determine the maximum number of Target IDs and Logical Units supported by
// this driver for Wide and Narrow Host Adapters.
HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
// Select appropriate values for the Mailbox Count,
// Initial CCBs, and Incremental CCBs variables based on whether or not Strict
// Round Robin Mode is supported. If Strict Round Robin Mode is supported,
// then there is no performance degradation in using the maximum possible
// number of Outgoing and Incoming Mailboxes and allowing the Tagged and
// Untagged Queue Depths to determine the actual utilization. If Strict Round
// Robin Mode is not supported, then the Host Adapter must scan all the
// Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can
// cause a substantial performance penalty. The host adapters actually have
// room to store the following number of CCBs internally; that is, they can
// internally queue and manage this many active commands on the SCSI bus
// simultaneously. Performance measurements demonstrate that the Driver Queue
// Depth should be set to the Mailbox Count, rather than the Host Adapter
// Queue Depth (internal CCB capacity), as it is more efficient to have the
// queued commands waiting in Outgoing Mailboxes if necessary than to block
// the process in the higher levels of the SCSI Subsystem.
//
// 192 BT-948/958/958D
if (HostAdapter->FirmwareVersion[0] == '5')
{
HostAdapter->HostAdapterQueueDepth = 192;
}
if (strcmp((char*)HostAdapter->FirmwareVersion, "3.31") >= 0)
{
HostAdapter->StrictRoundRobinModeSupport = TRUE;
HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
}
//
// Tagged Queuing support is available and operates properly on all "W" series
// MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with
// firmware version 4.22 and above, and on "S" series MultiMaster Host
// Adapters with firmware version 3.35 and above.
HostAdapter->TaggedQueuingPermitted = 0xFFFF;
//
// Determine the Host Adapter BIOS Address if the BIOS is enabled and
///save it in the Host Adapter structure. The BIOS is disabled if the
// BIOS_Address is 0.
HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
//
//Initialize parameters for MultiMaster Host Adapters.
//
// Initialize the Host Adapter Full Model Name from the Model Name.
strcpy((char*)HostAdapter->FullModelName, "BusLogic ");
strcat((char*)HostAdapter->FullModelName, (char*)HostAdapter->ModelName);
// Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
// Therefore, mask the Tagged Queuing Permitted Default bits with the
// Disconnect/Reconnect Permitted bits.
HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
// Select an appropriate value for Bus Settle Time either from a BusLogic
// Driver Options specification, or from BusLogic_DefaultBusSettleTime.
HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
// Indicate reading the Host Adapter Configuration completed successfully.
return TRUE;
}// end BusLogic_ReadHostAdapterConfiguration
BOOLEAN
BusLogic_InitializeHostAdapter(PHW_DEVICE_EXTENSION deviceExtension,
PPORT_CONFIGURATION_INFORMATION ConfigInfo)
//_____________________________________________________________________________________________
// Routine Description:
// BusLogic_InitializeHostAdapter initializes Host Adapter. This is the only
// function called during SCSI Host Adapter detection which modifies the state
// of the Host Adapter from its initial power on or hard reset state.
// Arguments:
// 1. device extension
// 2. port config information
// Return Value:
// TRUE : Host Adapter initialization completed successfully
// FALSE : Initialization failed
//______________________________________________________________________________________________
{
BusLogic_HostAdapter_T *HostAdapter = &(deviceExtension->hcs);
BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
UCHAR RoundRobinModeRequest;
UCHAR SetCCBFormatRequest;
int TargetID, LunID;
// Used when we get the Physical address of the mail boxes
ULONG length;
// Initialize the pointers to the first and last CCBs that are queued for
// completion processing.
HostAdapter->FirstCompletedCCB = NULL;
HostAdapter->LastCompletedCCB = NULL;
// Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
// Command Successful Flag, Active Commands, and Commands Since Reset
// for each Target Device.
for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
{
HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = FALSE;
HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = FALSE;
HostAdapter->ActiveCommandsPerTarget[TargetID] = 0;
for (LunID = 0; LunID < HostAdapter->MaxLogicalUnits; LunID++)
HostAdapter->ActiveCommandsPerLun[TargetID][LunID] = 0;
HostAdapter->CommandsSinceReset[TargetID] = 0;
}
// Convert virtual to physical mailbox address.
deviceExtension->NoncachedExtension->MailboxPA = ScsiPortConvertPhysicalAddressToUlong(
ScsiPortGetPhysicalAddress(deviceExtension,
NULL,
deviceExtension->NoncachedExtension->MailboxOut,
&length));
HostAdapter->FirstOutgoingMailbox = (BusLogic_OutgoingMailbox_T *) deviceExtension->NoncachedExtension->MailboxOut;
HostAdapter->LastOutgoingMailbox = HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
HostAdapter->FirstIncomingMailbox = (BusLogic_IncomingMailbox_T *) deviceExtension->NoncachedExtension->MailboxIn;
HostAdapter->LastIncomingMailbox = HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
// Initialize the Outgoing and Incoming Mailbox structures.
memset(HostAdapter->FirstOutgoingMailbox,
0,
HostAdapter->MailboxCount * sizeof(BusLogic_OutgoingMailbox_T));
memset(HostAdapter->FirstIncomingMailbox,
0,
HostAdapter->MailboxCount * sizeof(BusLogic_IncomingMailbox_T));
ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
ExtendedMailboxRequest.BaseMailboxAddress = deviceExtension->NoncachedExtension->MailboxPA ;
if (BusLogic_Command(HostAdapter,
BusLogic_InitializeExtendedMailbox,
&ExtendedMailboxRequest,
sizeof(ExtendedMailboxRequest),
NULL, 0)
< 0)
{
DebugPrint((0,"BusLogic_Failure: MAILBOX INITIALIZATION"));
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((0,"BusLogic_Failure: ENABLE STRICT ROUND ROBIN MODE"));
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((0, "BusLogic_Failure: SET CCB FORMAT"));
return FALSE;
}
}
// Announce Successful Initialization.
if (!HostAdapter->HostAdapterInitialized)
{
DebugPrint((0,"Info *** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName));
}
else
{
DebugPrint((0,"Warning *** %s 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((0, "BusLogic_Failure: INQUIRE TARGET DEVICES"));
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,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?