Welcome to MSDN Blogs Sign in | Join | Help

List of the latest USB hotfixes for each Windows version

Hello, my name is Don Miller.  I am a software developer on the Windows USB team.  In this post my goal is to provide a USB end-user with a way to view the most recent USB public hotfixes for the below Windows releases:

Windows 2000 Service Pack 4

Windows XP Service Pack 3

Windows 2003 Service Pack 2

Windows Vista Service Pack 2

Windows 7 RTM

As most Windows users know, Microsoft releases public hotfixes for various Windows components after a new Windows version or service pack is released.  A hotfix will contain a fix to a specific problem found in that Windows component.  Multiple hotfixes can occur to the same Windows component over a period of time and it can be confusing to know what fixes have occurred for a specific Windows USB component.   Each Windows hotfix has a version assigned to it in order for the hotfix installer to not install older versions of a Windows USB component over the top of a newer version.  A newer version hotfix will contain all the previous version's fixes meaning that a USB end-user will only have to install the latest hotfix version for a Windows component and have all the fixes done for that Windows component relative to the Windows OS version. 

If a USB end-user is experiencing a USB issue, he/she can look at the below list and see if any of the KB's description of the issue is similar to what he/she is experiencing.  If a KB description matches then a USB end-user can download the hotfix the KB references and see if the issue is resolved.  The below list will list all the public hotfixes to each USB core component in release date order for the above Windows releases.  Note that for best results, for example, if you are running Vista Service Pack 1, you will need to download install Vista Service Pack 2 from http://www.microsoft.com/downloads/en/default.aspx before installing any of the Vista Service Pack 2 hotfixes.  The same recommendation applies to all the other above Windows releases.  Also, the best time to use the below list is when a USB end-user is troubleshooting a USB issue.  If a USB end-user's system is running fine it is recommended that the USB end-user not install any USB hotfixes.

Note: WINUSB.SYS became a Windows inbox driver starting with Vista.

Windows 2000 SP4 Core USB Hotfixes

Last updated:   11/12/2009

BinaryFiles

FinalFixPostedDate

KB #

KB Title

 

USBPORT.SYS

4/28/2003

818129

You Must Restart Your Computer After You Reinstall the USB

 

OPENHCI.SYS

5/13/2003

819895

STOP 0x0000000A Error When Computer Performs Intensive Operations on USB Drives

 

USBEHCI.SYS

5/13/2003

820759

Problems occur when you run a program that accesses a USB 2.0 DVD drive or CD-RW drive

 

OPENHCI.SYS

7/23/2003

823715

Computer Does Not Resume from Standby When You Click a USB Mouse

 

USBEHCI.SYS

9/19/2003

827675

"Unsafe Removal of Device" error message when you use the Safe Hardware Removal tool

 

USB.INF

10/10/2003

829759

USB devices are not detected or use 100 percent CPU time after you apply the hotfix that is described in article 810090

 

USBD.SYS,USBHUB.SYS

5/27/2004

838921

Stop error 0x1E occurs in the Usbhub.sys driver when you install Windows 2000 SP4 from a USB CD drive

 

USBD.SYS,USBHUB.SYS

6/1/2004

838417

Stop error 0x0000001E is logged when you restart the computer to complete the installation of Windows 2000

 

USBPORT.SYS

6/2/2004

838989

A USB device may not be redetected after a power cycle in Windows XP or in Windows 2000

 

OPENHCI.SYS

6/11/2004

843540

Computer stops responding when you shut down Windows 2000

 

USBPORT.SYS

6/16/2004

843503

Computer with an Intel ICH6-based platform may stop responding during DVD playback if a high-speed USB 2.0 storage device is attached and if the computer is running Win 2000

 

 

Windows XP SP3 Core USB Hotfixes

BinaryFiles

FinalFixPostedDate

KB #

KB Title

USBOHCI.SYS

2/27/2008

948101

A USB keyboard does not work after you restart a Windows XP-based computer that has an NVIDIA 680i motherboard installed

USBPORT.SYS

2/28/2008

949764

A USB device no longer works after you resume a Windows XP-based computer from hibernation (S4)

USBCCGP.SYS

4/24/2008

945436

Error message when you try to uninstall or unload the driver for a multifunction USB device on a Windows XP-based computer: "STOP: 0x000000D1 DRIVER_IRQL_NOT_LESS_OR_EQUAL"

USBEHCI.SYS

4/25/2008

949033

You may experience severe video degradation and a Stop error when you connect a USB Webcam to a Windows XP-based computer

USBPORT.SYS

3/19/2009

968764

Streaming USB 1.1 devices that are connected to an external USB 2.0 hub behave incorrectly on a Windows XP-based, Windows Vista-based, or Windows Server 2008-based computer

USBEHCI.SYS

6/9/2009

969238

A data transfer is corrupted when you transfer data from or to a USB device on a computer that is running Windows XP

 

Windows 2003 SP2 Core USB Hotfixes

BinaryFiles

FinalFixPostedDate

KB #

KB Title

USBPORT.SYS

2/21/2007

925528

Stop errors occur on a Windows-based computer that has 2GB or more of RAM and is using an NVIDIA nForce USB controller

USBUHCI.SYS

6/1/2007

938136

Recording quality is poor when you use a USB microphone on a Windows Server 2003-based computer that has 4 GB of RAM or more

USBHUB.SYS

6/12/2007

936641

You do not receive notification when the USB bus is overloaded on a Windows Server 2003-based or a Windows XP Professional x64-based computer

USBEHCI.SYS

6/12/2007

918005

Power consumption may be more than you expect on a computer that is running Windows XP or Windows Server 2003

USBPORT.SYS,USBEHCI.SYS

9/3/2007

908673

Problems may occur when you try to transfer files to or from a device that is connected to a USB 2.0 hub in Windows XP or Windows Vista

USBHUB.SYS

9/19/2007

941716

You do not receive an overcurrent notification when the USB bus becomes overloaded on a computer that is running Windows Server 2003 or Windows XP Professional x64 Edition and that is using an NVIDIA USB controller

USBPORT.SYS

11/14/2007

944704

When you try to shut down or to restart a Windows Server 2003-based computer that has USB devices connected, the computer stops responding and displays a black screen

USBPORT.SYS

3/16/2008

949764

A USB device no longer works after you resume a Windows XP-based computer from hibernation (S4)

USBHUB.SYS

5/16/2008

949483

Stop error when you resume a computer that is running Windows XP or a 64-bit version of Windows Server 2003 from hibernation: "STOP 0x1000007E"

USBEHCI.SYS

7/17/2009

973618

Stop error when a surprise removal of a USB host controller occurs on a computer that is running Windows Server 2003: "Stop 0x00000050"

USBHUB.SYS

7/20/2009

972659

USB devices do not respond when you resume a computer that is running Windows Server 2003 from sleep or hibernation

 

Windows Vista SP2 Core USB Hotfixes

BinaryFiles

FinalFixPostedDate

KB #

KB Title

USBPORT.SYS,USBEHCI.SYS

5/2/2009

968764

Streaming USB 1.1 devices that are connected to an external USB 2.0 hub behave incorrectly on a Windows XP-based, Windows Vista-based, or Windows Server 2008-based computer

USBPORT.SYS

5/22/2009

971171

A computer that is running Windows Vista or Windows Server 2008 restarts automatically and generates a Stop error after you repeatedly plug and hot-unplug a USB device: "0x000000FE"

