Re: New USB stack on FreeBSD w/Linux emulation layer coming

Hans Petter Selasky <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
Hi,

On Wednesday 16 May 2007 20:20, David Brownell wrote:
> > > > > URB submission has other failure possibilities than lack of memory.
> > > > > Those other things have to be checked for regardless.
> > > >
> > > > Yes, but that is because you allow too many parameters in the URB to
> > > > be changed between USB transfers.
> > >
> > > No; it's because unforeseen events can occur.  For example, the device
> > > may have been unplugged or suspended.
> >
> > On FreeBSD it will never happen that you call the equivalent
> > of "usb_submit_urb()" after that the device has detached! It must be
> > something terribly wrong in the Linux USB stack if the callbacks are
> > alive after that you have detached a USB device.
>
> How does that work then ... driver must grab a lock, check
> whether the device has disconnected, then submit the request
> and drop the lock?  Sounds like needless slowdowns.

Each USB device has its own lock. There are some tricks there.

1) usbd_transfer_start() is always called like this:
   usbd_transfer_start(sc->sc_xfer[x]);

2) sc->sc_xfer[x] is set to zero at detach holding the private lock of the USB 
device driver. All subsequent calls to usbd_transfer_start(), if any, will 
fail.

3) usbd_transfer_start() is always non-blocking. In other words a single lock 
is held across the call.

This is how it looks until further:

As you can see, no other locks are locked unless you want to submit a transfer 
to the USB host controller. Then you have to aquire "usb_mtx" which is per 
USB host controller.

void
usbd_transfer_start(struct usbd_xfer *xfer)
{
	if (xfer == NULL) {
	    /* transfer is gone */
	    return;
	}

	mtx_assert(xfer->priv_mtx, MA_OWNED);

	if(!(xfer->flags & USBD_DEV_OPEN))
	{
		xfer->flags |= USBD_DEV_OPEN;

		/*
		 * open transfer
		 */
		mtx_lock(xfer->usb_mtx);
		(xfer->pipe->methods->open)(xfer);
		mtx_unlock(xfer->usb_mtx);
	}

	/* "USBD_DEV_TRANSFERRING" is only changed
	 * when "priv_mtx" is locked
	 */
	if(!(xfer->flags & (USBD_DEV_TRANSFERRING)))
	{
		/* call callback */
		__usbd_callback(xfer);

		<cut away>
	}
	return;
}

>
> Because if there's no lock against async disconnect events,
> then it's trivial to have the disconnect logic underway on
> one CPU while another CPU does real work, submitting an I/O
> request.

We solve this in one of two ways:

1) Using a mutex. At detach we lock the mutex stopping all transfers.

2) Using a thread. At detach we teardown and wait for the thread to exit.

> - Dave
>
> p.s. You mentioned 16 MB/sec bulk transfer rates.  Folk often
>      get over twice that on Linux, and a few years back there
>      were measurements of around 50 MByte/sec ... limitations
>      seeming to come from hardware not the driver stack.

Yes, hardware and price :-)

--HPS

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.