aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2010-06-09 17:34:05 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 17:35:33 -0400
commit96e077ae347912dfce0e93f5958efc3ed6f311f4 (patch)
tree58eef1baba1052090daa8c457936c1a1ff66b470 /drivers/usb
parentb34d8915c413acb51d837a45fb8747b61f65c020 (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.c18
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
2307error_create_attr_group: 2307error_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);
2311err_register_root_hub: 2320err_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);
2313err_hcd_driver_start: 2325err_hcd_driver_start:
2314 if (hcd->irq >= 0) 2326 if (hcd->irq >= 0)
2315 free_irq(irqnum, hcd); 2327 free_irq(irqnum, hcd);
2316err_request_irq: 2328err_request_irq:
2317err_hcd_driver_setup: 2329err_hcd_driver_setup:
2330err_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);
2320err_allocate_root_hub: 2333err_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);