WdfUsbTargetDeviceSelectConfig returns STATUS_INVALID_PARAMETER

Hello,

We have an issue with one of our new prototype USB devices that is failing to enumerate using our device driver. The device driver works for all other models we offer (USB2 and USB3 devices), but the one new protype fails a WdfUsbTargetDeviceSelectConfig call during the enumeration sequence with “STATUS_INVALID_PARAMETER”

We prepare to make the call in as simple a matter as possible:

WDF_USB_DEVICE_SELECT_CONFIG_PARAMS params;
NTSTATUS status;

// Device is WDFDEVICE object received as parameter
PDEVICE_CONTEXT pDeviceContext = GetDeviceContext(Device);

WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_MULTIPLE_INTERFACES(&params, 0, NULL );
// devContext->UsbDevice is a WDFUSBDEVICE object previously created with WdfUsbTargetDeviceCreate
status = WdfUsbTargetDeviceSelectConfig(devContext->UsbDevice,
WDF_NO_OBJECT_ATTRIBUTES,
&params);

// (This call returns with STATUS_INVALID_PARAMETER)

I captured both a USB bus trace and a software level trace with USBTrace (similar to USBlyzer). When I look at the URB for the SELECT_CONFIGURATION call, I can see that the MaximumTransferSize for the one pipe on the one interface that exists is set to 0xFFFFFFFF. I believe this is why the call is failing; we’ve tried installing the device with libusb as well, and all the parameters in the URB are exactly the same except for this one parameter, which is instead set to 0x10000.

I’ve looked at the libusb code, and it looks like they set this parameter explicitly to 0x10000. Our driver instead relies solely on the framework calls as shown above, which has always worked.

Looking at the USB bus trace (for both our driver and the libusb driver), I see that the host attempts a Device Qualifier Descriptor, which fails (returns 0 bytes). I did read about the descriptor here:
http://www.keil.com/support/man/docs/rlarm/rlarm_usb_descript_dev_qualifier.htm

Could this be the reason why this device is failing to enumerate and the MaximumTransferSize parameter provided in the pipe information in the URB is wrong (0xFFFFFFFF)?

Thanks!

MaximumTransferSize is meaningless (at least since Win7, probably earlier), not a problem. What does
!wdfkd.wdflogdump say
And
The USB core ETW log?

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Friday, March 21, 2014 3:47 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] WdfUsbTargetDeviceSelectConfig returns STATUS_INVALID_PARAMETER

Hello,

We have an issue with one of our new prototype USB devices that is failing to enumerate using our device driver. The device driver works for all other models we offer (USB2 and USB3 devices), but the one new protype fails a WdfUsbTargetDeviceSelectConfig call during the enumeration sequence with “STATUS_INVALID_PARAMETER”

We prepare to make the call in as simple a matter as possible:

WDF_USB_DEVICE_SELECT_CONFIG_PARAMS params; NTSTATUS status;

// Device is WDFDEVICE object received as parameter PDEVICE_CONTEXT pDeviceContext = GetDeviceContext(Device);

WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_MULTIPLE_INTERFACES(&params, 0, NULL ); // devContext->UsbDevice is a WDFUSBDEVICE object previously created with WdfUsbTargetDeviceCreate status = WdfUsbTargetDeviceSelectConfig(devContext->UsbDevice,
WDF_NO_OBJECT_ATTRIBUTES,
&params);

// (This call returns with STATUS_INVALID_PARAMETER)

I captured both a USB bus trace and a software level trace with USBTrace (similar to USBlyzer). When I look at the URB for the SELECT_CONFIGURATION call, I can see that the MaximumTransferSize for the one pipe on the one interface that exists is set to 0xFFFFFFFF. I believe this is why the call is failing; we’ve tried installing the device with libusb as well, and all the parameters in the URB are exactly the same except for this one parameter, which is instead set to 0x10000.

I’ve looked at the libusb code, and it looks like they set this parameter explicitly to 0x10000. Our driver instead relies solely on the framework calls as shown above, which has always worked.

Looking at the USB bus trace (for both our driver and the libusb driver), I see that the host attempts a Device Qualifier Descriptor, which fails (returns 0 bytes). I did read about the descriptor here:
http://www.keil.com/support/man/docs/rlarm/rlarm_usb_descript_dev_qualifier.htm

Could this be the reason why this device is failing to enumerate and the MaximumTransferSize parameter provided in the pipe information in the URB is wrong (0xFFFFFFFF)?

Thanks!


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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

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

Hi Doron,

I can answer the first question right away. The WDF log spits out the following:
7: FxUsbDevice::SelectConfig - USB core failed Select Configuration, 0xc000009a(STATUS_INSUFFICIENT_RESOURCES)