USBPORT.SYS

6/5/2009

972109

The shutdown process does not finish, and you receive an error message on a computer that is running Windows Vista or Windows Server 2008: "Stop 0x0000009F"

USBPORT.SYS

7/24/2009

972485

USB 2.0 high-speed devices are recognized as full-speed after you hibernate and then resume a computer that is running Windows Vista or Windows Server 2008

 

Windows Vista SP2 WinUSB Hotfixes

BinaryFiles

FinalFixPostedDate

KB #

KB Title

N/A

N/A

N/A

N/A

 

Windows 7 RTM Core USB Hotfixes

BinaryFiles

FinalFixPostedDate

KB #

KB Title

USBHUB.SYS

9/8/2009

974476

The computer stops responding when an USB device resumes from the USB Selective Suspend state in Windows 7 or in Windows Server 2008 R2

USBPORT.SYS

10/26/2009

976972

You encounter problems when you move data over USB from a Windows 7 or Windows Server 2008 R2-based computer that has an NVIDIA USB EHCI chipset and at least 4GB of RAM

 

Windows 7 RTM WinUSB Hotfixes

BinaryFiles

FinalFixPostedDate

KB #

KB Title

WINUSB.SYS

9/11/2009

975599

WinUSB causes a 9F bugcheck - KB coming soon

 

 

Posted by USB Blog | 0 Comments

Why is my USB device not detected or comes up as "Unknown Device"?

Hi, this is Martin Borve from the USB team. In the previous blog, I gave a detailed description on how the device gets enumerated by the core USB stack and reported to the OS. In this post, I'm going to summarize which incorrect hardware behaviors during enumeration causes the core stack to abandon the device and which ones lead to reporting the device as "Unknown Device". 

Device is not enumerated

There are several reasons why a USB device may not enumerate at all when it is attached to a USB port.  Assuming the connect change was detected by the USB hub driver, the following events will cause the device to not be enumerated at all:

  • The USB device failed to stabilize during the debounce period.
  • An overcurrent event occurred during enumeration.
  • A port disconnect event occurred during enumeration.
  • The port is reported as suspended after a successful port reset.

“Unknown Device” in Device Manager due to Enumeration failure

In most cases when enumeration fails the hub driver will still report the arrival of a device to Windows.  In these cases the USB device will appear as “Unknown Device” in Device Manager, and will have a Device ID of “USB\VID_0000&PID_0000” and a Hardware ID and Compatible ID of “USB\UNKNOWN”.   The following events will cause the USB hub driver to enumerate a USB device as an “Unknown Device”:

  • A port reset request timed out during enumeration.
  • The Set Address request for the USB device failed.
  • The request for the USB device’s Device Descriptor request failed.
  • The USB Device Descriptor was malformed and failed validation.
  • The request for the Configuration Descriptor failed.
  • The USB Configuration Descriptor was malformed and failed validation.

On Windows 7, devices that failed enumeration will be marked with failure Code 43 in the device manager. 

On downlevel OS, namely Vista, the device manager may not have a failure code. So the way to detect enumeration failure is to look at the Hardware ID in the detail property page (right click on the device and select Properties and then look click on Details tab) of the device in the device manager. If the ID is USB\VID_0000&PID_0000 then the failure is during enumeration.

“Unknown Device” in Device Manager due to Unavailable driver

There is a second reason why a device would come up as "Unknown Device" in the device manager even if the enumeration was successful. This happens when the device doesn't provide a Product ID string during enumeration and the system is not able to find a matching INF for the device to install a driver. In this case, the device will be marked with failure Code 28 in the device manager.

You may be able to get the driver downloaded and installed from the Windows Update site by right clicking on the device in the device manager and selecting "Update Driver Software" option and then selecting "Search automatically for updated driver software."

Posted by USB Blog | 2 Comments
Filed under:

How does USB stack enumerate a device?

Hello, my name is Martin Borve.  I am a software developer on the Windows USB team.  In this post I will provide a detailed description of the enumeration process used by the Windows 7 core USB driver stack - from the point the stack detects a presence of device to the point it indicates to the PnP manager that a new device has arrived.

Device enumeration for a USB port begins when the hub indicate a connect status change via the hub’s interrupt endpoint.  If the port status indicates a newly connected device, the USB hub driver will use the following sequences of steps to enumerate the device:

  1. Port Stabilization Debounce
  2. First Port Reset
  3. First Device Descriptor Request
  4. Second Port Reset
  5. Set USB Address
  6. Second Device Descriptor Request
  7. Configuration Descriptor Request
  8. MS OS Descriptor Query
  9. Serial Number String Descriptor Query
  10. MS OS Extended Configuration Descriptor Request
  11. MS OS Container ID Descriptor Query
  12. Language ID Query
  13. Product ID String Query
  14. Device Qualifier Descriptor Query
  15. Duplicate Device Detection
  16. Report New Device to PnP Manager

Let us find out in detail how the software stack interacts with the device in each of these steps by describing which hardware events are handled, which ones are ignored, how long the software waits for the next event to occur, when does the software attempt reenumeration, how many times it reattempts, what constitutes a broken device, what leads to enumeration failure, etc.

The steps 1 through 7 are required for the device to be enumerated and reported to the system. In the next blog post, I will summarize all the hardware issues during enumeration that can either cause the software stack to not report the device at all or report to the system as “Unknown Device” by providing  “USB\VID_0000&PID_0000” as the Device ID.

NOTE: Enumeration information provided here applies to 1.1 and 2.0 devices. The sequence and timing of various operations may change for 2.1+ and 3.0+ devices.

Port Stabilization Debounce

The hub driver must observe a period of at least 100ms where there are no port connect changes (USB 2.0 spec, 7.1.7.3, TATTDB).  If the port has not stabilized after 200ms, the hub driver will disable the port and cancel enumeration.  No device will be reported to PnP.

First Port Reset

Once the port debounce has completed successfully, the hub driver will issue a reset request for the port.  In normal operation this will result in the port status transitioning to a connected and enabled state, and the device itself will respond to the default USB address of 0.

Port resets of all USB devices are serialized via an “enumeration lock” on a per host controller basis, as only one USB device can be enabled with the default USB address 0 at a any one time.  The hub driver will acquire the enumeration lock prior to issuing the first port reset request, and will release it when the device has been assigned a non-default USB address, or when enumeration has been cancelled.  The hub driver uses a 5 second timeout for the port reset request in case it never completes.

While waiting for the first port reset to complete, the hub driver must be able to deal with the following events:

Device Disconnect

Enumeration is cancelled.   No device is reported to PnP.

Overcurrent Change

Enumeration is normally cancelled in this case, unless the over-current is determined to be spurious.  No device is reported to PnP.

Timeout of Port Reset

In the case of a timeout of the first reset request, the hub driver will attempt to retry enumeration up to 3 times by returning to the beginning of the “First Port Reset” state.  A delay of 500ms occurs between each retry to allow the device to settle.  If the port reset times out on the 3rd retry, enumeration will be cancelled and an “Unknown Device” will be reported to PnP.

If the port reset request completes successfully, the hub driver will proceed based on the current port state as follows:

Device Disconnected

Enumeration is cancelled.  No device is reported to PnP.

Port Connected and Disabled

