为什么我的 StorPort Virtual Miniport Driver (KMDF) 在首次调用 AdapterControl 函数后停止工作?
目前,驱动实现后(WinDbg)发生以下情况:
PSCSI_REQUEST_BLOCK
("SRB") -> 函数为 SRB_FUNCTION_STORAGE_REQUEST_BLOCK
(这对我来说没问题,因为在 HwFindAdapter 例程中,我将 PPORT_CONFIGURATION_INFORMATION
-> SrbType 定义为等于 SRB_TYPE_STORAGE_REQUEST_BLOCK
)。SCSI_ADAPTER_CONTROL_TYPE
使用 ControlType ScsiQuerySupportedControlTypes
进行调用(根据首次调用的 MS 文档,这是默认行为)。AdapterControl
例程并“要求”我定义一个设备。--
请注意,以下不是实际的完整代码,而是结构概述:
DriverEntry (
_In_ PVOID DriverObject,
_In_ PVOID RegistryPath
)
{
HW_INITIALIZATION_DATA initdata = { 0 }
initdata.HwFindAdapter = HwFindAdapter;
initdata.HwInitialize = HwInitialize;
initdata.HwAdapterControl = AdapterControl;
initdata.HwResetBus = HwResetBus;
initdata.HwStartIo = HwStartIo;
initdata.HwFreeAdapterResources = HwFreeAdapterResources;
initdata.AdapterInterfaceType = Internal;
initdata.MultipleRequestPerLu = TRUE;
initdata.PortVersionFlags = 0;
status = StorPortInitialize(
DriverObject,
RegistryPath,
&initdata,
NULL
);
return status;
}
|
HwFindAdapter (AdapterExtension, HwContext, BusInformation, ArgumentString, ConfigInfo, Reserved3)
{
//ConfigInfo is referenced to PPORT_CONFIGURATION_INFORMATION in the parameters above.
ConfigInfo->AlignmentMask = FILE_BYTE_ALIGNMENT;
ConfigInfo->NumberOfBuses = 1
ConfigInfo->CachesData = FALSE;
ConfigInfo->MapBuffers = STOR_MAP_ALL_BUFFERS_INCLUDING_READ_WRITE;
ConfigInfo->MaximumNumberOfTargets = 255;
ConfigInfo->SrbType = SRB_TYPE_STORAGE_REQUEST_BLOCK;
ConfigInfo->AddressType = STORAGE_ADDRESS_TYPE_BTL8;
ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
ConfigInfo->HwMSInterruptRoutine = NULL;
ConfigInfo->InterruptSynchronizationMode = InterruptSupportNone;
ConfigInfo->VirtualDevice = TRUE;
ConfigInfo->DumpMode = DUMP_MODE_RESUME;
ConfigInfo->MaxNumberOfIO = 100;
ConfigInfo->BusResetHoldTime = 0;
ConfigInfo->FeatureSupport = 0x7f;
return SP_RETURN_FOUND;
}
HwInitialize 在那里,但除了返回 STATUS_SUCCESS 之外什么也不做。
|
HwStartIo (
_In_ PVOID DeviceExtension,
_In_ PSCSI_REQUEST_BLOCK Srb
)
{
//Currently does nothing with data, as is not needed for now.
StorPortNotification(RequestComplete, DeviceExtension, Srb);
return TRUE;
}
|
AdapterControl (
_In_ PVOID DeviceExtension,
_In_ SCSI_ADAPTER_CONTROL_TYPE ControlType,
_In_ PVOID Parameters
)
{
PSCSI_SUPPORTED_CONTROL_TYPE_LIST controlTypeList;
switch (ControlType)
{
case ScsiQuerySupportedControlTypes:
controlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters; // get pointer to control type list
controlTypeList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
controlTypeList->SupportedTypeList[ScsiStopAdapter] = TRUE;
controlTypeList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
controlTypeList->SupportedTypeList[ScsiSetBootConfig] = TRUE;
//referenced cases are defined but not relevant for now.
}
return ScsiAdapterControlSuccess;
}
HwFreeAdapterResources 在那里,但什么也不做,也不返回任何内容,因为它是 VOID。
好的,所以我发现出了什么问题。
HwStartIo 被调用,但值为
PSCSI_REQUEST_BLOCK->Function == "SRB_FUNCTION_PNP"
。
这表明事先调用的任何函数都有错误,在我的例子中,我设置了错误的返回代码(函数 HwInitialize:我返回了
"STATUS_SUCCESS" (0xL) instead of "TRUE" (0x0)
。)
在正常操作中,首次初始化时,
PSCSI_REQUEST_BLOCK->Function
应等于 "SRB_FUNCTION_EXECUTE_SCSI"
,以收集 SCSI 总线、目标和 LUN 信息。
在 HwFindAdapter 之后,如果在 HwInitialize 或 HwPassiveInitialize 中遇到错误,它将使用 RemoveDevice 触发 SRB_FUNCTION_PNP。
顺便说一句,虚拟微型端口驱动程序将在关闭的最后阶段触发 HwFreeAdapterResource。您可以将您的关机程序放在这里。
在 HwAdapterControl 中,当设备电源从 D0 转换到 D3 时,会触发 ScsiStopAdapter 事件。当设备从睡眠或休眠状态(Dx 到 D0)唤醒时,ScsiRestartAdapter 被触发。