diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/core/driver.c | 63 |
1 files changed, 31 insertions, 32 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index f2f055eb6831..fcafb2dce3ac 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -274,56 +274,55 @@ static int usb_probe_interface(struct device *dev) | |||
274 | intf->needs_binding = 0; | 274 | intf->needs_binding = 0; |
275 | 275 | ||
276 | if (usb_device_is_owned(udev)) | 276 | if (usb_device_is_owned(udev)) |
277 | return -ENODEV; | 277 | return error; |
278 | 278 | ||
279 | if (udev->authorized == 0) { | 279 | if (udev->authorized == 0) { |
280 | dev_err(&intf->dev, "Device is not authorized for usage\n"); | 280 | dev_err(&intf->dev, "Device is not authorized for usage\n"); |
281 | return -ENODEV; | 281 | return error; |
282 | } | 282 | } |
283 | 283 | ||
284 | id = usb_match_id(intf, driver->id_table); | 284 | id = usb_match_id(intf, driver->id_table); |
285 | if (!id) | 285 | if (!id) |
286 | id = usb_match_dynamic_id(intf, driver); | 286 | id = usb_match_dynamic_id(intf, driver); |
287 | if (id) { | 287 | if (!id) |
288 | dev_dbg(dev, "%s - got id\n", __func__); | 288 | return error; |
289 | |||
290 | error = usb_autoresume_device(udev); | ||
291 | if (error) | ||
292 | return error; | ||
293 | 289 | ||
294 | /* Interface "power state" doesn't correspond to any hardware | 290 | dev_dbg(dev, "%s - got id\n", __func__); |
295 | * state whatsoever. We use it to record when it's bound to | ||
296 | * a driver that may start I/0: it's not frozen/quiesced. | ||
297 | */ | ||
298 | mark_active(intf); | ||
299 | intf->condition = USB_INTERFACE_BINDING; | ||
300 | 291 | ||
301 | /* The interface should always appear to be in use | 292 | error = usb_autoresume_device(udev); |
302 | * unless the driver suports autosuspend. | 293 | if (error) |
303 | */ | 294 | return error; |
304 | atomic_set(&intf->pm_usage_cnt, !driver->supports_autosuspend); | ||
305 | 295 | ||
306 | /* Carry out a deferred switch to altsetting 0 */ | 296 | /* Interface "power state" doesn't correspond to any hardware |
307 | if (intf->needs_altsetting0) { | 297 | * state whatsoever. We use it to record when it's bound to |
308 | error = usb_set_interface(udev, intf->altsetting[0]. | 298 | * a driver that may start I/0: it's not frozen/quiesced. |
309 | desc.bInterfaceNumber, 0); | 299 | */ |
310 | if (error < 0) | 300 | mark_active(intf); |
311 | goto err; | 301 | intf->condition = USB_INTERFACE_BINDING; |
312 | 302 | ||
313 | intf->needs_altsetting0 = 0; | 303 | /* The interface should always appear to be in use |
314 | } | 304 | * unless the driver suports autosuspend. |
305 | */ | ||
306 | atomic_set(&intf->pm_usage_cnt, !driver->supports_autosuspend); | ||
315 | 307 | ||
316 | error = driver->probe(intf, id); | 308 | /* Carry out a deferred switch to altsetting 0 */ |
317 | if (error) | 309 | if (intf->needs_altsetting0) { |
310 | error = usb_set_interface(udev, intf->altsetting[0]. | ||
311 | desc.bInterfaceNumber, 0); | ||
312 | if (error < 0) | ||
318 | goto err; | 313 | goto err; |
319 | 314 | intf->needs_altsetting0 = 0; | |
320 | intf->condition = USB_INTERFACE_BOUND; | ||
321 | usb_autosuspend_device(udev); | ||
322 | } | 315 | } |
323 | 316 | ||
317 | error = driver->probe(intf, id); | ||
318 | if (error) | ||
319 | goto err; | ||
320 | |||
321 | intf->condition = USB_INTERFACE_BOUND; | ||
322 | usb_autosuspend_device(udev); | ||
324 | return error; | 323 | return error; |
325 | 324 | ||
326 | err: | 325 | err: |
327 | mark_quiesced(intf); | 326 | mark_quiesced(intf); |
328 | intf->needs_remote_wakeup = 0; | 327 | intf->needs_remote_wakeup = 0; |
329 | intf->condition = USB_INTERFACE_UNBOUND; | 328 | intf->condition = USB_INTERFACE_UNBOUND; |