Port reset completion is ignored.  Reset timeout will be allowed to run, and port reset will be retried as appropriate.

Port Connected and Suspended

Enumeration is cancelled. No device is reported to PnP.

Port Overcurrent

Port reset completion is ignored. Reset timeout will be allowed to run, and port reset will be retried as appropriate.

Port Enabled and Connected

This indicates a successful reset of the port.  The hub driver delays at least 10ms to allow for reset recovery (USB 2.0 spec, 7.1.7.3, TRSTRCY).  The hub driver moves to the “First Device Descriptor Request" state.   

First Device Descriptor Request

The USB driver stack issues a request for the USB Device Descriptor (GET_DESCRIPTOR for Descriptor Type DEVICE), using the default USB address of 0, and a maximum packet size of 8 bytes for low-speed devices and 64 bytes for full and high-speed devices.

This descriptor request is used solely to determine the correct maximum packet size for the default control endpoint, as specified in the Device Descriptor’s bMaxPacketSize0 field at offset 7.  USB devices are required to return at least the first 8 bytes of the Device Descriptor when they are at the default USB address (USB 2.0 spec, 5.5.3).

When requesting the device descriptor the hub driver will specify a transfer size of 64 bytes.  This is done because some older USB devices will behave badly if the request size is smaller.  We’ve also found some USB devices will babble when returning the device descriptor, but will still return valid data in at least the first 8 bytes.  For this reason transfer errors will be ignored if at least 8 bytes of data were returned by the device. 

If the request for the device descriptor fails, the hub driver will retry enumeration up to three times by returning to the “First Port Reset” state.  If the hub driver has already retried enumeration 3 times, enumeration will be cancelled and an “Unknown Device” will be reported to PnP.

If the device descriptor request succeeds, the hub driver will move to the “Second Port Reset” step.  All further control transfers for the default endpoint will use the maximum packet size specified in the Device Descriptor. 

Second Port Reset

In the early days of USB some USB devices would become confused by a second request for the Device Descriptor if they did not return the complete Device Descriptor for the first request.  To allow these devices to enumerate successfully it was necessary to reset the port between the first and second requests for the Device Descriptor.

The hub driver uses a 5 second timeout for the second port reset request in case it never completes.  While waiting for the second port reset to complete, the hub driver must be able to deal with the following events (this is essentially identical to the handling in the first reset request):

Device Disconnect

Enumeration is cancelled.   No device is reported to PnP.

Overcurrent Change

Enumeration is cancelled.  No device is reported to PnP. 

Timeout of Port Reset

In the case of a timeout of the second reset request, the hub driver will attempt to retry enumeration up to 3 times by returning to the beginning of the “First Port Reset” state.  If the port reset times out on the 3rd retry, enumeration will be cancelled and an “Unknown Device” will be reported to PnP. 

If the port reset request completes successfully, the hub driver will proceed based on the current port state as follows:

Device Disconnected

Enumeration is cancelled.  No device is reported to PnP.

Port Connected and Disabled

Port reset completion is ignored.  Reset timeout will be allowed to run, and port reset will be retried as appropriate.

Port Connected and Suspended

Enumeration is cancelled. No device is reported to PnP.

Port Overcurrent

Port reset completion is ignored. Reset timeout will be allowed to run, and port reset will be retried as appropriate.

Port Enabled and Connected

This indicates a successful reset of the port.  The hub driver delays at least 10ms to allow for reset recovery (USB 2.0 spec, 7.1.7.3, TRSTRCY).  The hub driver moves to the next enumeration state “Set USB Address".  The hub driver will delay 100ms after successfully resetting the port if enumeration had to be retried at least once. 

Set USB Address

The USB driver stack allocates a unique (per-controller) USB device address and issues a SET_ADDRESS request to the device.  If the SET_ADDRESS request fails or times out, enumeration is cancelled and an “Unknown Device” is reported to PnP.

If the SET_ADDRESS is successful, the hub driver will wait for at least 10ms to allow for device stabilization before moving to the “Second Device Descriptor Request” state. 

Second Device Descriptor Request

The USB driver stack will issue a second request for the full USB Device Descriptor (GET_DESCRIPTOR for Descriptor Type DEVICE).  If the request fails or times out, the port is disabled and enumeration is retried by returning to the “First Port Reset” state.  If the hub driver has already retried enumeration 3 times, enumeration is cancelled and an “Unknown Device” is reported to PnP.

Upon successful completion of the second request for the Device Descriptor, the hub driver will validate the Device Descriptor as follows:

  • The bLength field is equal to or greater than the size of a USB Device Descriptor, as defined in the USB 2.0 specification.
  • The bDescriptorType field is equal to descriptor type DEVICE (1).

If the validation fails, the port is disabled and enumeration is retried by returning to the “First Port Reset” state.  If the hub driver has already retried enumeration 3 times, enumeration is cancelled and an “Unknown Device” is reported to PnP.

Upon successful validation of the Device Descriptor, the hub driver will cache the descriptor, release the enumeration lock, and move to the “Configuration Descriptor Request” state. 

Configuration Descriptor Request

The USB driver stack will issue a request for the device’s USB Configuration Descriptor (GET_DESCRIPTOR for Descriptor Type CONFIGURATION).  For compatibility reasons the configuration descriptor request will specify a length of 255 bytes.

If the Configuration Descriptor request completes with an error or times out, the hub driver will disable the port and retry enumeration by returning to the “First Port Reset” state.  If the hub driver has already retried enumeration 3 times, enumeration is cancelled and an “Unknown Device” is reported to PnP.

If the Configuration Descriptor request completes successfully, the hub driver will verify that the number of bytes returned for the request is greater than or equal to the Configuration Descriptor’s wTotalLength value.  If it is not greater than or equal to wTotalLength, the hub driver will retry the Configuration Descriptor request once to insure the device is not returning invalid data in the descriptor.

Upon successful completion of the Configuration Descriptor request, the USB driver stack will validate the descriptor as follows:

  • The bLength field is equal to or greater than the size of a USB Configuration Descriptor, as defined in the USB 2.0 specification.
  • The bDescriptorType field is equal to descriptor type CONFIGURATION (2).

If the validation fails the hub driver will disable the port and retry enumeration by returning to the “First Port Reset” state.  If the hub driver has already retried enumeration 3 times, enumeration is cancelled and an “Unknown Device” is reported to PnP.

If the validation is successful, the Configuration Descriptor is cached and the hub driver moves on to the “MS OS Descriptor Query” state. 

MS OS Descriptor Query

Microsoft has defined a set of vendor specific USB descriptors called Microsoft OS Feature Descriptors, which are queried for at the time of device enumeration. 

If the USB Device Descriptor’s bcdUSB field is equal to 0x0100 or 0x0110, the hub driver will skip the query for the MS OS Descriptor and move to the “Serial Number String Descriptor Query” state.

If the hub driver has never before enumerated a device with the same VID/PID/Revision as the device being enumerated, it will query the device for the MS OS String Descriptor (GET_DESCRIPTOR for Descriptor Type STRING), which uses index 0xEE.  It will specify a language ID of 0x00.

If the device returns an MS OS Descriptor, the hub driver will validate the descriptor as follows:

  • The MicrosoftString field must be equal to “MSFT100”.

