Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: allocate memory for USB URB-buffers



Hi Patrick,

Patrick Boettcher wrote:

Hi list,

I would like to know which is the common way to allocate memory for the urb-buffer for the USB MPEG-TS-transfer?

Currently I use pci_alloc_consistent (which I copy'n'pasted from ttusb-dec, when I started working on usb drivers). It is working quite well, but with USB2.0 dibusb-devices (eg NOVA-T USB2) there is a problem sometimes:

DiBcom specifies a bulk-transfer-buffersize of 210*188 (39480) bytes in their usb2.0-firmware. I.e. I have to use a buffer of almost 40KB for each URB. Normally I submit 3 URBs, therefore I have to alloc 120KB.

The USB2.0 spec limits the size of packets for Bulk- and Isochronous transfers to 1024 bytes. In version 1.1 the limits were 64bytes (Bulk) and 1023 bytes (isochronous). It makes not much sense to allocate very big buffers, they will get transferred in splitted packets anyways. Please see the USB spec or the Cypress FX2 technical reference manual for details, the latter contains a nice introduction to the transfer modes.

This is what fails sometimes:

insmod: page allocation failure. order:4, mode:0x21

I assume this means it is not possible to get free, continous 120KB. Sometimes this even fails with 40KB... (1 URB for test reasons).

pci_alloc_consistent() tries to allocate continous, non-paged, DMA-capable memory. Due to fragmentation there may be several situations where you can't allocate big continous chunks (and you don't even need to, USB does never requires such big chunks, may they mean to request 210 URBs containing a 188-byte transferbuffer each?)

If you pass big transferbuffers to the URB then multiple packets get concatenated by the host controller, but you can as well use different URBs.

The cinergyT2 driver uses by default 32*512 bytes as transfer buffer, I would assume the DiBcom devices will work with similiar sizes in common setups, please see the code for details. Right now we are allocating a monolithic 16kB-block in cinergyt2_alloc_stream_urbs(), but this could get done as well in smaller pieces seperately attached to each URB.

If I just reduce the size of the URB Buffer, the device is crashing and the system with it.

Is there a reason why one can't use kmalloc(ATOMIC)? Will it fail as well?

you can do so, such small amounts of memory can also get allocated using page_alloc(), just be sure to request non-pageable memory. Since no packet type defined by the USB spec can grow larger than a page size you should always be able to get your buffers.

Holger





Home | Main Index | Thread Index