aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.org>2009-08-27 10:46:56 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 09:46:39 -0400
commit1e5ea5e32043094d96ca1e501110c1fbb631f693 (patch)
tree2bbf4930d45221889d100ac03f346e041aebfc2f /drivers/usb
parent01c6460f968d7b57fc6f98adb587952628c6e099 (diff)
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>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/driver.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 1c976c141f33..4f864472c5c4 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -239,24 +239,31 @@ static int usb_probe_interface(struct device *dev)
239 239
240 /* Carry out a deferred switch to altsetting 0 */ 240 /* Carry out a deferred switch to altsetting 0 */
241 if (intf->needs_altsetting0) { 241 if (intf->needs_altsetting0) {
242 usb_set_interface(udev, intf->altsetting[0]. 242 error = usb_set_interface(udev, intf->altsetting[0].
243 desc.bInterfaceNumber, 0); 243 desc.bInterfaceNumber, 0);
244 if (error < 0)
245 goto err;
246
244 intf->needs_altsetting0 = 0; 247 intf->needs_altsetting0 = 0;
245 } 248 }
246 249
247 error = driver->probe(intf, id); 250 error = driver->probe(intf, id);
248 if (error) { 251 if (error)
249 mark_quiesced(intf); 252 goto err;
250 intf->needs_remote_wakeup = 0;
251 intf->condition = USB_INTERFACE_UNBOUND;
252 usb_cancel_queued_reset(intf);
253 } else
254 intf->condition = USB_INTERFACE_BOUND;
255 253
254 intf->condition = USB_INTERFACE_BOUND;
256 usb_autosuspend_device(udev); 255 usb_autosuspend_device(udev);
257 } 256 }
258 257
259 return error; 258 return error;
259
260err:
261 mark_quiesced(intf);
262 intf->needs_remote_wakeup = 0;
263 intf->condition = USB_INTERFACE_UNBOUND;
264 usb_cancel_queued_reset(intf);
265 usb_autosuspend_device(udev);
266 return error;
260} 267}
261 268
262/* called from driver core with dev locked */ 269/* called from driver core with dev locked */
@@ -265,7 +272,7 @@ static int usb_unbind_interface(struct device *dev)
265 struct usb_driver *driver = to_usb_driver(dev->driver); 272 struct usb_driver *driver = to_usb_driver(dev->driver);
266 struct usb_interface *intf = to_usb_interface(dev); 273 struct usb_interface *intf = to_usb_interface(dev);
267 struct usb_device *udev; 274 struct usb_device *udev;
268 int error; 275 int error, r;
269 276
270 intf->condition = USB_INTERFACE_UNBINDING; 277 intf->condition = USB_INTERFACE_UNBINDING;
271 278
@@ -293,11 +300,14 @@ static int usb_unbind_interface(struct device *dev)
293 * Just re-enable it without affecting the endpoint toggles. 300 * Just re-enable it without affecting the endpoint toggles.
294 */ 301 */
295 usb_enable_interface(udev, intf, false); 302 usb_enable_interface(udev, intf, false);
296 } else if (!error && intf->dev.power.status == DPM_ON) 303 } else if (!error && intf->dev.power.status == DPM_ON) {
297 usb_set_interface(udev, intf->altsetting[0]. 304 r = usb_set_interface(udev, intf->altsetting[0].
298 desc.bInterfaceNumber, 0); 305 desc.bInterfaceNumber, 0);
299 else 306 if (r < 0)
307 intf->needs_altsetting0 = 1;
308 } else {
300 intf->needs_altsetting0 = 1; 309 intf->needs_altsetting0 = 1;
310 }
301 usb_set_intfdata(intf, NULL); 311 usb_set_intfdata(intf, NULL);
302 312
303 intf->condition = USB_INTERFACE_UNBOUND; 313 intf->condition = USB_INTERFACE_UNBOUND;