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().
Example #3
0
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().