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.
Hi,
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.
--HPS
More information about the freebsd-multimedia
mailing list