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