What is wrong with FreeBSD and USB Support

Hans Petter Selasky hps at selasky.org
Mon Mar 6 10:23:52 UTC 2017

On 03/06/17 07:05, Markus Rechberger wrote:
> libusb20_dev_open() opens an USB device so that setting up USB
> transfers becomes possible. The number of USB transfers can be zero
> which means only control transfers are allowed. This function returns
> zero on success else a LIBUSB20_ERROR value is returned. A return
> value of LIBUSB20_ERROR_BUSY means that the device is already opened.
> libusb20_tr_get_pointer() will return a pointer to the allocated USB
> transfer according to the pdev and tr_index arguments. This function
> returns NULL in case of failure.
> what is the definition of a "tr_index"? The documentation does not
> cover that anywhere, someone can only copy it from the sample sources.
> Please don't expect that anyone reading the manpage will have an idea
> how the FreeBSD API works, because all those items simply do not exist
> with other operating systems, neither is the ep_index calculation
> needed with other systems.


When you open a USB device you need to specify how many USB transfer 
structures you plan to use. Then you can bind each individual USB 
transfer by tr_index to an endpoint (bEndpointAddress).

> uint8_t ep_index = (((addr & 0x80) / 0x40) | (addr * 4)) % (16 * 4);
> uhe->bsd_xfer[0] = libusb20_tr_get_pointer(dev->bsd_udev, ep_index + 0);
> uhe->bsd_xfer[1] = libusb20_tr_get_pointer(dev->bsd_udev, ep_index + 1);

> So my guess is that the examples are just using 2 urb transfers and
> freebsd just cannot catch up. However it is still unclear how to
> correctly initiate more than 2 urb transfers by reading the
> documentation.

dev = libusb20_dev_open(xxx, 4);

xfer[0] = libusb20_tr_get_pointer(dev, 0);
libusb20_tr_open(xfer, max_buf_size, max_frame_count, ep_no);

xfer[1] = libusb20_tr_get_pointer(dev, 1);
libusb20_tr_open(xfer, max_buf_size, max_frame_count, ep_no);

xfer[2] = libusb20_tr_get_pointer(dev, 2);
libusb20_tr_open(xfer, max_buf_size, max_frame_count, ep_no);

xfer[3] = libusb20_tr_get_pointer(dev, 3);
libusb20_tr_open(xfer, max_buf_size, max_frame_count, ep_no);

Now you have four USB transfers index 0..3 inclusivly bound to USB 
Endpoint with bEndpointAddress ep_no.

NOTE: FreeBSD will only hardware buffer the two first transfers you 
submit. That's why most drivers and examples only do double buffering. 
If you try to submit 32 x 512bytes as individual USB transfers, you will 
receive a penalty. Instead, submit one USB transfer having 32 so-called 
frames, which each has a length of 512 bytes.


More information about the freebsd-multimedia mailing list