On Thu, Jun 24, 2004 at 03:08:01PM -0400, Alan Stern wrote:
> Greg:
> 
> This patch creates a special locking routine intended specifically for use 
> when calling usb_reset_device().  A special routine like this is needed to 
> avoid deadlocks with disconnect().  Symbolically:
> 
>       Khubd                           Driver
>       -----                           ------
>                                       Wants to reset a device, so calls
>                                       its own do_reset() function
>       Receives connect-change
>       notification and calls
>       usb_disconnect()
> 
>       Locks the device and calls
>       driver->disconnect()
>                                       do_reset() tries to lock the 
>                                       device for the reset, and blocks
>       disconnect() can't return
>       until do_reset() is finished
> 
> One simple-minded way out would be for the driver's do_reset routine to 
> use usb_trylock_device().  I don't like this because it will fail if the 
> device happens to be locked for some innocuous reason, like somebody 
> reading its entry in /proc/bus/usb/devices.
> 
> Instead, usb_lock_device_for_reset() calls usb_trylock_device() 
> repeatedly, in a polling loop.  It is careful to check that the device 
> state isn't NOTATTACHED and that the driver's interface isn't being 
> unbound; this will allow the lock-and-reset sequence to fail in scenarios 
> like the one above.
> 
> For the new routine to be able to tell when an interface is being unbound, 
> I had to add an additional field to struct usb_interface.  It's a simple 
> enumeration with four possible values:
> 
>       USB_INTERFACE_UNBOUND, USB_INTERFACE_BINDING,
>       USB_INTERFACE_BOUND, USB_INTERFACE_UNBINDING
> 
> The extra overhead of the new field is not large enough to matter.
> 
> A quick summary:
> 
>       Rename __usb_reset_device to usb_reset_device and get rid of
>       the alternate entry point.
> 
>       Notify the HCD that endpoint-0's maxpacket size may change
>       during a device reset (should have been written earlier).
> 
>       Add the new usb_interface_condition enumeration field to
>       struct usb_interface.
> 
>       Set the new field appropriately as interfaces are bound,
>       unbound, claimed, and released.
> 
>       Add usb_lock_device_for_reset().
> 
>       Change the usb-storage, microtek, and stir4200 IRDA drivers
>       to make them use the new locking routine.
> 
> With this patch applied, and using an altered gadget driver that forces 
> usb-storage to request a device reset, I've been able to go through a 
> large number of different tests successfully.  Reset during probe(), 
> reset after probe(), disconnect during reset(), reset with device 
> descriptor changing...  They all work beautifully.
> 
> Please apply.

Applied, thanks.

greg k-h


-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 - 
digital self defense, top technical experts, no vendor pitches, 
unmatched networking opportunities. Visit www.blackhat.com
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to