Commit 1e5ea5e3 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman

USB: fix missing error check in probing

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
Signed-off-by: default avatarOliver Neukum <oliver@neukum.org>
Acked-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 01c6460f
...@@ -239,23 +239,30 @@ static int usb_probe_interface(struct device *dev) ...@@ -239,23 +239,30 @@ static int usb_probe_interface(struct device *dev)
/* Carry out a deferred switch to altsetting 0 */ /* Carry out a deferred switch to altsetting 0 */
if (intf->needs_altsetting0) { if (intf->needs_altsetting0) {
usb_set_interface(udev, intf->altsetting[0]. error = usb_set_interface(udev, intf->altsetting[0].
desc.bInterfaceNumber, 0); desc.bInterfaceNumber, 0);
if (error < 0)
goto err;
intf->needs_altsetting0 = 0; intf->needs_altsetting0 = 0;
} }
error = driver->probe(intf, id); error = driver->probe(intf, id);
if (error) { if (error)
goto err;
intf->condition = USB_INTERFACE_BOUND;
usb_autosuspend_device(udev);
}
return error;
err:
mark_quiesced(intf); mark_quiesced(intf);
intf->needs_remote_wakeup = 0; intf->needs_remote_wakeup = 0;
intf->condition = USB_INTERFACE_UNBOUND; intf->condition = USB_INTERFACE_UNBOUND;
usb_cancel_queued_reset(intf); usb_cancel_queued_reset(intf);
} else
intf->condition = USB_INTERFACE_BOUND;
usb_autosuspend_device(udev); usb_autosuspend_device(udev);
}
return error; return error;
} }
...@@ -265,7 +272,7 @@ static int usb_unbind_interface(struct device *dev) ...@@ -265,7 +272,7 @@ static int usb_unbind_interface(struct device *dev)
struct usb_driver *driver = to_usb_driver(dev->driver); struct usb_driver *driver = to_usb_driver(dev->driver);
struct usb_interface *intf = to_usb_interface(dev); struct usb_interface *intf = to_usb_interface(dev);
struct usb_device *udev; struct usb_device *udev;
int error; int error, r;
intf->condition = USB_INTERFACE_UNBINDING; intf->condition = USB_INTERFACE_UNBINDING;
...@@ -293,11 +300,14 @@ static int usb_unbind_interface(struct device *dev) ...@@ -293,11 +300,14 @@ static int usb_unbind_interface(struct device *dev)
* Just re-enable it without affecting the endpoint toggles. * Just re-enable it without affecting the endpoint toggles.
*/ */
usb_enable_interface(udev, intf, false); usb_enable_interface(udev, intf, false);
} else if (!error && intf->dev.power.status == DPM_ON) } else if (!error && intf->dev.power.status == DPM_ON) {
usb_set_interface(udev, intf->altsetting[0]. r = usb_set_interface(udev, intf->altsetting[0].
desc.bInterfaceNumber, 0); desc.bInterfaceNumber, 0);
else if (r < 0)
intf->needs_altsetting0 = 1;
} else {
intf->needs_altsetting0 = 1; intf->needs_altsetting0 = 1;
}
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
intf->condition = USB_INTERFACE_UNBOUND; intf->condition = USB_INTERFACE_UNBOUND;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment