I’m writing a very simple KMDF driver for an FX2 board, in KMDF 1.5 for
XP SP2. It implements most of the ioctls from the old Cypress EZUSB
driver. All of the descriptor and control requests work perfectly.
However, I can’t get bulk operations to work.
There is one ioctl for bulk read, and one for bulk write. The input
buffer gives the pipe number, and the output buffer gives the data
buffer itself (read is METHOD_OUT_DIRECT, write is METHOD_IN_DIRECT).
So, I call
WdfRequestRetrieveInputBuffer to get the pipe number
WdfRequestRetrieveOutputMemory to get an object for the buffer
WdfUsbTargetPipeSetNoMaximumPacketSizeCheck
WdfUsbTargetPipeFormatRequestForRead (or Write)
WDF_REQUEST_SEND_OPTIONS options;
WDF_REQUEST_SEND_OPTIONS_INIT(
&options,
WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET
);
WdfRequestSend( Request, WdfUsbTargetPipeGetIoTarget( Pipe ),
&options );
I then return without completing the request.
What the application sees is that the ioctls return successfully, but
with no bytes processed. Further, a USB sniffer shows no activity on
the bulk pipe. The in-flight recorder shows this for the write request:
182: FxPkgIo::Dispatch - WDFDEVICE 0x76C8AC48 !devobj 0x89746C98
0x0000000e(IRP_MJ_DEVICE_CONTROL), IRP_MN 0, IRP 0x8B446ED8
183: FxDevice::AllocateRequestMemory - Allocating FxRequest* 8976F010,
WDFREQUEST 76890FE8
184: FxIoQueue::QueueRequest - Queuing WDFREQUEST 0x76890FE8 on WDFQUEUE
0x76C9C7D8
185: FxIoQueue::DispatchEvents - Thread 89E38020 is processing WDFQUEUE
0x76C9C7D8
186: FxIoQueue::DispatchRequestToDriver - Calling driver
EvtIoDeviceControl for WDFREQUEST 0x76890FE8
187: imp_WdfRequestRetrieveInputBuffer - Enter: WDFREQUEST 0x76890FE8
188: imp_WdfRequestRetrieveOutputMemory - Enter: WDFREQUEST 0x76890FE8
189: imp_WdfUsbTargetPipeSetNoMaximumPacketSizeCheck - WDFUSBPIPE 75F27C90
190: imp_WdfUsbTargetPipeFormatRequestForWrite - WDFUSBPIPE 75F27C90,
WDFREQUEST 76890FE8, WDFMEMORY 76890F79
191: FxUsbPipe::_FormatTransfer - WDFUSBPIPE 75F27C90, WDFREQUEST
76890FE8, WDFMEMORY 76890F79, STATUS_SUCCESS
192: FxIoQueue::RequestCompletedCallback - Enter: WDFQUEUE 0x76C9C7D8,
WDFREQUEST 0x76890FE8
193: FxDevice::FreeRequestMemory - Free FxRequest* 8976F010 memory
194: FxIoQueue::DispatchRequestToDriver - WDFREQUEST 0x76890FE8
dispatched to driver
195: FxIoQueue::DispatchEvents - No requests on WDFQUEUE 0x76C9C7D8
Notice that it goes straight from FormatTransfer to
RequestCompletedCallback. I was surprised not to see a line for
WdfRequestSend. I was also surprised to see that the WDFMEMORY handle
was an odd number. I thought all WDF objects used the same algorithm to
map address to handle. However, I can fetch the buffer address and
length from this handle, so it must be OK.
The WDFUSBPIPE, WDFUSBINTERFACE, and WDFUSBDEVICE structures all look
correct. I’ve triple-checked that I’m writing to the OUT pipe and
reading from the IN pipe. The pipe IO targets show “started”.
As an experiment, I replaces the SEND_AND_FORGET sequence with one that
sets a completion routine. In that case, the request hangs forever, or
until I Ctrl-C the test app, at which point my completion routine gets
called. Again, however, the USB Sniffer shows no activity on the bulk
pipes.
Am I missing something? I could write this kind of thing in my sleep
for WDM, but I thought this would be a great opportunity to find out
about the USB parts of KMDF.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.