My USB controller driver

Hans Petter Selasky hselasky at c2i.net
Sat Dec 31 05:50:23 PST 2005


On Saturday 31 December 2005 07:23, Anish Mistry wrote:
> On Friday 30 December 2005 04:35 pm, Hans Petter Selasky wrote:
> > Hi,
> >
> > I just want to remind you of my USB controller driver for FreeBSD.
> > I have now created a new homepage for it:
> >
> > http://www.turbocat.net/~hselasky/usb4bsd
> >
> > The sources are currently part of my ISDN4BSD driver, and can be
> > downloaded by running the following command, if one has got
> > Subversion installed:
> >
> > svn --username anonsvn --password anonsvn checkout
> > svn://svn.turbocat.net/i4b
> >
> > This should make it very easy to make patches against my driver, if
> > anyone has any suggestions for improvements. For those of you not
> > familiar with svn, a patch can be produced by running the command
> > "svn diff".
> >
> > It is also possible to browse the sources at the homepage without
> > having to install SVN.
>
> Do you have any ETA or progress report on merging these changes into
> the tree?

To get the locking stuff right, I think that FreeBSD 7 will have a new USB 
system. FreeBSD 5/6 will continue using the old USB system until further. 
There are no concrete plans made yet.


Maybe this about locking is not so easy to see.


According to a FreeBSD committer, one of the goals about FreeBSD 7 will be to 
get the system less dependent on Giant. For example one wants all network 
drivers out of Giant. There are USB network drivers also. This means that the 
USB transfer callbacks must be called with a custom lock locked and not 
Giant, else one gets a locking order reversal problem somewhere in the 
system. This sounds simple, but just try to implement it, and you will see 
another problem pop up: Central USB procedures sleep for various reasons. For 
example "bus_dma" is used to allocate memory on the fly. If one is in a 
timeout and wants to start a USB transfer, it is not a good idea to sleep, 
and then one needs another thread and _no_, just forget it. One can do it, 
but trust me, it make things terribly complicated. Look at this analogy:

        mtx_unlock(&sc->sc_mtx);

        /* "uiomove()" can sleep so one
         * needs to make a wrapper, exiting
         * the mutex and checking things
         */
        error = uiomove(cp, n, uio);

Every time one re-enters a mutex, one has to check things, hence something can 
have happended like that the device was unplugged, file closed, transfer 
stopped ... whatever. In the existing USB system one simply does not care at 
all about this. One can find "uiomove" called without any checks afterwards, 
several places in the existing USB device drivers. Most of the time nothing 
goes wrong. But the panic screen should not be the only motivation to do 
something.

        mtx_lock(&sc->sc_mtx);

        sce->state &= ~context_bit;

Extra checking, like shown below and its accompanying complexity can be 
completly elliminated if the USB system is non-blocking:

        if(sce->state & UGEN_CLOSING)
        {
                wakeup(sce);
                error = EINTR;
        }
        return error;

Of course some things will be blocking, but these functions can be factored 
out to be called from attach/detach only. That is what I have done.

I don't know if anyone else has tried to get the USB system out of Giant. It 
would be interesting to hear their experiences.

--HPS


More information about the freebsd-usb mailing list