I did a search and found this:
http://w.osronline.com/ShowThread.cfm?link=208890

FWIW, we can repeat this issue on standard Intel USB2 host controllers and several different USB3 host controllers. I am testing primarily on a Windows 8 machine with an xHCI card and the Microsoft xHCI driver installed.

I looked at USB Tree View and the card registers with RWEverything and noticed that the device connects at USB 1.1 speeds, but reports itself as USB 2.0 (via bcdUSB in the device descriptor). Is this what triggers the Device Qualifier Descriptor request from the host? And, is the failure of this GET_DESCRIPTOR request the likely cause of the STATUS_INSUFFICIENT_RESOURCES error?

What did you put to the device descriptors? Do you have USB analyser?

OK, good. That’s very useful. Now repeat the process and get a trace of USB Core. See the info on enabling ETW tracing in USB here:

http://msdn.microsoft.com/en-us/library/windows/hardware/jj151573(v=vs.85).aspx

Unless you’re using a USB 3 controller driver supplied by somebody OTHER THAN Microsoft, the link to the old thread you posted does not apply. So, nothing to see there.

Well, it SHOULD. Are you connected via some sort of Full Speed hub? Looking at the USB trace, what does your device answer to the request for the Device Qualifier Descriptor? Does the returned descriptor parse properly on your analyzer?

Peter
OSR
@OSRDrivers

xxxxx@gmail.com wrote:

I can answer the first question right away. The WDF log spits out the following:
7: FxUsbDevice::SelectConfig - USB core failed Select Configuration, 0xc000009a(STATUS_INSUFFICIENT_RESOURCES)

I did a search and found this:
http://w.osronline.com/ShowThread.cfm?link=208890

FWIW, we can repeat this issue on standard Intel USB2 host controllers and several different USB3 host controllers. I am testing primarily on a Windows 8 machine with an xHCI card and the Microsoft xHCI driver installed.

I looked at USB Tree View and the card registers with RWEverything and noticed that the device connects at USB 1.1 speeds, but reports itself as USB 2.0 (via bcdUSB in the device descriptor).

One possible cause for STATUS_INSUFFICIENT_RESOURCES is that you have
scheduled endpoints (interrupt and isochronous) with bandwidth demands
that exceed the available bandwidth. It is a relatively common mistake
to have isochronous endpoints request bandwidth in alternate setting 0.
The reason that is a mistake is shown here – if there isn’t sufficient
bandwidth, you fail at SelectConfiguration time. If you move the
isochronous endpoints to an alternate setting, then you don’t get the
failure until you change the alternate setting.

Can you show us the descriptors?


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

Thank you for the responses everyone.

Peter / Doron:

> ETW Log
I captured the ETW core dump. I'm not entirely sure what the look for, so I captured a log of a properly-enumerating USB device as well and compared them. The sequence of USBPort_MicrosoftWindowsUSBUSBPORT and USBHub_MicrosoftWindowsUSBUSBHUB event entries are the same for both in the "Frame Summary" window.

I also tried applying the "USB hub errors" standard filter, which does find five WINEVENT_LEVEL_ERROR NetEvent entries. I've copied the information for these entries to the bottom of this post

> Are you connected via some sort of Full Speed hub?
There is no external hub. The device is plugged directly into the host controller port.

> What does your device answer to the request for the Device Qualifier Descriptor?
The device does not answer the request. I should have mentioned earlier, but it responds with STALL. I can see "0 bytes - not enough data" in the USB trace, which is what I meant by 'returns zero bytes' earlier.

> Does the returned descriptor parse properly on your analyzer?
Since no descriptor is provided, there is no parsing.

It appears the hardware does not support this descriptor. In my work with our USB devices I've never even seen it, since I've worked exclusively with USB2 and 3.

Tim:

> One possible cause for STATUS_INSUFFICIENT_RESOURCES is that you have scheduled endpoints <...snip>
We do not use an scheduled endpoints. The device only provides a single BULK EP in addition to EP0. Here's a view of the descriptors, ripped out of USBTrace:

------------------ Device Descriptor ------------------
bLength : 0x12 (18 bytes)
bDescriptorType : 0x01 (Device Descriptor)
bcdUSB : 0x200 (USB Version 2.00)
bDeviceClass : 0x00 (defined by the interface descriptors)
bDeviceSubClass : 0x00
bDeviceProtocol : 0x00
bMaxPacketSize0 : 0x40 (64 bytes)
idVendor : 0xXXXX
idProduct : 0x1000
bcdDevice : 0x00
iManufacturer : 0x01
iProduct : 0x02
iSerialNumber : 0x03
bNumConfigurations : 0x01