Once validated, the value in the descriptor’s bVendorCode field will be stored in the registry on a per VID/PID/Revision basis, under the USBFLAGS registry subkey in the “osvc” registry value.  Subsequent enumerations of any device with the same VID/PID/Revision will read the bVendorCode from this registry value rather than querying the device.
The hub driver will then move to the “Serial Number String Descriptor Query” state. 

Serial Number String Descriptor Query

If the USB Device Descriptor reports a non-zero serial number string index, the hub driver will query for the serial number string descriptor (GET_DESCRIPTOR for Descriptor Type STRING) using the American English language ID (0x409) and the serial number string index.  
The hub driver performs the following validation on all string descriptors:

  • The number of bytes returned for the request must be greater than or equal to the bLength field.
  • The number of bytes returned for the request must be greater than or equal to the bLength field.
  • The bLength field must be larger than 2 bytes.
  • The bDescriptorType field must be equal to descriptor type STRING (3).
  • The bLength field must be an even number, as the string is a Unicode string.

If this validation passes, the hub driver performs the following validation specifically for the serial number string descriptor:

  • The string is non-NULL.
  • The string is not longer than 255 bytes.
  • The descriptor type returned in the descriptor is type STRING.
  • The number of bytes in the string is an even number, as it’s a Unicode string.
  • The string does not contain any invalid characters:
    • The character must have a value greater than or equal to 0x20.
    • The character must have a value less than or equal to 0x7F.
    • The character must not be a comma (‘,’=0x2C).

If any of the above validation fails the serial number will be discarded, otherwise it will be cached.

Regardless of the results of the serial number query and validation, the hub driver will move on to the “MS OS Extended Configuration Descriptor Request” state if the device supports the MS OS Descriptor, otherwise it will move to the “Language ID Query”. 

MS OS Extended Configuration Descriptor Request

If the device is not a composite device the hub driver will issue a request for the MS OS Extended Configuration Descriptor.

Software will issue an initial request for this descriptor by specifying a data size equal to the descriptor’s header.  This will be used to determine the existence of the descriptor, and to determine its size.  If the request is successful the hub driver will validate the header as follows:

  • The returned number of bytes must be equal to the defined size of the header.
  • The binary-coded decimal header version field must be 1.00.
  • The header’s wIndex field must be set to 4.
  • The header’s bCount field must be non-zero.
  • The header’s dwLength field must be equal to the size of the header, plus the value of the bCount field times the size of the configuration descriptor’s function structure.

Once the descriptor header is validated, the hub driver will re-issue the request for the descriptor using the size of the entire descriptor as returned by the device in the descriptor’s header.

If a device successfully returns an MS OS Extended Configuration Descriptor, the hub driver will validate the descriptor as follows:

  • The standard USB configuration descriptor will be parsed for functions described by Interface Association Descriptors and single-interface functions to determine the total number of functions on the device.
  • The following validation will be performed on the MS OS Extended Configuration Descriptor Header:
    • The header’s dwLength value must be greater than or equal to the size of the header structure.
    • The header’s dwLength value must be less than or equal to the size of the header plus 256 Extended Configuration Descriptor functions.
    • The header’s dwLength value must be less than or equal to the number of bytes returned by the device for the descriptor.
    • The header’s wIndex value must equal 4, the MS Extended Configuration Descriptor Index.
    • The header’s bCount value must be less than or equal to the number of functions that were found in the USB Configuration Descriptor.
    • The header’s dwLength value must be greater than or equal to the size of the header structure plus the header’s bCount times the size of the Extended Configuration Descriptor Function structure.
  • The following validation will be performed on each function descriptor:
    • bFirstInterfaceNumber is less than or equal to 256.
    • bFirstInterfaceNumber corresponds to the first interface of a function described by an Interface Association Descriptor or a single-interface function in the device’s USB Configuration Descriptor.
    • The CompatibleID string only contains upper-case ASCII characters(“A”-“Z”), numbers(“0”-“9”), and/or  the underscore character (“_”).
    • The SubCompatibleID string only contains upper-case ASCII characters(“A”-“Z”), numbers(“0”-“9”), and/or  the underscore character (“_”).
    • The number of function descriptors must be equal to the bCount value in the header.

Software will move to the “MS OS Container ID Descriptor Query” state. 

MS OS Container ID Descriptor Query

Windows 7 introduces the concept of a Container ID, which is used to group all functions that are part of a physical device.  For details on how USB generates Container IDs, please refer to this whitepaper.

If the VID/PID/Revision of the device has been previously flagged as not supporting the Container ID Descriptor via the registry, the hub driver will move to the “Language ID Query” state.

If neither the hub descriptor nor the ACPI namespace describes the device as non-removable, and the device supports the MS OS Descriptor, the USB stack will query the device for the MS OS Container ID, otherwise the hub driver will move to the “Language ID Query” state.

A device must indicate support for the container ID by setting bit 1 of the bFlags flag of the MS OS Descriptor.  If this bit is set, software will issue a request for the MS OS Container ID Descriptor header.  The setup packet will specify a wIndex of 6, and the Device as the recipient.  If a descriptor is successfully returned, the hub driver will validate the descriptor as follows:

  • The returned number of bytes must equal the size of the MS OS Container ID Descriptor header.
  • The MS OS Container ID Descriptor header’s bcdVersion must be 0x100.
  • The MS OS Container ID Descriptor header’s wIndex must be 6.
  • The MS OS Container ID Descriptor header’s dwLength must be equal to the size of a MS OS Container ID Descriptor.

If the header is successfully validated, software will issue a request for the entire MS OS Container ID Descriptor.  The setup packet will again specify a wIndex of 6, and the Device as the recipient.

If the descriptor is successfully returned, the hub driver will validate the descriptor as follows:

  • The returned number of bytes is equal to the defined size of the MS OS Container ID Descriptor
  • The Container ID is not all zeros.

If the request for the Container ID Descriptor fails for any reason, a registry value will be set to indicate the hub driver should skip this request in future enumerations of devices with the same VID/PID/Revision.  The hub driver will then disable the port and retry enumeration by returning to the “First Port Reset” state.  If the hub driver has already retried enumeration 3 times, enumeration is cancelled and an “Unknown Device” is reported to PnP. 

Language ID Query

The USB hub driver will query the device for the array of supported language IDs.  The hub driver will issue a query for the string descriptor at index 0, which is an array of 2-byte LANGID codes supported by the device, as defined in section 9.6.7 of the USB 2.0 specification.

The hub driver will perform standard string descriptor validation on the Language ID string descriptor, as described previously in the description of the “Serial Number String Descriptor Query” state.  If the string is found to be valid, the hub driver will cache the data returned in the string.  It will then move to the “Product ID String Query” state. 

Product ID String Query

If the USB Device Descriptor’s iProduct field is non zero the hub driver will issue a request for the Product ID string using the string index specified in the iProduct field and the English language ID of 0x409.

If the string descriptor request completes successfully, the hub driver will perform standard string descriptor validation on the Product ID string descriptor.  If the validation is successful, the hub driver will cache the string. It will then move to the “Device Qualifier Descriptor Query” state. 

Device Qualifier Descriptor Query

If the device is attached to a USB 1.1 hub, is operating at Full-Speed, and its USB Device Descriptor bcdUSB field is greater than or equal to 0x200, the hub driver will issue a GET_DESCRIPTOR for descriptor type DEVICE_QUALIFIER (6). 

The successful completion of the request indicates the device can support USB 2.0 high-speed operation.   

