USB isochronous transfer problem

Hi All,

I’m developing an USB audio recording device (microphone) according to UAC 1.0. My descriptors are accepted by the host and it adds my device to recording devices list - no any problems with the descriptors are reported by all the analyzer tools I have. But when I start recording itself, using standard Windows Sound Recorder and the host issues URB_FUNCTION_ISOCH_TRANSFER packets, it gets error response USBD_STATUS_INVALID_PARAMETER without any additional information.

I read that this error can happen when the number of packets per transfer exceeds some predefined limit (1024 packets for high speed iso transfer in my case), but I far from exceeding this limit and the error stays even with very small number of packets - 16 per transfer.

Actually, the problem happens before any transfer - right after the host selects required interface setting, it immediately starts iso requests and receives this error, independently of what I do on device side.

Any help will be appreciated.

Thanks, Denis

If you are using Windows 7 you could try capturing a USB ETW trace around the time when your driver is started and when it encounters the USBD_STATUS_INVALID_PARAMETER error. There should be ETW events corresponding to the URB_FUNCTION_ISOCH_TRANSFER USBD_STATUS_INVALID_PARAMETER errors with additional information, for example if the start frame or the number of packets are not valid values.

http://blogs.msdn.com/b/usbcoreblog/archive/2009/12/04/etw-in-the-windows-7-usb-core-stack.aspx

-Glen

Thank you for this tip! I tried that and got little more information, but unfortunately it’s still not enough to figure out the problem… I see that after urb isoch transfer issued, periodic scheduler starts then immediately stops and I receive “complete” response with “invalid parameter” status. Looks like host controller dislikes something in my request, but doesn’t inform exactly, what it dislikes.

Below is the transaction log and the contents of sent and received URBs. If anybody can point me something helpful, that would be extremely cool, since I must to resolve the problem today according to our plan :frowning:

This is a log that I get with ETW:
USBPort:Dispatch URB_FUNCTION_ISOCH_TRANSFER
USBPort:Host Controller Periodic Schedule Enable
USBPort:Host Controller Periodic Schedule Disable
USBPort:Complete COMPLETE_URB_FUNCTION_ISOCH_TRANSFER

This is the contents of sent URB:
Frame: Number = 173, Captured Frame Length = 466, MediaType = NetEvent

  • NetEvent:
    USBPort: Dispatch URB_FUNCTION_ISOCH_TRANSFER
  • UsbPort: Dispatch URB_FUNCTION_ISOCH_TRANSFER
  • USBPORT_ETW_EVENT_DISPATCH_URB_FUNCTION_ISOCH_TRANSFER: Dispatch URB_FUNCTION_ISOCH_TRANSFER
  • HostController: 1a-7 e
  • DeviceObject: 0x0000000002B79050
  • HostController: 1a-7 e
  • fid_USBPORT_Device:
  • fid_USBPORT_Endpoint:
  • fid_USBPORT_Endpoint_Descriptor:
  • fid_IRP_Ptr: 0x0000000003995C60
  • fid_URB_Ptr: 0x00000000017B5560
    fid_USBPORT_URB_NumberOfPackets: 10 (0xA)
  • Urb: Function = URB_FUNCTION_ISOCH_TRANSFER, Length = 320, Flags 0x5
    fid_URB_Hdr_Length: 272 (0x110)
    fid_URB_Hdr_Function: URB_FUNCTION_ISOCH_TRANSFER (0xa)
    fid_URB_Hdr_Status: USBD_STATUS_SUCCESS (0x0)
  • fid_URB_Hdr_UsbdDeviceHandle: 0x0000000003E19A60
  • fid_URB_Hdr_UsbdFlags: 0x0000000000000022
  • fid_URB_PipeHandle: 0x00000000043C1598
  • fid_URB_TransferFlags: In, iso asap (0x5)
    fid_URB_TransferBufferLength: 320 (0x140)
  • fid_URB_TransferBuffer: 0x00000000017B6250
  • fid_URB_TransferBufferMDL: 0x00000000042B1C00
  • fid_URB_ReservedMBZ: 0x0000000000000000
  • fid_URB_ReservedHcd: 0x0000000004685980
  • fid_URB_ReservedHcd: 0x00000000DEADF00D
  • fid_URB_ReservedHcd: 0x0000000000000000
  • fid_URB_ReservedHcd: 0x0000000000000000
  • fid_URB_ReservedHcd: 0x0000000000000000
  • fid_URB_ReservedHcd: 0x0000000000000000
  • fid_URB_ReservedHcd: 0x0000000000000000
  • fid_URB_ReservedHcd: 0x0000000000000000
    fid_URB_StartFrame: 360928 (0x581E0)
    fid_URB_NumberOfPackets: 10 (0xA)
    fid_URB_ErrorCount: 0 (0x0)

