VOID MpHwFreeAdapterResources(__in PVOID DeviceExtension) { PLIST_ENTRY pNextEntry; pHW_HBA_EXT pLclHBAExt; KLOCK_QUEUE_HANDLE LockHandle; KIRQL lowest_assumed_irql = PASSIVE_LEVEL; pHW_HBA_EXT pHBAExt = (pHW_HBA_EXT)DeviceExtension; KdPrint2(("PhDskMnt::MpHwFreeAdapterResources: pHBAExt = 0x%p\n", pHBAExt)); // Free memory allocated for disk ImScsiStopAdapter(pHBAExt, &lowest_assumed_irql); ImScsiAcquireLock(&pMPDrvInfoGlobal->DrvInfoLock, &LockHandle, lowest_assumed_irql); for ( // Go through linked list of HBA extensions. pNextEntry = pMPDrvInfoGlobal->ListMPHBAObj.Flink; pNextEntry != &pMPDrvInfoGlobal->ListMPHBAObj; pNextEntry = pNextEntry->Flink ) { pLclHBAExt = CONTAINING_RECORD(pNextEntry, HW_HBA_EXT, List); if (pLclHBAExt == pHBAExt) { // Is this entry the same as pHBAExt? RemoveEntryList(pNextEntry); pMPDrvInfoGlobal->DrvInfoNbrMPHBAObj--; break; } } ImScsiReleaseLock(&LockHandle, &lowest_assumed_irql); } // End MpHwFreeAdapterResources().
SCSI_ADAPTER_CONTROL_STATUS MpHwAdapterControl( __in pHW_HBA_EXT pHBAExt, // Adapter device-object extension from port driver. __in SCSI_ADAPTER_CONTROL_TYPE ControlType, __in PVOID pParameters ) { PSCSI_SUPPORTED_CONTROL_TYPE_LIST pCtlTypList; ULONG i; KdPrint2(("PhDskMnt::MpHwAdapterControl: pHBAExt = 0x%p, ControlType = 0x%p, pParameters=0x%p\n", pHBAExt, ControlType, pParameters)); pHBAExt->AdapterState = ControlType; switch (ControlType) { case ScsiQuerySupportedControlTypes: KdPrint2(("PhDskMnt::MpHwAdapterControl: ScsiQuerySupportedControlTypes\n")); // Ggt pointer to control type list pCtlTypList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)pParameters; // Cycle through list to set TRUE for each type supported // making sure not to go past the MaxControlType for (i = 0; i < pCtlTypList->MaxControlType; i++) if ( i == ScsiQuerySupportedControlTypes || i == ScsiStopAdapter || i == ScsiRestartAdapter || i == ScsiSetBootConfig || i == ScsiSetRunningConfig ) { pCtlTypList->SupportedTypeList[i] = TRUE; } break; case ScsiStopAdapter: KdPrint2(("PhDskMnt::MpHwAdapterControl: ScsiStopAdapter\n")); // Free memory allocated for disk ImScsiStopAdapter(pHBAExt); break; case ScsiRestartAdapter: KdPrint2(("PhDskMnt::MpHwAdapterControl: ScsiRestartAdapter\n")); /* To Do: Add some function. */ break; case ScsiSetBootConfig: KdPrint2(("PhDskMnt::MpHwAdapterControl: ScsiSetBootConfig\n")); break; case ScsiSetRunningConfig: KdPrint2(("PhDskMnt::MpHwAdapterControl: ScsiSetRunningConfig\n")); break; default: KdPrint2(("PhDskMnt::MpHwAdapterControl: UNKNOWN: 0x%X\n", ControlType)); break; } KdPrint2(("PhDskMnt::MpHwAdapterControl End: status=0x%x\n", ScsiAdapterControlSuccess)); return ScsiAdapterControlSuccess; } // End MpHwAdapterControl().
BOOLEAN MpHwStartIo( __in PHW_HBA_EXT pHBAExt, // Adapter device-object extension from port driver. __in __out PSCSI_REQUEST_BLOCK pSrb ) { UCHAR Result = ResultDone; #ifdef USE_SCSIPORT UCHAR PathId = pSrb->PathId; UCHAR TargetId = pSrb->TargetId; UCHAR Lun = pSrb->Lun; #endif KdPrint2(("PhDskMnt::MpHwStartIo: pHBAExt = 0x%p, pSrb = 0x%p, Path=%i, Target=%i, Lun=%i, IRQL=%i\n", pHBAExt, pSrb, (int) pSrb->PathId, (int) pSrb->TargetId, (int) pSrb->Lun, KeGetCurrentIrql())); pSrb->SrbStatus = SRB_STATUS_PENDING; pSrb->ScsiStatus = SCSISTAT_GOOD; ImScsiCompletePendingSrbs(pHBAExt); _InterlockedExchangeAdd((volatile LONG *)&pHBAExt->SRBsSeen, 1); // Bump count of SRBs encountered. // Next, if true, will cause port driver to remove the associated LUNs if, for example, devmgmt.msc is asked "scan for hardware changes." //if (pHBAExt->bDontReport) //{ // Act as though the HBA/path is gone? // pSrb->SrbStatus = SRB_STATUS_INVALID_LUN; // goto done; //} switch (pSrb->Function) { case SRB_FUNCTION_IO_CONTROL: ScsiIoControl(pHBAExt, pSrb, &Result); break; case SRB_FUNCTION_EXECUTE_SCSI: ScsiExecute(pHBAExt, pSrb, &Result); break; case SRB_FUNCTION_RESET_LOGICAL_UNIT: DbgPrint("PhDskMnt::MpHwStartIo: SRB_FUNCTION_RESET_LOGICAL_UNIT.\n"); pSrb->SrbStatus = ScsiResetLun(pHBAExt, pSrb); break; case SRB_FUNCTION_RESET_DEVICE: DbgPrint("PhDskMnt::MpHwStartIo: SRB_FUNCTION_RESET_DEVICE.\n"); pSrb->SrbStatus = ScsiResetDevice(pHBAExt, pSrb); break; case SRB_FUNCTION_RESET_BUS: DbgPrint("PhDskMnt::MpHwStartIo: SRB_FUNCTION_RESET_BUS.\n"); pSrb->SrbStatus = MpHwResetBus(pHBAExt, pSrb->PathId); break; case SRB_FUNCTION_PNP: MpHwHandlePnP(pHBAExt, (PSCSI_PNP_REQUEST_BLOCK)pSrb); break; case SRB_FUNCTION_POWER: KdPrint(("PhDskMnt::MpHwStartIo: SRB_FUNCTION_POWER.\n")); pSrb->SrbStatus = SRB_STATUS_SUCCESS; break; case SRB_FUNCTION_SHUTDOWN: KdPrint(("PhDskMnt::MpHwStartIo: SRB_FUNCTION_SHUTDOWN.\n")); pSrb->SrbStatus = SRB_STATUS_SUCCESS; ImScsiStopAdapter(pHBAExt); break; default: KdPrint(("PhDskMnt::MpHwStartIo: Unknown pSrb Function = 0x%X\n", pSrb->Function)); ScsiSetCheckCondition(pSrb, SRB_STATUS_ERROR, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ADSENSE_ILLEGAL_COMMAND, 0); break; } // switch (pSrb->Function) if (Result == ResultDone) { // Complete now? #ifdef USE_SCSIPORT KdPrint2(("PhDskMnt::MpHwStartIo sending 'RequestComplete', 'NextRequest' and 'NextLuRequest' to ScsiPort.\n")); ScsiPortNotification(RequestComplete, pHBAExt, pSrb); ScsiPortNotification(NextRequest, pHBAExt); ScsiPortNotification(NextLuRequest, pHBAExt, 0, 0, 0); #endif #ifdef USE_STORPORT KdPrint2(("PhDskMnt::MpHwStartIo sending 'RequestComplete' to port StorPort.\n")); StorPortNotification(RequestComplete, pHBAExt, pSrb); #endif } else { #ifdef USE_SCSIPORT _InterlockedExchangeAdd((volatile LONG*)&pHBAExt->WorkItems, 1); KdPrint2(("PhDskMnt::MpHwStartIo sending 'RequestTimerCall' and 'NextLuRequest' to ScsiPort.\n")); ScsiPortNotification(RequestTimerCall, pHBAExt, MpHwTimer, (ULONG) 1); ScsiPortNotification(NextLuRequest, pHBAExt, PathId, TargetId, Lun); ScsiPortNotification(NextLuRequest, pHBAExt, 0, 0, 0); #endif } KdPrint2(("PhDskMnt::MpHwStartIo End.\n")); return TRUE; } // End MpHwStartIo().