-------------- Configuration Descriptor ---------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x02 (Configuration Descriptor)
wTotalLength : 0x0019 (25 bytes)
bNumInterfaces : 0x01
bConfigurationValue : 0x01
iConfiguration : 0x00
bmAttributes : 0x80 (Bus Powered)
MaxPower : 0xFA (500 mA)

---------------- Interface Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x04 (Interface Descriptor)
bInterfaceNumber : 0x00
bAlternateSetting : 0x00
bNumEndpoints : 0x01
bInterfaceClass : 0xFF (Vendor Specific)
bInterfaceSubClass : 0x00
bInterfaceProtocol : 0x00
iInterface : 0x00

----------------- Endpoint Descriptor -----------------
bLength : 0x07 (7 bytes)
bDescriptorType : 0x05 (Endpoint Descriptor)
bEndpointAddress : 0x81 (Direction=IN EndpointID=1)
bmAttributes : 0x02 (TransferType=Bulk)
wMaxPacketSize : 0x200 (512 bytes)
bInterval : 0x00 (ignored)

ETW Error events mentioned above:

Frame: Number = 149, Captured Frame Length = 105, MediaType = NetEvent

  • NetEvent:
  • Header:
    Size: 96 (0x60)
    HeaderType: 0 (0x0)
  • Flags: 32 (0x20)
  • EventProperty: 0 (0x0)
    ThreadId: 0 (0x0)
    ProcessId: 0, ProcessName:
    TimeStamp: 03/24/2014, 17:48:04.403891 UTC
    ProviderId: {AC52AD17-CC01-4F85-8DF5-4DCE4333C99B}
  • Descriptor:
    Id: 176 (0xB0)
    Version: 0 (0x0)
    Channel: 16 (0x10)
    Level: WINEVENT_LEVEL_ERROR
    Opcode: 0xb
    Task: 9 (0x9)
    DefaultKeyword: 9223372036854793217 (0x8000000000004401)
    ProcessorTime: 22650 (0x587A)
    ActivityId: {5FCF7618-4788-0001-5977-CF5F8847CF01}
    ETLProvider:
  • BufferContext:
    ProcessorNumber: 4 (0x4)
    Alignment: 0 (0x0)
    LoggerId: 12 (0xC)
    ExtendedDataCount: 0 (0x0)
    UserDataLength: 16 (0x10)
    Reassembled: 0 (0x0)
    UserData: Binary Large Object (16 Bytes)

Frame: Number = 162, Captured Frame Length = 105, MediaType = NetEvent

  • NetEvent:
  • Header:
    Size: 96 (0x60)
    HeaderType: 0 (0x0)
  • Flags: 32 (0x20)
  • EventProperty: 0 (0x0)
    ThreadId: 0 (0x0)
    ProcessId: 0, ProcessName:
    TimeStamp: 03/24/2014, 17:48:04.415874 UTC
    ProviderId: {AC52AD17-CC01-4F85-8DF5-4DCE4333C99B}
  • Descriptor:
    Id: 165 (0xA5)
    Version: 0 (0x0)
    Channel: 16 (0x10)
    Level: WINEVENT_LEVEL_ERROR
    Opcode: 0xb
    Task: 9 (0x9)
    DefaultKeyword: 9223372036854793217 (0x8000000000004401)
    ProcessorTime: 22407 (0x5787)
    ActivityId: {5FCF7618-4788-0001-5977-CF5F8847CF01}
    ETLProvider:
  • BufferContext:
    ProcessorNumber: 0 (0x0)
    Alignment: 0 (0x0)
    LoggerId: 12 (0xC)
    ExtendedDataCount: 0 (0x0)
    UserDataLength: 16 (0x10)
    Reassembled: 0 (0x0)
    UserData: Binary Large Object (16 Bytes)

Frame: Number = 163, Captured Frame Length = 105, MediaType = NetEvent

  • NetEvent:
  • Header:
    Size: 96 (0x60)
    HeaderType: 0 (0x0)
  • Flags: 32 (0x20)
  • EventProperty: 0 (0x0)
    ThreadId: 0 (0x0)
    ProcessId: 0, ProcessName:
    TimeStamp: 03/24/2014, 17:48:04.415874 UTC
    ProviderId: {AC52AD17-CC01-4F85-8DF5-4DCE4333C99B}
  • Descriptor:
    Id: 132 (0x84)
    Version: 0 (0x0)
    Channel: 16 (0x10)
    Level: WINEVENT_LEVEL_ERROR
    Opcode: 0xb
    Task: 15 (0xF)
    DefaultKeyword: 9223372036854792193 (0x8000000000004001)
    ProcessorTime: 22407 (0x5787)
    ActivityId: {00000000-0000-0000-0000-000000000000}
    ETLProvider:
  • BufferContext:
    ProcessorNumber: 0 (0x0)
    Alignment: 0 (0x0)
    LoggerId: 12 (0xC)
    ExtendedDataCount: 0 (0x0)
    UserDataLength: 16 (0x10)
    Reassembled: 0 (0x0)
    UserData: Binary Large Object (16 Bytes)

