I have BUS driver that does static enumeration.
Now I need to reload my Child FDO on some soft error. I tried WdfDeviceSetFailed(WdfDeviceFailedAttemptRestart), Looks like that is only for Dynamic enumeration (along with BusDriver implementing REENUMERATE_SELF_INTERFACE_STANDARD, SurpriseRemoveAndReenumerateSelf()).
Is there any way to have my child FDO ( statically enumerated) reload itself
without re-creating PDO (like in disable/Enable case)
Any other standard QI interfaces etc for me to implement in BUSDriver to recreate PDO and reload my FDO driver automatically (preferably when WdfDeviceSetFailed(WdfDeviceFailedAttemptRestart) invoked.
Else is it my only options are
with static enumeration, implement own custom interface, to recreate the PDO
or use dynamic enumeration w/ REENUMERATE_SELF_INTERFACE_STANDARD.
Just use dynamic enumeration for this child. You can keep static enumeration for other children if you need to. All of the data you supply for the static child you provide for the dynamic child, just in a different callback. IOW your existing could is nearly all reusable.
BTW on disable/enable, the PDO is not deleted. Only the drivers layered on top of the PDO are removed and deleted
Thanks Doron. Will change to dynamic enumeration.
Also I have a UMDF lower filter between my KMDF Child FDO and BudDriver, hopefully I won’t see any issues.
Implemented dynamic enumeration for my child FDOs’.
Do I have to still implement REENUMERATE_SELF_INTERFACE_STANDARD on my PDO?
Actually my error was in one of WdfDevice callbacks (from a port driver), that happens after my PrepHw() returns and before D0Entry() is called.
-With static enumeration, once I return error, the FDO is yellow bang in device Manager immediately.
-With Dynamic enumeration, looks like PnP tried some 6 times and gave up.
-Just for test did WdfDeviceSetFailed(WdfDeviceFailedAttemptRestart) before returning error from callback, Pnp manager reloads the driver infinitely (As I never got to return Success yet)
In none of the cases above I ever got call to
a) EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN Bus_EvtChildListScanForChildren;
b) EVT_WDF_CHILD_LIST_DEVICE_REENUMERATED Bus_EvtChildListDeviceReenumerated;
So for above case looks like I need to implement some private counter etc. to decide when I have to stop calling WdfDeviceSetFailed(WdfDeviceFailedAttemptRestart) to force PnP finally give up, in case I never recover internally (i.e. cannot return SUCCESS)
I guess in above cases, at no time my PDO was destroyed and recreated (since a/b were never called)
Also looks like I really do not have to provide impl. to below. Default implementations seems sufficient
c) EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COMPARE Bus_EvtChildListIdentificationDescriptionCompare;
d) EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_CLEANUP Bus_EvtChildListIdentificationDescriptionCleanup;
e) EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_DUPLICATE Bus_EvtChildListIdentificationDescriptionDuplicate;
Also after dynamic enumeration, had issues with child FDOs being visible in DeviceManager (‘Driver working properly, but device connected has HW ID issues’ msg).
EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_DUPLICATE sampl impl, wasn’t doing proper count/copy of my HW IDs. Changed my HW IDs thinking if WCHAR/UNICODE_STRING/null-chars were causing issues. But even after HWID mods and fixing count/copy, same issue. Uninstalling/deleting existing installed packages didn’t help. Went back to static enumeration which was working all along, that also encountered issue.
Had to change back to original HW IDs’ I had to have drivers install again. Looks like once different HW IDs got assigned to PDO, some check was happening with old persisted HW IDs. Was expecting whatever HWID, it would have just not installed drivers from store and instead be ready in UI to install/upgrade the driver instead of ‘Driver working properly, but device connected has HW ID issues’ msg.
Correction, I do get calls to below, so i can veto out any further re-enumeration, if excessive #fails happen w/o fwd progress.
a) EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN ;
b) EVT_WDF_CHILD_LIST_DEVICE_REENUMERATED ;
Also induced calling WdfSetFailed(Restart) outside the context of WdfDevice callbacks, it works as expected.
if I use dynamic enumeration (WDFCHILDLIST), I do not need REENUMERATE_SELF_INTERFACE_STANDARD right?
Anyways had code for REENUMERATE_SELF_INTERFACE_STANDARD as well, so tried WdfFdoQueryForInterface(REENUMERATE_SELF_INTERFACE_STANDARD), but my query handler doesn’t get called.
But the call returns returns SUCCESS, so went ahead with interface->SurpriseRemoveAndReenumerateSelf() ! with whatever the Fx returned for SurpriseRemoveAndReenumerateSelf, it BSODS.
Looks like CHILDLIST and REENUMERATE_SELF_INTERFACE_STANDARD are exclusive or something. Of course I guess just one suffice and CHILDLIST provides default impl.
if I use dynamic enumeration (WDFCHILDLIST), I do not need REENUMERATE_SELF_INTERFACE_STANDARD right?
Anyways had code for REENUMERATE_SELF_INTERFACE_STANDARD as well, so tried WdfFdoQueryForInterface(REENUMERATE_SELF_INTERFACE_STANDARD), but my query handler doesn’t get called.
But the call returns returns SUCCESS, so went ahead with interface->SurpriseRemoveAndReenumerateSelf() ! with whatever the Fx returned for SurpriseRemoveAndReenumerateSelf, it BSODS.
Looks like CHILDLIST and REENUMERATE_SELF_INTERFACE_STANDARD are exclusive or something. Of course I guess just one suffice and CHILDLIST provides default impl.