This is the contents of received URB:
Frame: Number = 176, Captured Frame Length = 466, MediaType = NetEvent

  • NetEvent:
    USBPort: Complete COMPLETE_URB_FUNCTION_ISOCH_TRANSFER
  • UsbPort: Complete COMPLETE_URB_FUNCTION_ISOCH_TRANSFER
  • USBPORT_ETW_EVENT_COMPLETE_URB_FUNCTION_ISOCH_TRANSFER: Complete COMPLETE_URB_FUNCTION_ISOCH_TRANSFER
  • HostController: 1a-7 e
  • DeviceObject: 0x0000000002B79050
  • HostController: 1a-7 e
  • fid_USBPORT_Device:
  • fid_USBPORT_Endpoint:
  • fid_USBPORT_Endpoint_Descriptor:
  • fid_IRP_Ptr: 0x0000000003995C60
  • fid_URB_Ptr: 0x00000000017B5560
    fid_USBPORT_URB_NumberOfPackets: 10 (0xA)
  • Urb: USBD_STATUS_INVALID_PARAMETER, Function = URB_FUNCTION_ISOCH_TRANSFER, Length = 0, Flags 0x5
    fid_URB_Hdr_Length: 272 (0x110)
    fid_URB_Hdr_Function: URB_FUNCTION_ISOCH_TRANSFER (0xa)
    fid_URB_Hdr_Status: USBD_STATUS_INVALID_PARAMETER (0x80000300)
  • fid_URB_Hdr_UsbdDeviceHandle: 0x0000000003E19A60
  • fid_URB_Hdr_UsbdFlags: 0x0000000000000022
  • fid_URB_PipeHandle: 0x00000000043C1598
  • fid_URB_TransferFlags: In, iso asap (0x5)
    fid_URB_TransferBufferLength: 0 (0x0)
  • fid_URB_TransferBuffer: 0x00000000017B6250
  • fid_URB_TransferBufferMDL: 0x00000000042B1C00
  • fid_URB_ReservedMBZ: 0x0000000000000000
  • fid_URB_ReservedHcd: 0x0000000004685980
  • fid_URB_ReservedHcd: 0x00000000DEADF00D
  • fid_URB_ReservedHcd: 0x0000000000000000
  • fid_URB_ReservedHcd: 0x0000000000000000
  • fid_URB_ReservedHcd: 0x0000000000000000
  • fid_URB_ReservedHcd: 0x0000000000000000
  • fid_URB_ReservedHcd: 0x0000000000000000
  • fid_URB_ReservedHcd: 0x0000000000000000
    fid_URB_StartFrame: 0 (0x0)
    fid_URB_NumberOfPackets: 10 (0xA)
    fid_URB_ErrorCount: 0 (0x0)

Is the device a high-speed device? What is the Endpoint Descriptor bInterval value?

The USB 2.0 specification says that the bInterval value for a high-speed isochronous endpoint must be in the range from 1 to 16, yielding periods of 1 to 32768 microframes 2^(bInterval-1). However, a URB_FUNCTION_ISOCH_TRANSFER request will fail with an USBD_STATUS_INVALID_PARAMETER error if the bInterval value is greater than 4. The only supported high-speed isochronous endpoint bInterval values are 1, 2, 3, and 4 yielding periods of 1, 2, 4, and 8 microframes.

Also, a URB_FUNCTION_ISOCH_TRANSFER request must start and end on frame boundaries.
If the period is 1 microframe the NumberOfPackets must be a multiple of 8.
If the period is 2 microframes the NumberOfPackets must be a multiple of 4.
If the period is 4 microframes the NumberOfPackets must be a multiple of 2.

Your original post said you were trying 16 packets per URB_FUNCTION_ISOCH_TRANSFER request. The ETW event shows a NumberOfPackets value of 10 decimal. Did you really intend to use 0x10 hexadecimal? If the high-speed isochronous endpoint has a period of 1 or 2 microframes then a NumberOfPackets value of 10 decimal will result in a USBD_STATUS_INVALID_PARAMETER error.

-Glen

xxxxx@gmail.com wrote:

I’m developing an USB audio recording device (microphone) according to UAC 1.0. My descriptors are accepted by the host and it adds my device to recording devices list - no any problems with the descriptors are reported by all the analyzer tools I have. But when I start recording itself, using standard Windows Sound Recorder and the host issues URB_FUNCTION_ISOCH_TRANSFER packets, it gets error response USBD_STATUS_INVALID_PARAMETER without any additional information.

Are you using usbaudio.sys, or are you using a custom driver?


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

Fortunately, I noticed a thread (http://www.freelists.org/post/wdmaudiodev/USB20-High-speed-audio-device-for-windows-XP,15) with answer to my question. I have a high-speed audio device and use usbaudio.sys, which requires bInterval value to be set to 4 for high-speed devices (I set it to 1 initially) to result in 1 ms in accordance with USB 1.1 spec.

As I understood, this is a redundant bandwidth limitation, but it’s somewhat unclear to me, how the restriction of bInterval to 4 eventually affects the bandwidth. Since we still can set wMaxPacketSize to any value, this means, that fixed bInterval makes the selection of possible bandwidths too coarse, without ability to fine tune, right?

xxxxx@gmail.com wrote:

Fortunately, I noticed a thread (http://www.freelists.org/post/wdmaudiodev/USB20-High-speed-audio-device-for-windows-XP,15) with answer to my question. I have a high-speed audio device and use usbaudio.sys, which requires bInterval value to be set to 4 for high-speed devices (I set it to 1 initially) to result in 1 ms in accordance with USB 1.1 spec.

As I understood, this is a redundant bandwidth limitation, but it’s somewhat unclear to me, how the restriction of bInterval to 4 eventually affects the bandwidth. Since we still can set wMaxPacketSize to any value, this means, that fixed bInterval makes the selection of possible bandwidths too coarse, without ability to fine tune, right?

Well, you can’t literally set wMaxPacketSize to “any value”. The
limitation on bInterval is not, strictly speaking, about bandwidth.
Creating an isochronous URB at high-speed where bInterval is 1, 2 or 3
has additional restrictions on the number of packets per URB.
Usbaudio.sys does not know about those restrictions. It only computes
the timing based on even multiples of milliseconds.

Audio just doesn’t consume that much bandwidth, so you don’t need an
enormous amount of granularity. A 48kHz stereo 16-bit stream only needs
192 bytes per millisecond. When the need is less, usbaudio.sys adjusts
the packet sizes in the URBs to keep the stream relatively constant.


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