Frame: Number = 183, Captured Frame Length = 105, MediaType = NetEvent

  • NetEvent:
  • Header:
    Size: 96 (0x60)
    HeaderType: 0 (0x0)
  • Flags: 32 (0x20)
  • EventProperty: 0 (0x0)
    ThreadId: 36 (0x24)
    ProcessId: 4, ProcessName:
    TimeStamp: 03/24/2014, 17:48:05.442832 UTC
    ProviderId: {AC52AD17-CC01-4F85-8DF5-4DCE4333C99B}
  • Descriptor:
    Id: 176 (0xB0)
    Version: 0 (0x0)
    Channel: 16 (0x10)
    Level: WINEVENT_LEVEL_ERROR
    Opcode: 0xb
    Task: 9 (0x9)
    DefaultKeyword: 9223372036854793217 (0x8000000000004401)
    ProcessorTime: 6 (0x6)
    ActivityId: {5FCF7618-4788-0003-1F77-CF5F8847CF01}
    ETLProvider:
  • BufferContext:
    ProcessorNumber: 3 (0x3)
    Alignment: 0 (0x0)
    LoggerId: 12 (0xC)
    ExtendedDataCount: 0 (0x0)
    UserDataLength: 16 (0x10)
    Reassembled: 0 (0x0)
    UserData: Binary Large Object (16 Bytes)

Frame: Number = 189, Captured Frame Length = 118, MediaType = NetEvent

  • NetEvent:
  • Header:
    Size: 109 (0x6D)
    HeaderType: 0 (0x0)
  • Flags: 32 (0x20)
  • EventProperty: 0 (0x0)
    ThreadId: 0 (0x0)
    ProcessId: 0, ProcessName:
    TimeStamp: 03/24/2014, 17:48:05.445572 UTC
    ProviderId: {30E1D284-5D88-459C-83FD-6345B39B19EC}
  • Descriptor:
    Id: 34 (0x22)
    Version: 0 (0x0)
    Channel: 16 (0x10)
    Level: WINEVENT_LEVEL_ERROR
    Opcode: 0xa
    Task: 22 (0x16)
    DefaultKeyword: 4611686018427912193 (0x4000000000080001)
    ProcessorTime: 22473 (0x57C9)
    ActivityId: {00000000-0000-0000-0000-000000000000}
    ETLProvider:
  • BufferContext:
    ProcessorNumber: 0 (0x0)
    Alignment: 0 (0x0)
    LoggerId: 12 (0xC)
    ExtendedDataCount: 0 (0x0)
    UserDataLength: 29 (0x1D)
    Reassembled: 0 (0x0)
    UserData: Binary Large Object (29 Bytes)

Thanks!

xxxxx@gmail.com wrote:

>> Are you connected via some sort of Full Speed hub?
There is no external hub. The device is plugged directly into the host controller port.

>> What does your device answer to the request for the Device Qualifier Descriptor?
The device does not answer the request. I should have mentioned earlier, but it responds with STALL. I can see “0 bytes - not enough data” in the USB trace, which is what I meant by ‘returns zero bytes’ earlier.

>> Does the returned descriptor parse properly on your analyzer?
Since no descriptor is provided, there is no parsing.

It appears the hardware does not support this descriptor. In my work with our USB devices I’ve never even seen it, since I’ve worked exclusively with USB2 and 3.

I can’t imagine that you’ve never seen a device qualifier descriptor.
All high-speed USB 2 devices should have one. It is always possible for
you to be enumerated at full-speed, and your configuration descriptor is
not valid for a full-speed device. (A full-speed device cannot have a
bulk pipe with 512-byte packets.) The device qualifier tells the system
“I have a different configuration descriptor if I enumerate at full speed”.


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

Well… It depends on how you design your device. Depending on the USB chipset chosen you can often wait to determine if you’re connecting to a High Speed or Full Speed bus (you can wait for the chirp) and then have your firmware change the configuration descriptors returned. If you’re connected to a Full Speed bus, you return your Full Speed configuration as the primary descriptor… and if you’re connected to a High Speed bus, you return your High Speed configuration as the primary. In each descriptor, you list the OTHER speed (Full or High) as the alternate speed.

Works quite nicely in my experience,

Peter
OSR
@OSRDrivers

Tim:

Right, excellent observation! Thank you very much! I’ve forwarded this information to the hardware team.

Thanks everyone on this one.