I'm currently writing a KMDF based driver that will upon insertion of
a USB device, download firmware to it and then reset the USB bus
causing re-enumeration. I'm not entirely clear on the best way to
implement this, my current plan is as follows:
* From EvtPrepareHardware, I start a timer which causes TimerExpired
to be called
* In TimerExpired, I do a USB control transfer to check device state,
upload a block of data and then set another timer.
I thought this should be working, but I'm running into an access
violation somewhere in the USB stack, and I'm not sure how to debug
this further. When I call this function from EvtPrepareHardware
itself, everything works fine, but calling it from TimerExpired causes
the access violation. The call stack at that moment is as follows:
(using KMDF 1.5)
nt!DbgBreakPoint
Wdf01000!imp_WdfUsbTargetDeviceSendControlTransferSynchronously+0x186
mydriver!WdfUsbTargetDeviceSendControlTransferSynchronously+0x29
mydriver!TimerExpired
Now I have two questions:
1. Should I be using this design or would you suggest a different way?
(the protocol requires me to sleep every now and then, and since you
can't just use Sleep() I decided to go for the design as described).
2. What could be causing the access violation? Is it not allowed to
call USB stack functions from TimerExpired?
My TimerExpired function looks something like this:
VOID TimerExpired(IN WDFTIMER Timer)
{
NTSTATUS status;
WDFDEVICE Device;
PDEVICE_CONTEXT pDeviceContext;
WDF_USB_CONTROL_SETUP_PACKET thePacket;
BYTE buf[16];
DWORD len, nbytes;
WDF_MEMORY_DESCRIPTOR memoryDescriptor;
Device = WdfTimerGetParentObject(Timer);
pDeviceContext = GetDeviceContext(Device);
WDF_USB_CONTROL_SETUP_PACKET_INIT_CLASS(
&thePacket,
BmRequestDeviceToHost,
BmRequestToInterface,
0x05,
0,
0
);
pDeviceContext = GetDeviceContext(Device);
WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memoryDescriptor,
(PVOID) buf,
*len);
status = WdfUsbTargetDeviceSendControlTransferSynchronously(
pDeviceContext-
>WdfUsbTargetDevice,
WDF_NO_HANDLE, // Optional
WDFREQUEST
NULL, //
PWDF_REQUEST_SEND_OPTIONS
&thePacket,
&memoryDescriptor, //
MemoryDescriptor
&nbytes); // BytesTransferred
}