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: Oliver Neukum <oliver@neukum.org> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
01c6460f96
commit
1e5ea5e320
@@ -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)
|
|||||||
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)
|
|||||||
* 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;
|
intf->needs_altsetting0 = 1;
|
||||||
|
} else {
|
||||||
|
intf->needs_altsetting0 = 1;
|
||||||
|
}
|
||||||
usb_set_intfdata(intf, NULL);
|
usb_set_intfdata(intf, NULL);
|
||||||
|
|
||||||
intf->condition = USB_INTERFACE_UNBOUND;
|
intf->condition = USB_INTERFACE_UNBOUND;
|
||||||
|
Reference in New Issue
Block a user