On Fri, 8 Feb 2008, Mauro Carvalho Chehab wrote:

> Hi Guys,
> 
> There's currently an issue with isoc transfers made by em28xx driver[1] and
> ehcd_hci. If I try to start isoc transfers on more than one hardware, the
> second hardware fails at usb_submit_urb() with -ENOSPC.

ENOSPC means that you are attempting to use more bandwidth than the bus
allows.  A high-speed isochronous transfer of length 3072 requires 41%
of the total bandwidth (according to Table 5-5 in the USB 2.0 spec),
and periodic transfers (isochronous and interrupt) on a high-speed bus
are limited to no more than 80% of the total bandwidth.

Performing transfers to two devices would require 82% of the bandwidth;
hence it isn't allowed.

> The current code that initializes isoc transfers looks like this (I've removed
> error handling and replaced some constants to make it cleaner to read):
> 
>       max_pkt_size = 3072;
>       size = 40 * max_pkt_size;
>         for (i = 0; i < 5; i++) {
>                 urb = usb_alloc_urb(40, GFP_KERNEL);
>                 dev->transfer_buffer[i] = usb_buffer_alloc(usb_dev, size, 
> GFP_KERNEL, &urb->transfer_dma);
> 
>                 memset(dev->transfer_buffer[i], 0, size);
>                 urb->dev = usb_udev;
>                 urb->context = v4l_dev;
>                 urb->pipe = usb_rcvisocpipe(usb_dev, 0x82);
>                 urb->transfer_flags = URB_ISO_ASAP;

Since you have set urb->transfer_dma, you also need to set 
URB_NO_TRANSFER_DMA_MAP in urb->flags.

>                 urb->interval = 1;
>                 urb->transfer_buffer = dev->transfer_buffer[i];
>                 urb->complete = em28xx_isocIrq;
>                 urb->number_of_packets = 40;
>                 urb->transfer_buffer_length = size;
>                 for (j = 0; j < 40; j++)
>                         urb->iso_frame_desc[j].offset = j * max_pkt_size;

Where do you set urb->iso_frame_desc[i].length?

>                 dev->urb[i] = urb;
>         }
> 
>         for (i = 0; i < 5; i++)
>                 usb_submit_urb(dev->urb[i], GFP_KERNEL);
> 
> Any ideas on how this could work?

You may need to put your two devices on separate USB buses.

Alan Stern

-
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to