Am Donnerstag, 27. August 2009 04:25:49 schrieb Alan Stern: > On Thu, 27 Aug 2009, Oliver Neukum wrote: > > If usb_set_interface() needs to be called during probing, it > > may return an error which needs to be checked for. > > You didn't add a comparable check to usb_unbind_interface(). If the > usb_set_interface() call in there fails, you should set > intf->needs_altsetting0. Indeedd. Regards Oliver Signed-off-by: Oliver Neukum <oliver@xxxxxxxxxx> -- commit 25fc22f503ffc9e93eb339cb5fa1dc18d7cc2c7a Author: Oliver Neukum <oliver@xxxxxxxxxx> Date: Thu Aug 27 15:54:13 2009 +0200 usb: check for IO errors usb_set_interface can return if they happen while unbinding a flag is set to retry upon probe if they happen during probe they are handled as probe errors diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 69e5773..9d8bc8c 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -236,24 +236,30 @@ static int usb_probe_interface(struct device *dev) /* Carry out a deferred switch to altsetting 0 */ if (intf->needs_altsetting0) { - usb_set_interface(udev, intf->altsetting[0]. + error = usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); + if (error < 0) + goto err; + intf->needs_altsetting0 = 0; } error = driver->probe(intf, id); - if (error) { - mark_quiesced(intf); - intf->needs_remote_wakeup = 0; - intf->condition = USB_INTERFACE_UNBOUND; - usb_cancel_queued_reset(intf); - } else - intf->condition = USB_INTERFACE_BOUND; + if (error) + goto err; + intf->condition = USB_INTERFACE_BOUND; usb_autosuspend_device(udev); } return error; + +err: + mark_quiesced(intf); + intf->needs_remote_wakeup = 0; + intf->condition = USB_INTERFACE_UNBOUND; + usb_cancel_queued_reset(intf); + return error; } /* called from driver core with dev locked */ @@ -262,7 +268,7 @@ static int usb_unbind_interface(struct device *dev) struct usb_driver *driver = to_usb_driver(dev->driver); struct usb_interface *intf = to_usb_interface(dev); struct usb_device *udev; - int error; + int error, r; intf->condition = USB_INTERFACE_UNBINDING; @@ -290,11 +296,14 @@ static int usb_unbind_interface(struct device *dev) * Just re-enable it without affecting the endpoint toggles. */ usb_enable_interface(udev, intf, false); - } else if (!error && intf->dev.power.status == DPM_ON) - usb_set_interface(udev, intf->altsetting[0]. + } else if (!error && intf->dev.power.status == DPM_ON) { + r = usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); - else + if (r < 0) + intf->needs_altsetting0 = 1; + } else { intf->needs_altsetting0 = 1; + } usb_set_intfdata(intf, NULL); intf->condition = USB_INTERFACE_UNBOUND; -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html