Duplicate Device Detection

The USB driver stack must deal with an artifact of the EHCI companion controller design where a device can move quickly between the USB 2.0 EHCI host controller and a companion USB 1.1 controller when the USB 2.0 controller is enabled or disabled.  This creates a scenario where the new instance of a USB device can be reported to the PnP Manager before its previous instance on the other host controller had been reported as removed to PnP Manager.  This results in a bugcheck if the device has a serial number, as PnP Manager would see two device nodes reporting the same unique instance IDs.  This behavior can also occur when a USB device is moved to a different port while the system is suspended.

The USB hub driver maintains a list of all USB devices currently attached to the system and have been reported to the PnP Manager. If the currently enumerating device has a serial number, software will search this list for any device that has the same vendor ID, product ID, revision number, and serial number.  If no matching device is found, the hub driver will move to the “Report New Device To PnP Manager” state.

If a matching device is found the hub driver will handle it based the following logic:

  1. If the matching device and enumerating device are on the same port, it is a case where the device quickly detached/re-attached (possible a spurious connect change).  No action is taken, as the previous instance will be reported as removed at the same time the new instance is reported as arrived to PnP Manager.
  2. If the matching device is detected as being no longer physically present, software will delay 5 seconds, waiting for the matching device to be reported to PnP Manager as removed.  If the matching device is not reported as removed at the end of the delay, the port is disabled and enumeration is retried by returning to the “First Port Reset” state.  If software has already retried enumeration 3 times, the port is disabled and enumeration is cancelled.  No device will be reported to PnP Manager.
  3. If the matching device is still physically present, it is a case of two identical devices with the same serial number.  In this case the serial number for newly enumerated device will be discarded, to prevent PnP Manager from triggering a bugcheck.

Report New Device to PnP Manager

At this point the USB device has been successfully enumerated and the hub driver will report the new device to PnP.  This involves calling IoInvalidateDeviceRelations and reporting then new device when handling IRP_MN_QUERY_DEVICE_RELATIONS/BusRelations.

Posted by USB Blog | 0 Comments
Filed under:

How can I fix a device that doesn't work after system resume?

Hi, this is Vivek Gupta again from the USB team. In my last post on whether devices get reset on system resume, I talked about how some devices might get negatively impacted by the behavioral changes in USB core stack in Windows7. To make it easier for users to fix such devices, we have extended the new Windows7 device stage troubleshooting functionality. Let us find out how to use the troubleshooter.

This USB Troubleshooter is built on the Windows Troubleshooting Platform. If a user is having a problem with a USB device after the system resumes from sleep, he or she can choose to troubleshoot the device through the Devices and Printers UI (Detailed steps provided at the end). This will invoke our USB Troubleshooter which will, based on some heuristics, put the device on the list of devices that need reset on resume. From that point on, whenever the system resumes from sleep, the device will be always be reset and should start working. It should be noted that the decision to apply the reset behavior on a device is based on a certain heuristic method. Therefore it is recommended that the user should troubleshoot a device only if he or she is actually experiencing problems with the device.

To launch USB Troubleshooter on a device, Open Devices and Printers by clicking the Start button and then, on the start menu, clicking Devices and Printers. Then right-click on the target USB device, and click Troubleshoot. USB Troubleshooter, along with any other applicable device troubleshooters, will automatically get downloaded and launched; wait for the Troubleshooter to finish. When it finishes, it will inform you if it applied the reset on resume behavior change on the device. Note that the system needs to be online and configured to get the latest online troubleshooters. By default, the system should already be configured in this manner. This can be verified by clicking the start button and then, on the start menu, searching and clicking Troubleshooting. On the bottom of the page, the checkbox to get the latest troubleshooters should be set.

Posted by USB Blog | 2 Comments
Filed under: ,

Do USB devices get reset on system sleep resume?

Hi, my name is Vivek Gupta. I am a developer on the USB team. In this article, I am going to discuss a behavioral change introduced in Windows7 USB core stack and how it affects USB devices.

Old behavior: In Vista RTM, when the system resumed from sleep, the USB stack used to reset the host controller, thereby resetting the whole bus. All USB devices went through the process of USB re-enumeration that involves resetting the device and configuring it again. This behavior has certain disadvantages. Since there could be only one device at address 0 at a time, this enumeration has to be serialized for all USB devices on the bus. This significantly increases the time it takes for USB devices to be available after system resume. We have also seen that resetting the host controller can also lead to an illegal SE1 signal state on some host controllers, which in turn can cause some USB devices to hang or drop off the bus. Moreover, devices cannot maintain any private state across sleep resume as that state will be lost on reset.

New behavior: Because of these disadvantages, it was decided to change the stack behavior so as to not do the bus wide reset on system resume, except in some special circumstances. In Vista SP1, the new behavior was implemented but was configurable by OEMs and most of the OEMs chose the old behavior. In Windows7, the requirement to support the new behavior was hardened. Consequently USB devices in Windows7 will not be reset on system resume, unless the device lost power during sleep cycle.

Testing devices for new behavior: Therefore it is very important that IHVs and OEMs should test their devices for the new stack behavior, in addition to the old behavior. One thing to note is that on upgrade from Vista SP1 to Windows7, the old behavior is maintained. So if a system was configured for bus wide reset on Vista SP1, it will still be configured to do the bus reset after the upgrade. Therefore for testing the new behavior, the system should have a clean install of Windows7. The device should be tested on resume from S3 as well as resume from hibernation. When I say device should be tested, I mean testing the actual end-to-end functionality of the device. Looking at just the PNP state of the device is not sufficient; we have seen cases where the device is not operational even though the device manager does not report a problem. We have also seen devices where their control endpoint is working after system resume but their other endpoints are not - therefore devices should be thoroughly tested after sleep resume cycle. Also note that even though the new behavior allows devices to maintain private state across sleep resume, devices (and their drivers) should use any such state only as an optimization and should always be able to deal with the loss of that state.

Existing devices needing reset: Even though the new behavior will be good for the ecosystem in the long term, it might have a negative impact on a small set of existing devices that have started depending on always getting a reset on system resume. In our extensive testing, we have found only a handful of such devices. These devices might stop working after system resumes from sleep and will only start working after user plugs them out and plugs them back in. To work around this problem, the USB stack maintains a list of such devices i.e. devices that are known to not work on system resume without a reset. These devices are selectively reset on system resume. But we do realize that this list may not be exhaustive; there might be devices that are not on the list but require a reset on system resume. To provide a way to mitigate the effect of this behavior on user experience, we just released the first version of USB Troubleshooter. I will talk about it more in my next post.

Posted by USB Blog | 1 Comments
Filed under: ,

What's the difference between USBSAMP and OSRUSBFX2 sample?

Hi, this is Qiang Qiu again from USB core test team. Last week, I wrote about how to get started with USB driver development and gave an overview of highly used samples in the WDK. In this article, I'm going to list out the features side-by-side of two most important KMDF based USB samples, namely USBSAMP and OSRUSBFX2. My hope is that this will enable you to decide which sample to follow as a reference for your driver development.  I have listed couple of frequently asked questions about these samples at the end of this article.

Features

USBSAMP Sample

OSRUSBFX2 Sample

Test Board Hardware

Intel 82930 USB Test Board

Vendor ID: 0x045E

Product ID: 0x930A


