On Wednesday 12 November 2003 17:47, Alan Stern wrote:
> On Wed, 12 Nov 2003, Duncan Sands wrote:
> > I'm getting various oopses in 2.6 due to actconfig being NULL
> > unexpectedly in devio.c, namely in these releaseintf and findintif:
> >
> > The first oops occurs always at system shutdown.  The second oops occurs
> > sometimes at system startup.  I can "fix" the first one by replacing
> >     down(&dev->serialize);
> > with
> >     lock_kernel();
> > and
> >     up(&dev->serialize);
> > with
> >     unlock_kernel();
> > in releasintf.  The logic here is that although usbdev_release takes the
> > BKL, it can lose it while sleeping in the down(&dev->serialize) in
> > releaseintf, which is not what is intended I guess (and since it
> > eliminates the first oops, there must be some truth to this theory). 
> > However things are more complicated because
> > usb_driver_release_interface(&usbdevfs_driver, iface) can also sleep,
> > which might also cause problems.  I haven't analysed this yet.  Maybe
> > this change also fixed the second oops, but since that one only occurs
> > about one time in four, it is hard to be sure.
> >
> > I will of course look into this further, but I thought I would mention it
> > now in case anyone has any ideas.
>
> Usbfs is full of locking errors.  In particular, there's no excuse for it
> holding the BKL.
>
> In this case, the simplest solution is simply to insert a test for
> actconfig != NULL before it gets dereferenced.  To make certain that
> actconfig won't change out from under you, be sure to hold dev->serialize
> during that test.
>
> The real problem is that usbfs is trying to unbind a driver after usbcore
> has already done so on its behalf.  A better fix would be to repair
> driver_disconnect() and the USBDEVFS_DISCONNECT case in proc_ioctl()
> to make them use the
>
>       test_and_clear_bit(intf, &ps->ifclaimed)
>
> test as they should.

Hi Alan, looking through devio.c I see many problems.  A basic problem is
that disconnect methods are now per-interface, but usbfs is still working
on the per-device model.  For example, in driver_disconnect the whole
of ps->ifclaimed is reset to zero, not just the bit for the interface in question.
The same goes for the use of ps->dev = NULL to indicate disconnection.
That just doesn't mean anything any more - the device hasn't been disconnected,
just one interface.  It seems to me that this is all easy to fix:

(1) take a reference to the usb device in usbdev_open (drop it in usbdev_release).
(2) don't set ps->dev to NULL in driver_disconnect
(3) just clear the right bit, and use destroy_async_on_interface in driver_disconnect

Et voila as they say around here.

Duncan.

PS: I don't see what this has to do with my oopsen though :)


-------------------------------------------------------
This SF.Net email sponsored by: ApacheCon 2003,
16-19 November in Las Vegas. Learn firsthand the latest
developments in Apache, PHP, Perl, XML, Java, MySQL,
WebDAV, and more! http://www.apachecon.com/
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to