Hello Experts,
How can I programmatically re-enable a USB device that has gone into an Over-current condition? The Windows utility that pops up during an over current scenario is able to do this with human intervention, but I couldn?t find a mechanism that would help me do the same steps programmatically.
IOCTL_INTERNAL_USB_CYCLE_PORT require a reference to the Hub PDO object which would have been already removed by the PnP manager in response to the Over-current status and was not of any help. I also tried sending PORT_POWER messages to the hub port using a filter driver, which enables the port but does not result in the device getting re-enumerated on Windows.
A forceful re-enumeration by calling IoInvalidateDeviceRelations from the filter driver resulted in the new PDO object being returned by the Hub driver, but the driver stack is not getting build. In device manager I still see a node for the old device, with the error code set to 43. But I can clearly see that the driver stack for the faulty device was removed. I have tried using USB software analyzers to see what?s happening when the system utility resets the device, but couldn?t find anything much apart from the PORT_POWER message being triggered by the hub driver.
This is being done for a closed system that uses Windows XP embedded, and having some programmatic way of re-enumerating the device is a critical requirement for us. Any hints in this regard would be of great help.
Thanks,
Anees
xxxxx@gmail.com wrote:
How can I programmatically re-enable a USB device that has gone into an Over-current condition? The Windows utility that pops up during an over current scenario is able to do this with human intervention, but I couldn?t find a mechanism that would help me do the same steps programmatically.
IOCTL_INTERNAL_USB_CYCLE_PORT require a reference to the Hub PDO object which would have been already removed by the PnP manager in response to the Over-current status and was not of any help. I also tried sending PORT_POWER messages to the hub port using a filter driver, which enables the port but does not result in the device getting re-enumerated on Windows.
The hub PDO cannot go away until all of the devices above it have gone
away. If you still have a living filter driver, then all of the device
objects underneath you must still exist.
A forceful re-enumeration by calling IoInvalidateDeviceRelations from the filter driver resulted in the new PDO object being returned by the Hub driver, but the driver stack is not getting build. In device manager I still see a node for the old device, with the error code set to 43. But I can clearly see that the driver stack for the faulty device was removed. I have tried using USB software analyzers to see what?s happening when the system utility resets the device, but couldn?t find anything much apart from the PORT_POWER message being triggered by the hub driver.
This is being done for a closed system that uses Windows XP embedded, and having some programmatic way of re-enumerating the device is a critical requirement for us. Any hints in this regard would be of great help.
This is a hardware failure. The hub has taken steps to protect itself,
by shutting down, an it shouldn’t be willing to come back up unless
there has been some change in the hardware state (like an
unplug/replug). Otherwise, it’s just going to get in the same state
again. I’m not convinced there is (or SHOULD be) any way to recover
from this in software. It’s like asking if there is a way to reset a
circuit breaker in software.
How are you getting into an over-current situation? That would seem to
indicate a design flaw.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Hi Tim,
Thanks for your response. I think I wrote it wrong as hub PDO. I was actually refering to the hub created device PDO which the IOCTL should target. The hub device stack is still intact.
We are working on a Windows XP embedded devive that uses an external USB hub to connect to third party devices. The explorer shell is disabled on this device, and we are looking for a mechanism to reset the device in case of an overcurrent scenario from our application. On normal Windows we see that there is a USB Utitlity that pops up and provides the user an option to reset the port, after which the port functions properly. But we are not really able to figure out what it does in the background. Using USB analyzers we were able to see a set port power request being send to the hub PDO after which the device re-enumerates. We tried to simulate this, but the device stack is not getting build even after the hub reports the new PDO.
I hope I have made it clear this time. We are trying to see how we can implement a similar reset mechanism as the Windows USB utility does
Thanks again,
Anees
You might want to try sending IOCTL_USB_HUB_CYCLE_PORT to the hub from
user mode. I’m not sure if it will recover the device from overcurrent.
(Also note this IOCTL isn’t available on Vista/7.)
On 4/6/2011 10:37 AM, xxxxx@gmail.com wrote:
Hi Tim,
Thanks for your response. I think I wrote it wrong as hub PDO. I was actually refering to the hub created device PDO which the IOCTL should target. The hub device stack is still intact.
We are working on a Windows XP embedded devive that uses an external USB hub to connect to third party devices. The explorer shell is disabled on this device, and we are looking for a mechanism to reset the device in case of an overcurrent scenario from our application. On normal Windows we see that there is a USB Utitlity that pops up and provides the user an option to reset the port, after which the port functions properly. But we are not really able to figure out what it does in the background. Using USB analyzers we were able to see a set port power request being send to the hub PDO after which the device re-enumerates. We tried to simulate this, but the device stack is not getting build even after the hub reports the new PDO.
I hope I have made it clear this time. We are trying to see how we can implement a similar reset mechanism as the Windows USB utility does
Thanks again,
Anees
Hi
IOCTL_USB_HUB_CYCLE_PORT was the first apparoach that we tried but it failed when the port was in an overcurrent state. I dont remember the exact error code now. Is there a way by which I can figure out what the windows port reset utility does in the background
Thanks,
Anees
Hi,
For the sake of the completeness of this thread, I got it to work by issuing a SET FEATURE (PORT_CURRENT) on the port with the help of a filter driver and then issuing a IOCTL_USB_HUB_CYCLE_PORT, as Philip mentioned, from user mode. No forced re-enumeration is required, the user mode IOCTL results in a new PDO being enumerated by the hub driver.
Thanks,
Anees