Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Mar 2017 11:23:01 +0100
From:      Hans Petter Selasky <hps@selasky.org>
To:        Markus Rechberger <mrechberger@gmail.com>, freebsd-multimedia@freebsd.org
Subject:   Re: What is wrong with FreeBSD and USB Support
Message-ID:  <43ec60ca-57ce-faf9-32da-524454e1ac4a@selasky.org>
In-Reply-To: <CA%2BO4pC%2Bf5xzOjENKSJu_sQeaiN3XL3WiTcRQvm4vVweQ71Xtrg@mail.gmail.com>
References:  <CA%2BO4pCK4%2B1rE5ft4Boy_3xPdCxK31UtTQ2BYpnBUn5jxZr%2Bz_g@mail.gmail.com> <CA%2BO4pCJr5Bq-sgjzvZQB-mFRT6x7Tp3psga6f__V9Ag-=v-mhw@mail.gmail.com> <CA%2BO4pC%2Bf5xzOjENKSJu_sQeaiN3XL3WiTcRQvm4vVweQ71Xtrg@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?43ec60ca-57ce-faf9-32da-524454e1ac4a>