diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2010-06-09 17:34:05 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-10 17:35:33 -0400 |
commit | 96e077ae347912dfce0e93f5958efc3ed6f311f4 (patch) | |
tree | 58eef1baba1052090daa8c457936c1a1ff66b470 /drivers/usb | |
parent | b34d8915c413acb51d837a45fb8747b61f65c020 (diff) |
USB: fix failure path in usb_add_hcd()
This patch (as1389) fixes some errors in the failure pathway of
usb_add_hcd(). The actions it takes ought to be exactly the same as
those taken by usb_remove_hcd(), but they aren't.
In one case (removal of the usb_bus_attr_group), the two routines are
brought into agreement by changing usb_remove_hcd(). All the other
discrepancies are fixed by changing usb_add_hcd().
Signed-off-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/hcd.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 12742f152f4..caae4625a1f 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -2229,7 +2229,7 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
2229 | rhdev->speed = USB_SPEED_SUPER; | 2229 | rhdev->speed = USB_SPEED_SUPER; |
2230 | break; | 2230 | break; |
2231 | default: | 2231 | default: |
2232 | goto err_allocate_root_hub; | 2232 | goto err_set_rh_speed; |
2233 | } | 2233 | } |
2234 | hcd->self.root_hub = rhdev; | 2234 | hcd->self.root_hub = rhdev; |
2235 | 2235 | ||
@@ -2305,16 +2305,29 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
2305 | return retval; | 2305 | return retval; |
2306 | 2306 | ||
2307 | error_create_attr_group: | 2307 | error_create_attr_group: |
2308 | if (HC_IS_RUNNING(hcd->state)) | ||
2309 | hcd->state = HC_STATE_QUIESCING; | ||
2310 | spin_lock_irq(&hcd_root_hub_lock); | ||
2311 | hcd->rh_registered = 0; | ||
2312 | spin_unlock_irq(&hcd_root_hub_lock); | ||
2313 | |||
2314 | #ifdef CONFIG_USB_SUSPEND | ||
2315 | cancel_work_sync(&hcd->wakeup_work); | ||
2316 | #endif | ||
2308 | mutex_lock(&usb_bus_list_lock); | 2317 | mutex_lock(&usb_bus_list_lock); |
2309 | usb_disconnect(&hcd->self.root_hub); | 2318 | usb_disconnect(&hcd->self.root_hub); |
2310 | mutex_unlock(&usb_bus_list_lock); | 2319 | mutex_unlock(&usb_bus_list_lock); |
2311 | err_register_root_hub: | 2320 | err_register_root_hub: |
2312 | hcd->driver->stop(hcd); | 2321 | hcd->driver->stop(hcd); |
2322 | hcd->state = HC_STATE_HALT; | ||
2323 | hcd->poll_rh = 0; | ||
2324 | del_timer_sync(&hcd->rh_timer); | ||
2313 | err_hcd_driver_start: | 2325 | err_hcd_driver_start: |
2314 | if (hcd->irq >= 0) | 2326 | if (hcd->irq >= 0) |
2315 | free_irq(irqnum, hcd); | 2327 | free_irq(irqnum, hcd); |
2316 | err_request_irq: | 2328 | err_request_irq: |
2317 | err_hcd_driver_setup: | 2329 | err_hcd_driver_setup: |
2330 | err_set_rh_speed: | ||
2318 | hcd->self.root_hub = NULL; | 2331 | hcd->self.root_hub = NULL; |
2319 | usb_put_dev(rhdev); | 2332 | usb_put_dev(rhdev); |
2320 | err_allocate_root_hub: | 2333 | err_allocate_root_hub: |
@@ -2337,6 +2350,8 @@ void usb_remove_hcd(struct usb_hcd *hcd) | |||
2337 | { | 2350 | { |
2338 | dev_info(hcd->self.controller, "remove, state %x\n", hcd->state); | 2351 | dev_info(hcd->self.controller, "remove, state %x\n", hcd->state); |
2339 | 2352 | ||
2353 | sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group); | ||
2354 | |||
2340 | if (HC_IS_RUNNING (hcd->state)) | 2355 | if (HC_IS_RUNNING (hcd->state)) |
2341 | hcd->state = HC_STATE_QUIESCING; | 2356 | hcd->state = HC_STATE_QUIESCING; |
2342 | 2357 | ||
@@ -2349,7 +2364,6 @@ void usb_remove_hcd(struct usb_hcd *hcd) | |||
2349 | cancel_work_sync(&hcd->wakeup_work); | 2364 | cancel_work_sync(&hcd->wakeup_work); |
2350 | #endif | 2365 | #endif |
2351 | 2366 | ||
2352 | sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group); | ||
2353 | mutex_lock(&usb_bus_list_lock); | 2367 | mutex_lock(&usb_bus_list_lock); |
2354 | usb_disconnect(&hcd->self.root_hub); | 2368 | usb_disconnect(&hcd->self.root_hub); |
2355 | mutex_unlock(&usb_bus_list_lock); | 2369 | mutex_unlock(&usb_bus_list_lock); |