W7/W10: host wake issue with USB2 device

Hi,

I have a standalone device (musical equipment) which can be configured via USB2. It has two 64 byte bulk endpoints (IN and OUT) in its only configuration and single interface, and only supports power state D0 (well, and OFF of cause).

My host test application opens our KMDF driver, which selects the USB configuration, opens its two pipes and communicates with it.
This all works well (including (surprise) device arrival/removal, etc.).

Under W7 after sending the host to sleep (canceling all outstanding I/O if any) and keeping the pipes open, the drivers IRPs to the USB don?t get handled anymore in its EvtDeviceD0Entry. They don?t appear on the USB bus and are not finalised by the stack.

If a work item is scheduled from EvtDeviceD0Entry instead, its possible to send normal USB read/write requests. However an attempt to send either a URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL or its KMDF equivalent WdfUsbTargetPipeResetSynchronously will hang without any activity seen on the USB bus. (I have also tried to send the requests from EvtDeviceSelfManagedIoInit/EvtDeviceSelfManagedIoRestart instead.)

Under W10 even read/write transaction requests are not send/finalized wether deferred or sent directly from EvtDeviceD0Entry.

From the bus log I assume the device itself reacts correctly to all configuration/device descriptor request after the host wakes up. There are no errors in the bus communication seen.

When the host goes to sleep without any open user mode handles to the kernel driver (no open pipes) the system can sleep/wake and the test application can be started again with successful USB communication.

Thats why I test-wise tried to “iterate” over the interface and create new pipes handles after the system waking up. I did not try to re-send a configuration request, yet. (But I do see the bus driver correctly does so.)

I am running out of ideas what else to check now, I am very thankful for any (even vage) hints what to look for.

Thanks and cheers,
Hagen.

>power state D0 (well, and OFF of cause).

OFF is D3 :slight_smile:


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

… I am not sure if D3 also refers to un-anounced removing of the power cable, what I meant is that the device can’t be set into any other power state via USB.

… and in case it matters the device can’t wake up the host.

xxxxx@dynax.at wrote:

… I am not sure if D3 also refers to un-anounced removing of the power cable, what I meant is that the device can’t be set into any other power state via USB.

D3 simply refers to the state where the device is off. When the system
goes into any state other than S0 (on), your driver should respond by
going into D3. Are you doing any power configuration in your KMDF setup?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

xxxxx@dynax.at wrote:

I have a standalone device (musical equipment) which can be configured via USB2. It has two 64 byte bulk endpoints (IN and OUT) in its only configuration and single interface, and only supports power state D0 (well, and OFF of cause).

So, it must be a full speed device, right?

Under W7 after sending the host to sleep (canceling all outstanding I/O if any) and keeping the pipes open, the drivers IRPs to the USB don?t get handled anymore in its EvtDeviceD0Entry. They don?t appear on the USB bus and are not finalised by the stack.

So, your URBs just hang? What are you trying to send in D0Entry? Are
you using WDFUSBDEVICE or are you spinning the URBs by hand? Have you
ensured that there are no outstanding requests from your driver in the
USB stack before you allow shutdown? Does your device need any
particular initialization after power is restored before it is able to
handle requests?

Did you do anything in D0Exit to prepare?

If a work item is scheduled from EvtDeviceD0Entry instead, its possible to send normal USB read/write requests. However an attempt to send either a URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL or its KMDF equivalent WdfUsbTargetPipeResetSynchronously will hang without any activity seen on the USB bus.

WdfUsbTargetPipeResetSynchronously sends URB_FUNCTION_RESET_PIPE. That
is strictly a software request. It cancels outstanding requests and
resets tables in the host controller driver. It does not produce any
bus traffic. You shouldn’t need that in D0Entry. You MIGHT use it in
D0Exit to make sure any request you might have submitted are canceled.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks, Tim,

So, it must be a full speed device, right?

yes, correct.

So, your URBs just hang? What are you trying to send in D0Entry? Are

Actually I only need to send a write request, and scheduled two read requests (but those are asynchronous, and since the other request hangs I am not yet to see if those are issued/handled correctly).
Additionally I test-wise tried to send an ClearFeature(ENDPOINT_HALT), which under a certain OSX version was needed, facilitating a URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL.

you using WDFUSBDEVICE or are you spinning the URBs by hand? Have you

It doesn’t seem to matter in that case, I tried both, using the KMDF framework calls and building the URBs by myself. I am pretty sure my URB building is OK, since they work otherwise, also with other (streaming) devices, so a lot of those are issued, but of course there is always a chance of setting up something wrongly.

ensured that there are no outstanding requests from your driver in the
USB stack before you allow shutdown? Does your device need any

Yes, in this test-case I am sending a URB_FUNCTION_ABORT_PIPE per pipe and seeing that the two scheduled read requests getting canceled, their cancel routines are getting called, it looks all correct to me. In the test-case nothing more should be needed to be done.

But even if I only either use the IN or the OUT pipe I can’t to neither issue an USB request in the d0 entry.

particular initialization after power is restored before it is able to
handle requests?

no, not at the protocol level.

Did you do anything in D0Exit to prepare?
yes, see above. Cancelling the scheduled read requests via URB_FUNCTION_ABORT_PIPE.

WdfUsbTargetPipeResetSynchronously sends URB_FUNCTION_RESET_PIPE. That
is strictly a software request. It cancels outstanding requests and
and that makes it even more suspicious to why it is not finalised. (As you mentioned something probably brought the USB stack in a certain state.)

resets tables in the host controller driver. It does not produce any
bus traffic. You shouldn’t need that in D0Entry. You MIGHT use it in

it was used test-wise instead of a URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL.

D0Exit to make sure any request you might have submitted are canceled.

All request should already get cancelled there…

But is my assumption correct, that the USB stack itself should setup to a state where it was before leaving S0? (i.e. it selects the USB device configuration, interface and provides the pipes, using the old handles my driver is still holding.)

Thanks,
Hagen.

xxxxx@dynax.at wrote:

> particular initialization after power is restored before it is able to
> handle requests?
no, not at the protocol level.

So, there aren’t any vendor commands or register settings or interface
alternate settings required to get you from “just powered on” to “ready
to go”?

But is my assumption correct, that the USB stack itself should setup to a state where it was before leaving S0? (i.e. it selects the USB device configuration, interface and provides the pipes, using the old handles my driver is still holding.)

It should select the configuration. The pipe handles should still be
valid. Interfaces are not interesting to the hardware; they are only a
software convention used to group endpoints. By the time you get to
D0Entry, the stack should be ready to accept requests. Can you do
ANYTHING, like even fetch the descriptors?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks again, Tim,

So, there aren’t any vendor commands or register settings or interface alternate settings required to get you from “just powered on” to “ready to go”?

yes, nothing special is required, it only has a single interface and no alternative setting.

Can you do ANYTHING, like even fetch the descriptors?
I am going to check this. However I was able to retrieve pipe KMDF informations.

thanks,
Hagen.