(Note: OSR USB-Fx2 Learning Kit can also be used for USBSAMP driver just to do the loop read and write operations )

OSR USB-FX2 Learning Kit

Vendor ID: 0x0547

Product ID: 0x1002

Test Board Configuration

The board supports a single configuration and can operate at high-speed and full-speed mode. It implements one interface.  Two endpoints can be configured as internal loopback function for bulk transfer. Two endpoints can be configured as an internal loopback function to perform isochronous transfer.

The board supports a single configuration and can operate at high-speed and full-speed mode. It implements Interface 0 with three endpoints (Interrupt IN - Endpoint 1, Bulk Out - Endpoint 6, Bulk IN - Endpoint 8).

Endpoint 1 is used to indicate the state of the 8-switch pack on the OSR USB-FX2 board. Endpoints 6 and 8 perform an internal loop-back function. Data which is sent to EP6 and returned to EP8.

(Note: The bulk endpoints are DOUBLE buffered. Read data will not complete if the buffers are empty. If buffers are full, write data will not complete until the buffers are emptied.)

Support Control Transfer

Yes

Yes

Support Bulk Transfer

Yes

Yes

Support Interrupt Transfer

No

Yes

Support Isochronous Transfer

Yes

No

Support for wait-wake and Selective Suspend

Yes, Test Board will enter suspend after 10 seconds idle.

Yes, Test Board will enter suspend after 10 seconds idle.

Support additional IOCTL

IOCTL_USBSAMP_RESET_PIPE
IOCTL_USBSAMP_GET_CONFIG_DESCRIPTOR
IOCTL_USBSAMP_RESET_DEVICE

IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR
IOCTL_OSRUSBFX2_RESET_DEVICE IOCTL_OSRUSBFX2_REENUMERATE_DEVICE
IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY
IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY
IOCTL_OSRUSBFX2_READ_SWITCHES
IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY
IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY
IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE

Support ETW Events

No

Yes, the sample driver package includes an osrusbfx2.man file which describes events that added: Failure during the add device routine; Failure to start the OSF device on a USB 1.1 controller; Invocation of the "re-enumerate device" IOCTL. There are also read/write start/stop events that can be used to measure the time taken.

Support vendor command

No

The firmware on the test board supports vendor commands to query or set LED Bar graph display, 7-segment LED display, and query toggle switch states.

Console Application

The Usbsamp.exe console application is used to initiate read and write bulk/isoch transfers, send ioctl requests, and obtain a dump of information on the device's endpoints.

The Osrusbfx2.exe console application is used to initiate read and write to bulk endpoints, play with 7 segment display, toggle switches and bar graph display, reset and re-enumerate the device and dump descriptors.

Testing with console application

Usage for usbsamp.exe:

-r [n] where n is number of bytes to read
-w [n] where n is number of bytes to write
-c [n] where n is number of iterations (default = 1)
-i [s] where s is the input pipe
-o [s] where s is the output pipe
-v verbose -- dumps read data
-u to dump USB configuration and pipe info

One interesting feature of this sample is that it enables the application to pick the pipes it wants to use for I/O operations.  For example,

Usbsamp.exe -w 1024 -o pipe03 -r 1024 -i pipe02 <- This command first writes 1024 bytes of data to pipe3 and  reads 1024 bytes of data from pipe02.

If you don't specify the pipe name, the application uses default input pipe name as "PIPE00" and out pipe name as "PIPE01". Pipe name is appended to the device-path when the application opens a handle to the device. The driver receives this string as fileobject name in the create callback. It then parses out the pipe number, finds the corresponding pipe-handle and saves it in the fileobject context to be used during I/O.

Usage for osrusbfx2.exe:

-r [n] where n is number of bytes to read
-w [n] where n is number of bytes to write
-c [n] where n is number of iterations (default = 1)
-v verbose -- dumps read data
-p to control bar LEDs, seven segment, and dip switch
-a to perform asynchronous I/O
-u to dump USB configuration and pipe info

-Osrusbfx2.exe -p option 1-11 allows to set and clear bar graph display, set and get seven segment state, read the toggle switch states, reset and reenumerate the device:

 1- Light Bar
2- Clear Bar
3- Light entire Bar graph
4- Clear entire Bar graph
5- Get bar graph state
6- Get Switch state
7- Get Switch Interrupt Message
8- Get 7 segment state
9- Set 7 segment state
10- Reset the device
11- Reenumerate the device

Windows Support

Windows 2000 and later

Windows 2000 and later

 

FAQ: 

Question: What is Maximum Transfer Size of USBSAMP and OSRUSBFX2 sample driver? Is it possible to change their sizes?

Answer: Technically, from the device point of view, you could submit reads of any size. For writes, you can also submit larger as long as the reads are submitted before the writes complete, otherwise the writes will block as device NAKs when its buffer is full.

The maximum transfer size of USBSAMP is set by 65536 because it was originally designed with the i82930 test board's which is limited by a 64KB circular buffer. You can change the size of "MaximumTransferSize" for your device in usbsamp.inf as below and rebuild your driver package.

[usbsamp.AddReg]

HKR,"Parameters","MaximumTransferSize",0x10001,65536

The maximum transfer size of OSRUSBFX2 is also 65536 (64*1024). It is set in the file orusbfx2.h:

#define TEST_BOARD_TRANSFER_BUFFER_SIZE (64*1024)

You can change this value as you expected.

Question: What I/O types are supported in USBSAMP? How do I change the I/O types? Is bulk and isochronous transfer supported in both direct and buffered I/O types in this sample?

Answer: There is a compile switch "-DBUFFERED_READ_WRITE = 1" for buffered I/O in USBSAMP's build source file as below:

C_DEFINES= $(C_DEFINES)

#-DBUFFERED_READ_WRITE=1

It is commented out so that USBSAMP is doing direct I/O for Reads and Writes by default. Developer can uncomment this switch to do buffered I/O for Reads and Writes.

Please NOTE that USBSAMP can do isochronous transfer only if the I/O type is set as direct I/O in this sample.

Posted by USB Blog | 0 Comments

Getting Started with USB Driver Development

Hi, my name is Qiang Qiu. I work for USB core test team. I write USB device drivers and services to test USB core stack with DSF simulated EHCI controller, hub and different types of devices. I enjoy working on device drivers. In this article, I'm going to provide a roadmap to getting started with USB driver development.

1. Obtain and Install the latest WDK and debugging tools

To build a driver, you must install WDK which contains the resources, libraries, tools, documentation that you need to develop WDF driver. Go to WHDC web site to obtain and install latest version of WDK and debugging tools.

To debug WDM and KMDF kernel drivers, two computers are needed: One to host the debugger and another to host the driver that is being debugged. This page will tell you how to setup kernel mode debug environment.

To debug UMDF drivers, the debugger and driver can be run either on the same computer or on two separate computers. This page will tell you how to setup user mode debug environment.

2. Choose which framework to use for your driver: WinUSB, UMDF, KMDF or WDM

There are several different ways to interact with a USB device. You can either write your own driver or use Microsoft provided generic USB driver called WinUSB.

