I’ve written a driver for a proprietary USB protocol which I use. I’m using WdfRequestSend to forward requests to the correct USB endpoints, however, in the completion function I always find that the IoStatus is STATUS_UNSUCCESSFUL, yet the USBD status is STATUS_SUCCESS.
I have no idea how to debug this, I’ve tried numerous things such as making the request synchronously using WdfUsbTargetPipeWriteSynchronously, and doing the work in a worker thread. I have no idea what is going wrong, and trying to debug STATUS_SUCCESS is difficult.
This is quite a headache compared to developing drivers on linux!
a.) Have you established a Kd session (windbg)?
b.) Have you loaded the correct symbols both for the OS and your driver?
mm
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Thursday, October 21, 2010 7:25 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] WdfRequestSend STATUS_UNSUCCESSFUL.
Hello,
I’ve written a driver for a proprietary USB protocol which I use. I’m using
WdfRequestSend to forward requests to the correct USB endpoints, however, in
the completion function I always find that the IoStatus is
STATUS_UNSUCCESSFUL, yet the USBD status is STATUS_SUCCESS.
I have no idea how to debug this, I’ve tried numerous things such as making
the request synchronously using WdfUsbTargetPipeWriteSynchronously, and
doing the work in a worker thread. I have no idea what is going wrong, and
trying to debug STATUS_SUCCESS is difficult.
This is quite a headache compared to developing drivers on linux!
I can get WinDBG attached to the kernel of the machine I’m working on. (I don’t really have another machine to help me debug.) And I’ve got all the symbols loaded correctly, but I presume I can’t add breakpoints on the kernel running on this machine?
I’ve been using DebugView extensively to develop the driver. (Write commands seem to work fine, and have very similar code.)
Regarding breakpoints, correct. In order to actually debug a driver, you
must have either a second machine or in some cases a supported virtual
machine will work, but given that you hitting real hardware, that’s not an
option for you.
Without a second machine, all that you are really going to be able to do in
the way of ‘debugging’ is examine trace statements. Consequently, I really
don’t know what to tell you to do next, if you don’t want to set up a second
machine.
You lost me with the bit about ‘write commands.’
Good luck,
mm
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Thursday, October 21, 2010 8:09 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] WdfRequestSend STATUS_UNSUCCESSFUL.
I can get WinDBG attached to the kernel of the machine I’m working on. (I
don’t really have another machine to help me debug.) And I’ve got all the
symbols loaded correctly, but I presume I can’t add breakpoints on the
kernel running on this machine?
I’ve been using DebugView extensively to develop the driver. (Write commands
seem to work fine, and have very similar code.)
I’m sorry about the comment on write statement, after re-reading it’s somewhat misplaced.
The problem I’m having only occurs in my EvtIoRead handler. I can issue write commands to the USB hardware without any such error.
I’m not sure what you mean by ETW support, Maxim.
My protocol works like so:
I have two interrupt EPs, one in each direction, and two bulk EPs, again, one in each direction.
The interrupts are used to negotiate swapping streams being sent from the USB device, to query how much data is queued on the device, and for telling the device how much data we have to send.
In order to read, I do the following:
* If we don’t know how much data is queued, (or we’ve read all that was queued last time we asked), I send a command on the out interrupt, requesting the amount of data queued. (Synchronously.) Then I return from the function. Execution doesn’t continue until a response is received on the in interrupt.
* I get a response from the in interrupt pipe telling me how much data is queued.
* I then check the read amount against the maximum packet size and the amount the device has queued, and adjust using a WDFMEMORY_OFFSET accordingly.
* I then send a command telling the device to send that amount of data over bulkIn. (Asynchronously.) Using the read request.
* I then forward the request to the USB stack to perform the actual read (which fails).
Additionally, I do have a netbook I could use for debugging, but the network I’m on is restricted and I cannot use the COM/1934/USB options as I do not have the required ports on the netbook, or the correct lead for USB.
My protocol works like so:
I have two interrupt EPs, one in each direction, and two bulk EPs, again, one in each direction.
The interrupts are used to negotiate swapping streams being sent from the USB device, to query how much data is queued on the device, and for telling the device how much data we have to send.
In order to read, I do the following:
* If we don’t know how much data is queued, (or we’ve read all that was queued last time we asked), I send a command on the out interrupt, requesting the amount of data queued. (Synchronously.) Then I return from the function. Execution doesn’t continue until a response is received on the in interrupt.
* I get a response from the in interrupt pipe telling me how much data is queued.
That’s an unusual and somewhat wasteful approach. Why don’t you just
use a vendor command over the control pipe? That way, you can do the
write and the read at the same time, and reduce the driver complexity at
the same time.
* I then check the read amount against the maximum packet size and the amount the device has queued, and adjust using a WDFMEMORY_OFFSET accordingly.
Why? I don’t see how that makes sense.
* I then send a command telling the device to send that amount of data over bulkIn. (Asynchronously.) Using the read request.
I don’t understand the whole “how much data is there” paradigm here.
Why not skip the whole first exchange and just issue a bulk read? If
the device has data, it returns whatever it has. If it doesn’t, it can
return an empty packet. That seems like a lot less overhead.
In general, a design that requires you to tell your USB device “send
this much data” is flawed. You should just read, and the device should
send whatever it has.
* I then forward the request to the USB stack to perform the actual read (which fails).
There’s not much we can tell without seeing some code.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
> * If we don’t know how much data is queued, (or we’ve read all that was queued last time we asked), I send a command on the out interrupt, requesting the amount of data queued. (Synchronously.) Then I return from the function. Execution doesn’t continue until a response is received on the in interrupt.
* I get a response from the in interrupt pipe telling me how much data is queued.
* I then check the read amount against the maximum packet size and the amount the device has queued, and adjust using a WDFMEMORY_OFFSET accordingly.
* I then send a command telling the device to send that amount of data over bulkIn. (Asynchronously.) Using the read request.
* I then forward the request to the USB stack to perform the actual read (which fails).
What is the need in all these complexities?
Why not just plain do the bulk-in read and nothing else?