USB Client Driver Tips And Tricks Part Two
USB Client Driver Tips And Tricks: Part Two Jason Kace WDEG – USB Core Team 1 © 2003 Microsoft Corporation. All rights reserved.
Agenda Part Two Tips and tricks you may not already know § USB Transfer sizes § Device configuration tips § Recommended URB error recovery steps § Working with isochronous transfers § USB power management tips § Limitations of composite device support § XP selective suspend rules summary Common driver errors § Common URB/IRP handling errors Tips on debugging common USB problems § Bugcheck FE § Device fails to start (Code 10) 2 © 2003 Microsoft Corporation. All rights reserved.
USB Transfers What is a USB Transfer Struct § § URB_BULK_OR_INTERRUPT_TRANSFER { Bulk Interrupt Isochronous Control USB Transfer. Buffer § § All Buffers should be allocated from the nonpaged pool. Not necessary to create a MDL USB Pipes § § One pipe for each open endpoint SELECT_CONFIGURATION or SELECT_INTERFACE requests return a Pipe. Handle. Urb. Link field must be NULL!!! struct _URB_HEADER Hdr; USBD_PIPE_HANDLE Pipe. Handle; ULONG Transfer. Flags; ULONG Transfer. Buffer. Length; PVOID Transfer. Buffer; PMDL Transfer. Buffer. MDL; struct _URB *Urb. Link; … }; 3 © 2003 Microsoft Corporation. All rights reserved.
USB Maximum Transfer Sizes For Windows 2000 Transfer Type Maximum. Transfer. Size Error Reported Control Endpoint 0 4 k Error Control (Other Endpoints) 64 K Undetermined Interrupt Unlimited None UHCI Bulk Unlimited None OHCI Bulk Effectively Unlimited(See note below) None EHCI Bulk Comments § Drivers should be aware of performance and resource trade-offs when using large transfer sizes. § Use of very large bulk or interrupt transfers are not recommended due to resource limitations exposed by the OHCI driver. § Requests on the default control endpoint are limited to 4 k for compatibility with older driver versions. The USB Specification limits other control transfers to 64 k. 4 © 2003 Microsoft Corporation. All rights reserved.
USB Maximum Transfer Sizes For Windows XP And Later Transfer Type Maximum. Transfer. Size Error Reported Control Endpoint 0 4 k Error Control (Other Endpoints) 64 K Undetermined Interrupt Unlimited None UHCI Bulk Unlimited None OHCI Bulk 256 k Bugcheck 0 x. FE EHCI Bulk 4 MB Bugcheck 0 x. FE Comments § § Table represents theoretical limits, not practical limits Drivers should be aware of performance and resource trade-offs when using large transfer sizes. Use of very large transfers is not recommended Requests on the default control endpoint are limited to 4 k for compatibility with older driver versions. The USB Specification limits other control transfers to 64 k. 5 © 2003 Microsoft Corporation. All rights reserved.
Using The Maximum. Transfer. Size Field Used with the following URB requests: § SELECT_CONFIGURATION § SELECT_INTERFACE struct USBD_PIPE_INFORMATION { USHORT Maximum. Packet. Size ; The Maximum. Transfer. Size Field: Version Input Output Error UCHAR Endpoint. Address ; UCHAR Interval ; USBD_PIPE_TYPE Pipe. Type Windows 2000 Required None Windows XP, Server 2003 Not Used None Longhorn Not Used USBD_PIPE_HANDLE Pipe. Handle ; ULONG Maximum. Transfer. Size ; . . . Maximum Transfer Size allowed TBD } 6 © 2003 Microsoft Corporation. All rights reserved.
Device Configuration Tips Selecting a configuration that requires more power than the port can provide may result in the device being removed USBD_PF_CHANGE_MAX_PACKET pipe flag § § Not needed to set the Maximum. Transfer. Size for a pipe. Used only to override the Maximum. Packet. Size indicated in the USB_ENDPOINT_DESCRIPTOR URB_FUNCTION_SELECT_INTERFACE § § Can be used to set the Maximum. Transfer. Size of Maximum. Packet. Size for a pipe. Can be used to enable alternate interface settings Composite Devices § Setting the Maximum. Transfer. Size in Windows 2000: The parent driver will automatically set the transfer size to 4 k. Drivers may not set this field. § Setting the Maximum. Transfer. Size in Windows XP and Later: Driver may set the Maximum. Transfer. Size via a SELECT_CONFIGURATION or SELECT_INTERFACE request. 7 © 2003 Microsoft Corporation. All rights reserved.
Working With Isochronous Transfers 2 Methods to send Iso transfers struct URB_ISOCH_TRANSFER{ 1. Set the Start. Frame manually struct _URB_HEADER Hdr; 2. Let the bus driver schedule the transfer as soon as possible by setting the USBD_START_ISO_TRANSFER_ ASAP flag struct USBD_ISO_PACKET_DESCRIPTOR { ULONG Offset ; ULONG Length ; USBD_STATUS Status ; } USBD_PIPE_HANDLE Pipe. Handle; ULONG Transfer. Flags; ULONG Transfer. Buffer. Length; PVOID Transfer. Buffer; PMDL Transfer. Buffer. MDL; ULONG Start. Frame; ULONG Number. Of. Packets; ULONG Error. Count; USBD_ISO_PACKET_DESCRIPTOR Packet[1]; } 8 © 2003 Microsoft Corporation. All rights reserved.
Setting The Start. Frame Manually For Windows XP and later, if the start frame is not within +/USBD_ISO_START_FRAME_RANGE of the current frame the URB will fail with USBD_STATUS_BAD_START_FRAME For Windows XP and later, individual ISO packets will be returned with USBD_STATUS_ISO_NOT_ACCESSED_LATE if they could not be scheduled as indicated by the start frame. For Windows 2000 this behavior varies by controller flavor 9 © 2003 Microsoft Corporation. All rights reserved.
Using The USBD_START_ISO_TRANSFER_ASAP Flag For Windows XP Microsoft Windows XP Isochronous Transfer Code Example (Not Actual Code) on the right Dispatch. Isoch. Transfer. URB { If( FLAG(USBD_START_ISO_TRANSFER_ASAP) ) { if (endpoint->state == ENDPOINT_FIRST_USE) { The problem occurs when the following conditions are met Start. Frame = Current. Frame + DEFAULT_LATENCY; } 1. transfer URB using the USBD_START_ISO_TRANSFER_A SAP 2. The endpoint has been used with the USBD_START_ISO_TRANSFER_A SAP flag since the last reset else { Start. Frame = endpoint->Next. Transfer. Start. Frame; if (ABS((Current. Frame - Start. Frame)) > 256) { Start. Frame = Current. Frame + DEFAULT_LATENCY; } } endpoint->Next. Transfer. Start. Frame = Start. Frame + Frame. Count One of Two Problems will Occur 1. The URB arrives more than 256 frames too early 2. URB arrives late, but less than 256 frames too late } else{ Start. Frame = Urb->Start. Frame; } Queue. Urb(Start. Frame, Urb); return STATUS_PENDING; } 10 © 2003 Microsoft Corporation. All rights reserved.
Using The USBD_START_ISO_TRANSFER_ASAP Flag For Windows XP Dispatch. Isoch. Transfer. URB { Problem: URB arrives more than 256 frames earlier than scheduled. Sequence: 1. First URB arrives at frame 0. Start. Frame = 5. 2. Start. Frame for next URB is set to (5+1024)=1029 3. URB is scheduled starting at frame 5 4. Second URB arrives at frame 512 5. Second URB is scheduled starting at frame (512+5)=517 Frame 0 If(FLAG(USBD_START_ISO_TRANSFER_ASAP)) { if(endpoint->state==ENDPOINT_FIRST_USE){ Start. Frame = Current. Frame + DEFAULT_LATENCY; } 1 else { Start. Frame = endpoint->Next. Transfer. Start. Frame; 4 if (ABS((Current. Frame - Start. Frame)) > 256) { 5 Frame 2048 Start. Frame = Current. Frame + DEFAULT_LATENCY; } } Frame 517 Frame 1028 endpoint->Next. Transfer. Start. Frame = Start. Frame + Frame. Count; Urb 1 Urb 2 } 2 else{ Start. Frame = Urb->Start. Frame; } Queue. Urb(Start. Frame, Urb); return STATUS_PENDING; } 3 11 © 2003 Microsoft Corporation. All rights reserved.
Using The USBD_START_ISO_TRANSFER_ASAP Flag For Windows XP Dispatch. Isoch. Transfer. URB { Problem: URB arrives less than 256 frames late Sequence: 1. First URB arrives at frame 0. Start. Frame = 5. 2. Start. Frame for next URB is set to (5+1024)=1029 3. URB is scheduled starting at frame 5 4. Second URB arrives at frame 1200 5. Second URB is scheduled starting at scheduled time, frame 1029, first 170 packets are late!!! If(FLAG(USBD_START_ISO_TRANSFER_ASAP)) { if(endpoint->state==ENDPOINT_FIRST_USE){ 1 Start. Frame = Current. Frame + DEFAULT_LATENCY; } else { Start. Frame = endpoint->Next. Transfer. Start. Frame; 4 if (ABS((Current. Frame - Start. Frame)) > 256) { Start. Frame = Current. Frame + DEFAULT_LATENCY; Frame 0 } } Frame 517 Frame 1028 endpoint->Next. Transfer. Start. Frame = Start. Frame + Frame. Count; } Urb 1 2 5 else{ Urb 2 Start. Frame = Urb->Start. Frame; } Queue. Urb(Start. Frame, Urb); 3 return STATUS_PENDING; } 12 Frame 1200 © 2003 Microsoft Corporation. All rights reserved.
Using The USBD_START_ISO_TRANSFER_ASAP Flag For Windows XP Dispatch. Isoch. Transfer. URB { Potential Workarounds 1. reset the pipe before sending every URB 2. Do not stream URBs from multiple threads 3. Be careful when sending multiple isochronous URB requests to prevent an URB from arriving more than 256 frames before it will be scheduled Currently Affected Platforms § Windows XP § Windows Server 2003 If(FLAG(USBD_START_ISO_TRANSFER_ASAP)) { if(endpoint->state==ENDPOINT_FIRST_USE){ Start. Frame = Current. Frame + DEFAULT_LATENCY; } else { Start. Frame = endpoint->Next. Transfer. Start. Frame; if (ABS((Current. Frame - Start. Frame)) > 256) { Start. Frame = Current. Frame + DEFAULT_LATENCY; } } endpoint->Next. Transfer. Start. Frame = Start. Frame + Frame. Count; } else{ Start. Frame = Urb->Start. Frame; } Queue. Urb(Start. Frame, Urb); return STATUS_PENDING; } 13 © 2003 Microsoft Corporation. All rights reserved.
Working With Isochronous Transfers Error recovery § Isochronous endpoints should not halt. § However, requests may occasionally return errors and the pipe may need to be reset. § If the URB completes successfully, individual isochronous packets may still have failed with an error. Drivers should check the Error. Count field of the URB for a non-zero value. Sending multiple IRP/URB pairs § It is possible to have multiple isochronous IRP/URB pairs pending in the bus driver simultaneously § In some cases and IRP/URB pair may arrive too early or too late to be scheduled and will be completed with an error 14 © 2003 Microsoft Corporation. All rights reserved.
USB Errors Status Returned struct _URB_HEADER § § { IRP Status URB Status USHORT Length ; Endpoint Stall USHORT Function ; § USBD_STATUS Status ; URB_FUNCTION_RESET_PIPE will clear the stall and reset the data toggle Port Disabled/Device Disconnected § Check the port status via an IOCTL_INTERNAL_USB_GET_PORT_S TATUS request § If the port is disabled a driver can issue and IOCTL_INTERNAL_USB_RESET_PORT request to re-enable the port. . . }; 15 © 2003 Microsoft Corporation. All rights reserved.
USB Transfer Error Recovery Procedure Recommended procedure for recovery 1. URB_FUNCTION_ABORT_PIPE and wait until all pending IRPs have completed. 2. Request the port status via IOCTL_INTERNAL_USB_GET_PORT_STATUS 3. Follow action in table below Port Status Action Disabled AND Connected IOCTL_INTERNAL_USB_RESET_PORT Enabled AND Connected URB_FUNCTION_RESET_PIPE Not Connected Prepare for Remove Comments § URB_FUNCTION_RESET_PIPE will reset the pipe and clear a stall condition on the endpoint § These requests should be called at PASSIVE_LEVEL § Drivers should always retry the transfer and check for errors. 16 © 2003 Microsoft Corporation. All rights reserved.
More Things You Should Know About USB I/O The client driver is responsible for sending zero-length packets to terminate non-control transfers Maximum interrupt endpoint polling interval supported § Full and High Speed Devices: 32 § Low Speed Devices: 8 § Higher b. Interval values are rounded down. Determining if a device is operating at high-speed § USB 2. 0 Compliant devices are not necessarily high-speed devices § The bus driver exposes an interface, Is. Device. High. Speed, which will return the speed of the device. See the DDK for more information on querying for USB interfaces. USB_BUS_INTERFACE_USBDI_V 1 bus. Interface; if (NT_SUCCESS(Get. Bus. Interface(Device. Object, &bus. Interface))) { Device. Extension->Device. Is. High. Speed = bus. Interface. Is. Device. High. Speed(bus. Interface. Bus. Context); } 17 © 2003 Microsoft Corporation. All rights reserved.
Composite Devices What is a composite device § USB device with multiple functions. Each function may consist of one of more interfaces. § All functions share a single USB port. § Microsoft supplies a parent driver to multiplex requests from multiple functions Driver Stack for Windows XP and later Function 1 Function 2 Driver stack for Windows 2000 Function 1 Function 2 USBCCGP. SYS USBHUB. SYS USBPORT, SYS USBD, SYS 18 © 2003 Microsoft Corporation. All rights reserved.
Configuration Descriptors For Composite Devices USB_CONFIGURATION_DESCRIPTOR b. Num. Interfaces = 3 USB_INTERFACE_ASSOCIATION_DESCRIPTOR b. First. Interface = 0 b. Num. Interfaces = 2 USB_INTERFACE_DESCRIPTOR b. Interface. Number = 0 USB_ENDPOINT_DESCRIPTOR USB_INTERFACE_DESCRIPTOR b. Interface. Number = 1 USB_ENDPOINT_DESCRIPTOR USB_INTERFACE_DESCRIPTOR Configuration descriptor returned to Function PDO 1 USB_CONFIGURATION_DESCRIPTOR b. Num. Interfaces = 2 USB_INTERFACE_DESCRIPTOR b. Interface. Number = 0 USB_ENDPOINT_DESCRIPTOR USB_INTERFACE_DESCRIPTOR b. Interface. Number = 1 USB_ENDPOINT_DESCRIPTOR Configuration descriptor returned to function PDO 2 USB_CONFIGURATION_DESCRIPTOR b. Num. Interfaces = 1 USB_INTERFACE_DESCRIPTOR b. Interface. Number = 2 USB_ENDPOINT_DESCRIPTOR 19 © 2003 Microsoft Corporation. All rights reserved.
Limitations Of Composite Device Support Reseting or Cycling a Port § § IOCTL_INTERNAL_USB_CYCLE_PORT is only supported for Windows XP and later Whenever a driver loaded for a composite PDO issues cycles or resets its port, the operation will affect all function drivers for the device Device Configuration § § Composite drivers may not use configurations other than configuration index 0 The configuration and device descriptors returned to a driver loaded for a composite PDO are not necessarily the same as the descriptors returned by the device Power Management § § § A device will be armed for wake if any single function driver requests an IRP_MN_WAIT_WAKE Selective suspend for composite devices is currently NOT supported The completion of a device power IRP for a lower power state does not imply the device is in that state 20 © 2003 Microsoft Corporation. All rights reserved.
USB Power Management Tips Waking the System § § § All pending Wait-Wake IRPs will be completed with STATUS_SUCCESS when the system wakes. There is currently no way to determine which device woke the system. If a device generates wake signaling while the system is suspending, the device may not be armed for wake. A USB hub may wake the system on connect/disconnect events. There is currently no way to control this behavior. This may change in the future. Drivers should follow WDM rules for power management § § Cancel all pending transfers before sending a device power IRP for a lower power state. Do not send any transfers until after a device power IRP for power state D 0 completes successfully. This may fail if the device is not present. 21 © 2003 Microsoft Corporation. All rights reserved.
Selective Suspend Tips For Windows XP Methods for Signaling that a Device is Idle § Issue an IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION request to the bus driver Arming a Device for Wake § Devices which do not need to wake the bus in response to external events should not need to submit IDLE IRPs § If a device needs to arm itself to wake the bus it should send an IRP_MN_WAIT_WAKE irp as early as possible, preferably before its IDLE-IRP callback is invoked Methods for Canceling an Idle request § 1. Cancel the pending IDLE IRP § 2. Device in power state D 0 after returning from the IDLE-IRP callback routine Methods for Waking the Bus § Client driver issues a device power IRP for device state D 0 § A device on the bus generates wake signaling 22 © 2003 Microsoft Corporation. All rights reserved.
Client Driver Selective Suspend Flowchart Recommended client driver selective suspend behavior Highlights § Issue a WAIT_WAKE request as early as possible § Bus will not suspend if device is in D 0 after returning from the callback § Set Power D 0 on successful completion of IDLE IRP Comments about USB Selective Suspend § A Hub is not idle until all devices connected to it are idle § The controller will not suspend until all connected devices are idle § Devices should cancel all pending I/O requests in their callbacks, before powering down 23 © 2003 Microsoft Corporation. All rights reserved.
Common USB Driver Errors Do not free an IRP or an associated URB before the IRP has completed. Aborting Transfers § Wait after sending an URB_FUNCTION_ABORT_PIPE request for all pending transfer IRPs to complete § A driver should cancel all pending transfers before stopping, being removed or going to a lower power state Canceling IRPs § Do not assume an IRP has been cancelled if Io. Cancel. Irp has returned (there may not be a cancel routine!) § The USB bus driver does not have a timeout for requests. The client must cancel requests that have timed out. § USB IRPs may not complete immediately after being cancelled. The client must wait for the IRPs to complete. Recycling URBs § Ensure that the parent IRP for an URB has completed before resending the URB § If using a MDL, ensure that all PTEs are released before reusing; 24 © 2003 Microsoft Corporation. All rights reserved.
USB Bugcheck Code 0 x. FE INTERNAL_ERROR: USBPORT internal error. Often a result of low resources or a driver submitting too large a transfer size. BAD_URB: kd> !analyze -v *********************************** * * * Bugcheck Analysis * *********************************** The URB submitted is attached to a currently pending IRP. BUGCODE_USB_DRIVER (fe) MINIPORT_ERROR: Arg 1: 00000004, IRP_URB_DOUBLE_SUBMIT The caller has submitted an irp This is generally related to a hardware error. IRP_URB_DOUBLE_SUBMIT: The client had submitted an IRP that is already pending in the bus driver. USB Driver bugcheck, first parameter is USB bugcheck code. Arguments: that is already pending in the USB bus driver. Arg 2: 866 f 92 d 8, Address of IRP Arg 3: 86709 e 38, Address of URB Arg 4: 0000 Debugging Details: --------- 25 © 2003 Microsoft Corporation. All rights reserved.
Debugging Common USB Problems Device Fails to Start (Code 10) § The bus driver will fail a client driver start IRP if the device § Is unresponsive to bus driver requests for descriptors, configuration, and addressing § Cannot be reset § Client drivers often fail their start IRP if a SELECT_CONFIGURATION or GET_DESCRIPTOR request fails. § There is currently no way to identify the root cause of the failure in the bus driver. A client driver can set a completion routine for its start IRP and check the status code for more information. USBD_STATUS codes § Every completed URB contains an USBD_STATUS code. These codes are defined in usb. h. This status is often more descriptive than the IRP status returned. 26 © 2003 Microsoft Corporation. All rights reserved.
Debugging Common USB Problems User notification § The following events may result in a pop-up bubble notifying the user of a problem § Overcurrent condition § Not enough power available on the port § Device hub is nested too deeply § Controller bandwidth exceeded § High speed device plugged into a non-high speed port 27 © 2003 Microsoft Corporation. All rights reserved.
Resources Microsoft Resources Technical Papers § § § IAD & USB 2 Debug Device: developer. intel. com/technology/usb/ spec. htm § Booting Windows from USB Storage Devices: www. microsoft. com/whdc/system/bus/ usb/usb-boot. mspx § USB CCID Smart Card Readers: § www. microsoft. com/whdc/system/ bus/usb/default. mspx www. microsoft. com/downloads/ results. aspx? product. ID=&freetext= USB&Display. Lang=en MSDN Newsgroups § § Windows Development Device Drivers Windows Development Windows DDK www. microsoft. com/whdc/device/input/ smartcard/USB_CCID. mspx Industry Resources § § § www. usb. org www. pcisig. com www. pcmcia. org 28 © 2003 Microsoft Corporation. All rights reserved.
© 2003 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary. 29
- Slides: 29