WinUSB includes the WinUSB kernel-mode driver winusb.sys, which is an integral part of WDF user-mode driver framework (UMDF) support for USB drivers, and the WinUSB user-mode dynamic link library Winusb.dll. For USB devices that are accessed by only a single application, developers can often install WinUsb.sys as their device's function driver instead of implementing a custom driver. If you manage your device with user-mode software, WinUSB will cost you less time, effort and expense devoted to driver development. Driver with WinUSB is likely to cause less system errors which improve the customer experience, is easier to manage power, brings less security threat because user mode driver can not sniff data at kernel level, and is easier and smaller to update driver package. WinUSB would be the easiest and best approach except if your driver want to do data streaming through isochronous endpoints or the functions you want to implement already have kernel-mode support in the Windows operating system (such as modem functions which is supported by TAPI or LAN functions which is supported by NDIS).

The new Windows Driver Framework provides User-Mode Driver Framework (UMDF) library for user mode driver development and Kernel-Mode Driver Framework (KMDF) library for kernel mode driver development. UMDF and KMDF implement the same conceptual driver programming model with different components, device driver interfaces (DDIs), and data structures.

If the WinUSB driver can not meet your driver requirement, try UMDF next. UMDF provides a unified model that can work across device classes and integrates tasks handling for installation, Plug and Play (PnP) and power management. It supports protocol device classes such as cameras and portable music players.

KMDF should be used only if UMDF or WinUSB don't solve your purpose. KMDF framework is a library communicating with the operating system by using WDM interfaces. It provides interfaces simpler than WDM interface and handles many operations such as Plug and Play (PnP) and power management that must be handled by WDM drivers themselves. It also provides much of the synchronization code that is required for multiprocessor environments.

There is a common misunderstanding that miniport drivers such as NDIS or AVSTREAM cannot be written using KMDF. This WinHEC presenation provides more detail on how to use KMDF in miniports. Using KMDF provided USB I/O Target interfaces to interact with your USB device from an NDIS or AVSTREAM miniport is the best way to create a simple, robust driver.

WDM driver uses a set of interfaces to communicate directly with kernel-mode Windows components such as I/O manager and the Plug and Play (PnP) manager. WDM drivers are difficult to write, complex, less robust, and should not be written unless absolutely necessary.

This page will further help you choose a driver model based on the device class.

3. Check system requirements for your driver

You can develop WinUSB and UMDF drivers for Windows XP and later versions of Windows (not including Windows Server 2003). You can develop and build KMDF drivers for Windows 2000 with Service Pack 4 and later versions of Windows. You can develop WDM drivers for any version of Windows.

4. Obtain a test device

  • In most cases, the developer for a new driver will be given a device and/or a specification for a device and told to write a driver for it. If the device is just in prototype development phase, it will be helpful to use below Device Simulation Framework (DSF) to build a simulator following the specification for development and testing purposes.
  • OSR Learning Kits has all the required hardware specifications to implement a driver. It can be obtained from http://www.osronline.com/. OSR Learning Kits is the best actual hardware to study USB samples in WDK.
  • You can use the Device Simulation Framework (DSF) which is a part of WDK for USB Devices to test your driver (Choose install it during WDK installation). DSF only uses software to simulate USB devices, so that you do not need any special hardware. DSF has already created some sample USB Device Simulators such as HID Generic Device, Loopback Device, Audio Device and Keyboard Device. You can use them directly if you install DSF on your computer. There is an instruction to guide you to test your USB driver with a USB Device Simulator.

5. Reference samples from the WDK

  • WinUSB Samples

The most comprehensive documentation for how to use WinUSB to access a USB device is this whitepaper "How to USB WinUSB to communication with a USB Device". For sample code, refer below UMDF Fx2_Driver sample.

UMDF Driver Skeleton Sample: This sample demonstrates how to use UMDF to write a basic driver. It is a starting point for implementing a function driver.

Fx2_Driver: This sample demonstrates how to use UMDF to create a driver to perform bulk and interrupt data transfers with OSR USB Fx2 Learning Kit.

  • KMDF Samples

OSRUSBFX2: This sample is a step by step tutorial to demonstrate how to create a KMDF driver to perform bulk and interrupt data transfers to an USB device with OSR USB Fx2 Learning Kit. If you are new to KMDF driver, this sample is the best one to start with.

USBSAMP: This sample demonstrates how to perform bulk and isochronous data transfers to a generic USB device.

In the next blog post, I will describe the difference between OSRUSBFX2 and USBSAMP samples.

HIDUSBFX2: This sample demonstrates how to write a HID minidriver in which a non-HID USB device is mapped to a HID device.

Toaster -WDF Version: This sample is a rewrite of the WDM toaster driver and is great starting point for understanding KMDF. It illustrate the functionality for bus driver, function driver and filter drivers for a hypothetical bus and its devices.

  • WDM Samples

Toaster - WDM Version: This sample demonstrates how to write a bus driver, a function driver, assorted class, device and bus filter drivers, a class installer, and a device-specific co-installer for a hypothetical bus and its devices.

USBView Sample Application: This sample provides a GUI application to browse all connected controllers and USB devices on your computer. It is able to dump USB device's descriptors, query information about the devices from the registry via USB requests to the device. This is a useful tool but not a driver sample. 

We STONGLY DISCOURAGE you from using WDM Isochronous client driver sample (isousb.sys), Bulk transfer client driver sample (bulkusb.sys) and Selective suspend client driver sample (selsusp.sys) from old WDKs. These samples do not exist in the latest Windows 7 WDK installation package.

Posted by USB Blog | 3 Comments

Why doesn't my driver unload?

Hi, my name is Eliyas Yakub. After working on the Windows Driver Framework product for about 6 years as an SDE and development lead, I recently took up the development lead responsibility for bus connectivity technologies such as USB and 1394.  This is my new team blog where I and my team members from all disciplines (Dev, QA, PM) will try to provide useful insight about technologies we own, insight into the working of core drivers for these technologies, common driver and hardware issues we encounter, and general client driver development tips and tricks.

In this article, I want to discuss why drivers fail to unload. Failure to unload a driver leads to poor user-experience because the system needs to be rebooted either to update the driver or to make the device functional if the user plugs the device again. At the bottom of this article, I have pointer to other articles that describe how to avoid system reboots. Here, I'm want to provide insight into how the OS unloads a driver and what would prevent a driver from unloading.

Developers generally assume that if the DriverUnload routine is called then the driver-unload process is complete and driver should have unloaded. This is not true. Invocation of DriverUnload routine and the unloading of driver-image from memory is a two separate process governed by different factors in the system. In the first step, the system makes an attempt to unload the driver by calling the registered DriverObject->DriverUnload routine. When the DriverUnload routine returns, the system drops the final reference on the driverobject to trigger unloading of driver-image from memory.

So for a driver image to unload two things need to happen:

  1. Some entity in the system (service control manager (SC), I/O or PnP-manager subsystem or another driver in kernel-mode) needs to first make an attempt to unload the driver. When that happens and if there are no open handles to any of the deviceobjects created by the driver, the system calls the registered DriverUnload routine.
  2. When all the deviceobjects are deleted and the reference count of the driverobject drops to zero, the memory-manager then unloads the image from memory.

