usbd_bulk_transfer returns 1 (USBD_IN_PROGRESS) ?!
Hans Petter Selasky
hselasky at c2i.net
Sat May 28 06:30:32 PDT 2005
On Friday 27 May 2005 13:31, Seb wrote:
> Ok, I understood the problem.
> But I didn't fix it with mutexes, I used semaphores instead.
> I initialize a semaphore with a value equal to 1 and then, before the USB
> transfers, I do :
while(entered)
{
> mtx_unlock(&Giant);
> sema_wait(&sc->usb_tx_sema);
> mtx_lock(&Giant);
}
entered = 1;
> And after the USB transfers :
> sema_post(&sc->usb_tx_sema);
entered = 0;
> Is this OK ?
I think it is better you use "sx_xlock", "sx_xunlock" and "sx_init".
See "man sx".
> Apparently it has solved the problem, the driver now sustains
> heavy network load :)
> I wouln't like to use asynchronous transfers, they make the code hard to
> read and would require all users to recompile their kernels to install your
> USB driver...
You, can do asynchronous transfers with the existing USB driver too. But to do
what you want to do, the code will be a little more complicated, because the
existing USB-API wasn't designed to handle that. Just make a wrapper for
"usbd_bulk_transfer()":
my_bulk_transfer(sc, xfer):
{
if(started == 0)
{
m = dequeue packet;
if(m == NULL) return;
prepend m;
started = 1;
err = usbd_transfer();
if(err)
{
started = 0;
}
}
}
your_callback(xfer,...,error):
{
started = 0;
if(error == 0) {
my_bulk_transfer(sc, xfer);
/* calling usbd_transfer()
* from callback is allowed
*/
}
}
If you do things via callback you can remove "sc->tx_queues[]" and associated
functions. I think you will get better performance using callbacks. And most
importantly, you are no longer blocking the callers of those functions that
send packets.
--HPS
More information about the freebsd-usb
mailing list