Resetting USB hub with WinUsb?

Hi All,

Although I have written a WDF driver for our USB data acquisition hardware, we would prefer to have it work with the standard WinUsb driver as this might simplify the transition between various versions of Windows.

Basic WinUsb communication with our board is going fine. But I’m trying to include some emergency reset options for when things go bad on hard to reach systems (eg 170 miles away down a snowy road in Siberia).

The IOCTL_INTERNAL_USB_CYCLE_PORT and IOCTL_INTERNAL_USB_RESET_PORT calls worked well with the WDF driver. But they work from kernel mode and the online docs say the related user mode IOCTL_USB_CYCLE_PORT control code should not be used beyond WinXP.

So, my questions are:

  1. What method would you recommend for cycling and resetting the parent USB hub for a WinUsb device that works for WinXP, Win7-32, and Win7-64?

  2. Do the device and winusb handles remain valid across the cycle/reset or do they have to be closed and reopened?

  3. Are there any docs or code examples showing how to do this?

Any insights you can give would be appreciated!

Thanks, Wendy

Wendy Tucker
Symmetric Research

xxxxx@symres.com wrote:

Basic WinUsb communication with our board is going fine. But I’m trying to include some emergency reset options for when things go bad on hard to reach systems (eg 170 miles away down a snowy road in Siberia).

The IOCTL_INTERNAL_USB_CYCLE_PORT and IOCTL_INTERNAL_USB_RESET_PORT calls worked well with the WDF driver. But they work from kernel mode and the online docs say the related user mode IOCTL_USB_CYCLE_PORT control code should not be used beyond WinXP.

So, my questions are:

  1. What method would you recommend for cycling and resetting the parent USB hub for a WinUsb device that works for WinXP, Win7-32, and Win7-64?

It’s very difficult to provide generic advice on this. When something
goes wrong, you generally don’t know exactly what happened, and without
knowing that, you are just guessing at solutions. Cycling and resetting
the port are not general-purpose solutions. It’s not even clear to me
for what classes of problems you would recommend such a solution.

You can reset the hub by disabling and enabling it. That can be done
with “devcon”. Sometimes, that helps. If you have hardware problems,
it’s not clear there are ANY generic solutions. You can plop a filter
driver on WinUSB to accept a custom ioctl to forward a cycle or reset,
but there’s no guarantee it will help anything.

Have you considered adding a vendor command to the device that forces it
to cycle its own power? Even if endpoints are screwed up, control
endpoint requests usually go through.

  1. Do the device and winusb handles remain valid across the cycle/reset or do they have to be closed and reopened?

Cycling and resetting will cause the device stack to be torn down. Any
existing handles become orphans, no longer connected to hardware.


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

Hi Tim,

Thanks for your answers.

Our hardware is self-powered, so a temporary or partial power loss during a ReadPipe transaction can hang things up. The device can cycle it’s own power on request - but only if the hub can communicate with it, as the firmware expects those requests to come as a bulk transfer over endpoint 1 rather than as a vendor command over EP0.

Closing and reopening the orphaned handles sounds likely to fix the trouble with my current code. And perhaps using the WinUsb SetPipePolicy AUTO_CLEAR_STALL will let my “cycle yourself” requests through too? If not, maybe I’ll try revising the firmware to handle them over EP0.

Thanks again, Wendy

xxxxx@symres.com wrote:

Our hardware is self-powered, so a temporary or partial power loss during a ReadPipe transaction can hang things up. The device can cycle it’s own power on request - but only if the hub can communicate with it, as the firmware expects those requests to come as a bulk transfer over endpoint 1 rather than as a vendor command over EP0.

Out-of-band requests should almost always travel over the control
endpoint, exactly because of situations like this.

Closing and reopening the orphaned handles sounds likely to fix the trouble with my current code. And perhaps using the WinUsb SetPipePolicy AUTO_CLEAR_STALL will let my “cycle yourself” requests through too?

If the pipe is getting stalled, AUTO_CLEAR_STALL will help. Otherwise,
it’s just decorative.


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

Hi Tim,

Earlier you mentioned resetting the hub by disabling and enabling it with “devcon”. This sounds worth trying.

Can I do this by calling SetupDiCallClassInstaller on the correct hub with DIF_PROPERTYCHANGE for a StateChange of DICS_DISABLE and then DICS_ENABLE as shown in the devcon source code?

Also, what is the best way to identify which hub is the parent of my WinUsb device? Querying the device or WinUsb handle somehow or iterating recursively through all the root hubs like UsbView?

Thanks, Wendy

Wendy Tucker
Symmetric Research

Yes, follow the devcon source example for how to disable/enable. For getting the parent, use the DevInst you are given when you query for the device interface (iirc it is another field in the interface detail data struct), and then use cm_get_parent to get the parent devinst, which you can then query the device instance id which you can use with the devcon src

d

debt from my phone


From: xxxxx@symres.com
Sent: 10/25/2011 5:17 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Resetting USB hub with WinUsb?

Hi Tim,

Earlier you mentioned resetting the hub by disabling and enabling it with “devcon”. This sounds worth trying.

Can I do this by calling SetupDiCallClassInstaller on the correct hub with DIF_PROPERTYCHANGE for a StateChange of DICS_DISABLE and then DICS_ENABLE as shown in the devcon source code?

Also, what is the best way to identify which hub is the parent of my WinUsb device? Querying the device or WinUsb handle somehow or iterating recursively through all the root hubs like UsbView?

Thanks, Wendy

Wendy Tucker
Symmetric Research


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

xxxxx@symres.com wrote:

Earlier you mentioned resetting the hub by disabling and enabling it with “devcon”. This sounds worth trying.

Can I do this by calling SetupDiCallClassInstaller on the correct hub with DIF_PROPERTYCHANGE for a StateChange of DICS_DISABLE and then DICS_ENABLE as shown in the devcon source code?

If that’s what “devcon” does, then yes. I’ve never copied that code,
although I’ve copied a lot of other “devcon” code.

Also, what is the best way to identify which hub is the parent of my WinUsb device? Querying the device or WinUsb handle somehow or iterating recursively through all the root hubs like UsbView?

For experimental purposes, you can use Device Manager’s “Devices by
Connection” view, find your device, and look at the Details of the hub
to get the Device ID.

In production, it’s a bit more work. You’d have to look at the source
code for “usbview”. Usbview talks directly to the hubs and asks them
about the ports they hold. You can ask the hub to give you the device
descriptor for a given port.


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

Hi Doron and Tim,

Thanks for your replies. Now I have two possible methods to try.

Doron - Your mention of CM_Get_Parent function was what I needed. While searching through MSDN for its arguments, I came across the page “Obtaining the Parent of a Device in the Device Tree”. The steps it gives sound like what you are describing and should fix me up.

Tim - Using Device Manager’s “Devices by Connection” view will help verify my code is accessing the right hub.

Thanks again for your help!

Best regards, Wendy

Wendy Tucker
Symmetric Research