So deleting deviceobjects is key to get getting driver-unload to succeed. To understand the mistakes that prevent driver unload, let me categorize device drivers, based on when and how deviceobjects are created, into 3 types:  legacy driver, pure pnp driver, and hybrid driver:

  • In the case of legacy driver, the deviceobjects are created either in the DriverEntry routine or in an ioctl handler. These deviceobjects are deleted either in the ioctl handler or finally in the DriverUnload routine. This is how original NT drivers were written before the invention of PnP.
  • In the case of pure pnp-driver, the driver creates a deviceobject in its AddDevice routine for every new instance of a physical device, and deletes the object before it completes the IRP_MN_REMOVE_DEVICE Irp (aka remove request).
  • In the hybrid case, the driver creates a deviceobject for every instance of the physical device but then it also creates one or more deviceobjects on the side. We call these deviceobjects control or sideband objects. There are used to have sideband communication from application directly with the driver - bypassing all the other driver stacks attached above. An example of hybrid driver is pnpdtest filter driver (availabe in the WDK and WLK) used to test pnp-drivers where the test apps sends ioctl commands directly to the filter layered in the stack to drive the test.

Let us understand how these 3 types of drivers unload:

  • If the driver is a legacy driver then a client of the driver (typically user-mode process calling SC) must explicitly make an attempt to unload the driver. If there are no open handles to any deviceobjects created by the driver, then the system will call driver's DriverUnload routine to get the driver to delete all the deviceobjects. After the unload routine returns, system will drop the reference it has taken on the driverobject. If there are no more references on the driverobject then the driver image gets unloaded from memory.
  • If the driver is a pnp driver then every time a device is removed (removal of a device is triggered by unplugging the device, disabling the device in the device manager) and if there are no handles to the device, the pnp-manager will send remove request to the stack. When that request completes, the pnp-manager will check to see if there are still deviceobjects dangling from driverobject. If there aren't any then it assumes all the devices are removed and makes an attempt to unload the driver. The driverobject could have other deviceobjects if there are other instances of the devices serviced by this driver or the deviceobject that was deleted has extra, probably leaked references on it. In the case of pnp-driver, the unload routine doesn't have any device-object to delete - unlike legacy driver.  After the unload routine returns, if there are no more references on  the driverobject then the driver image gets unloaded from memory.
  • Since a hybrid driver is also a pnp-driver, when the pnp-stack is removed as described above, the pnp manager will look to see if there is any dangling deviceobject. If the control-deviceobjects aren't deleted prior to completing the remove request, there will be one or more dangling deviceobjects. As a result, the pnp manager will skip the attempt to unload the driver. This will lead to a wedged (stuck) driver in image. This driver cannot be ever unloaded again - even from usermode using SC. The reason for that is that SC doesn't call unload if the driver is a pnp-driver. It figures out a driver is pnp or not by checking whether AddDevice routine is registered. This is one of the most common driver unload issues.

Quite a number of you write such hybrid drivers, especially in stacks where the upper drivers don't allow unknown ioctls to pass-down (e.g keyboard class driver). Windows 7 WDK contains a filter sample (both in WDM and KMDF) as part of toaster package that shows to safely handle this situation. Since KMDF has made it easy to write a bus driver, we suggest even a simpler solution to have sideband communication. That is by enumerating a child-device for every pnp-device your driver attaches to. This enables you to have to one-to-one sideband communication relationship with the pnp device. This technique is also illustrated in another sample (kbfiltr) in the WDK.

Application, services and other kernel-mode clients failing to close handle to the device when the device is being removed is another common source of driver unload problem. Whenever a client opens a handle to a pnp device, it should register for pnp notification and close the handle when the system notifies the device is being removed. There are samples in the WDK that shows how to do from an application, service and a device driver. 

  1. Notify sample (src\general\toaster\exe\notify) demonstrates how to write a pnp-aware application.
  2. Toastmon sample, found under toaster\wdm and toaster\kmdf folders, shows how to be pnp-aware driver.
  3. I didn't find sample on how to do this in a service either in WDK or SDK. There is a brief description of this in "Programming the Windows Driver Model" book by Walter Oney.

Let me briefly touch upon some debugging techniques to root-cause driver unload problem. 

  1. !devhandle <deviceobject address>  - this command walks through every process handle table to find out whether any file handle refers to this deviceobect.
  2. To tracked leaked references on the driver and deviceobject, you can follow the technique outlined in the WinDBG documentation, "Advanced Debugging" chapter - Debugging a Failed Driver Unload.
  3. !obtrace  <object address> - this new command shows stacks traces recorded by the system when a reference is added or removed. You need to enable object tracing using gflags utility. Read this section to learn more about how to use gflags.exe. For example, to use gflags.exe for a device object with permanent traces enabled do (leave out the -p if you don't want permanent traces - these stay in memory until the next reboot so use temporary traces if possible): gflags -ko -t Devi -p

Summary

List of primary reasons for a driver to fail to unload:

  1. Application, service or another driver in the system fails (doesn't close in a timely manner) to close the handle to a device.
  2. Driver fails to delete the deviceobject.
  3. Driver leaks references on the deviceobject or driverobject.

List of rules to remember when trouble shooting a driver unload issue:

  1. Driver must have registered an unload routine.
  2. All handles must be closed before system can make an attempt to unload a driver.
  3. All deviceobject must be deleted and extra references dropped before unload-routine of a pnp-driver can be called.
  4. The fact that unload-routine is called doesn't mean the driver unload is successful.
  5. For a driver to be unloaded from memory, there shouldn't be any dangling references to driverobject. There are DDIs that take explicit reference (e.g IoRegisterPlugAndPlayNotification) on the driver-object. If you forget to call the complementary function, you driver-image will be stuck even though the unload routine was called.

 More information to avoid reboots during driver install:

Posted by USB Blog | 1 Comments
Filed under:

Introduction to the Microsoft Windows USB Core Team Blog

 

Introduction to our team

 

Hello and welcome to the Microsoft Windows USB core team blog. Microsoft Windows USB core team has the mission to design, develop and test the software stack that drives the USB Host Controllers and USB Hubs present on the Windows PC.  This software stack helps the Client Device driver software in discovering and driving their devices.

 

Our team has also contributed and continues to contribute in defining Industry standards like the USB 1.1/2.0/3.0 specifications and the Host Controller standards like the EHCI,OHCI,XHCI specifications.

 

Our team owns the following components that many of our readers might be familiar with:

·         USB miniports – USBEHCI, USBUHCI, USBOHCI. These drivers interface with the corresponding host controllers.

·         USBPORT driver

·         USBHUB driver – Drives the USB Hubs

·         USBCCGP – Common Composite Generic Parent Driver that drives a USB Composite device as a whole

·         USBUI – User Interface for USB

·         USB WDK Samples

·         WinUSB

What to expect in the future

 

In this blog various members of the USB Core team might blog about the following in future:

  • Common USB hardware issues we have found.
  • Common driver bugs we see in the USB client driver
  • What is new about USB samples in Windows7
  •  What are the common issues involved in programming Isochronous Devices
  • Information on Selective Suspend in the USB Stac
  • Insight into the workings of the HUB and Port driver
  •  USBCCGP - What is this ? What does it do ? 
  • Information on USB Logo tests
  • Information on  USB INF files, Information on USB User interface.
  • Summary of various USB QFEs we have released for the various OSes.

 

We look forward to your feedback on our posts and any suggestions on what you might want to see from us in future.

 

Windows USB Core Team

 

 

 Disclaimer : This blog does not replace official MSDN documentation from Microsoft regarding USB support in windows. Please continue to read and provide feedback on the official Microsoft resources  for Windows USB driver developers

.

Posted by USB Blog | 3 Comments
Filed under: , , ,
 
Page view tracker