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