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