aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2011-03-07 11:11:52 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-03-07 15:14:06 -0500
commit9b37596a2e860404503a3f2a6513db60c296bfdc (patch)
treef47f8e38895d0ce9db252328f686482bad79716f /drivers/usb
parente4738e29bef8ed9bdd8a0606d0561557b4547649 (diff)
USB: move usbcore away from hcd->state
The hcd->state variable is a disaster. It's not clearly owned by either usbcore or the host controller drivers, and they both change it from time to time, potentially stepping on each other's toes. It's not protected by any locks. And there's no mechanism to prevent it from going through an invalid transition. This patch (as1451) takes a first step toward fixing these problems. As it turns out, usbcore uses hcd->state for essentially only two things: checking whether the controller's root hub is running and checking whether the controller has died. Therefore the patch adds two new atomic bitflags to the hcd structure, to store these pieces of information. The new flags are used only by usbcore, and a private spinlock prevents invalid combinations (a dead controller's root hub cannot be running). The patch does not change the places where usbcore sets hcd->state, since HCDs may depend on them. Furthermore, there is one place in usb_hcd_irq() where usbcore still must use hcd->state: An HCD's interrupt handler can implicitly indicate that the controller died by setting hcd->state to HC_STATE_HALT. Nevertheless, the new code is a big improvement over the current code. The patch makes one other change. The hcd_bus_suspend() and hcd_bus_resume() routines now check first whether the host controller has died; if it has then they return immediately without calling the HCD's bus_suspend or bus_resume methods. This fixes the major problem reported in Bugzilla #29902: The system fails to suspend after a host controller dies during system resume. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Tested-by: Alex Terekhov <a.terekhov@gmail.com> CC: <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/hcd-pci.c13
-rw-r--r--drivers/usb/core/hcd.c55
2 files changed, 47 insertions, 21 deletions
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index f71e8e307e0f..d37088591d9a 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -363,8 +363,7 @@ static int check_root_hub_suspended(struct device *dev)
363 struct pci_dev *pci_dev = to_pci_dev(dev); 363 struct pci_dev *pci_dev = to_pci_dev(dev);
364 struct usb_hcd *hcd = pci_get_drvdata(pci_dev); 364 struct usb_hcd *hcd = pci_get_drvdata(pci_dev);
365 365
366 if (!(hcd->state == HC_STATE_SUSPENDED || 366 if (HCD_RH_RUNNING(hcd)) {
367 hcd->state == HC_STATE_HALT)) {
368 dev_warn(dev, "Root hub is not suspended\n"); 367 dev_warn(dev, "Root hub is not suspended\n");
369 return -EBUSY; 368 return -EBUSY;
370 } 369 }
@@ -386,7 +385,7 @@ static int suspend_common(struct device *dev, bool do_wakeup)
386 if (retval) 385 if (retval)
387 return retval; 386 return retval;
388 387
389 if (hcd->driver->pci_suspend) { 388 if (hcd->driver->pci_suspend && !HCD_DEAD(hcd)) {
390 /* Optimization: Don't suspend if a root-hub wakeup is 389 /* Optimization: Don't suspend if a root-hub wakeup is
391 * pending and it would cause the HCD to wake up anyway. 390 * pending and it would cause the HCD to wake up anyway.
392 */ 391 */
@@ -427,7 +426,7 @@ static int resume_common(struct device *dev, int event)
427 struct usb_hcd *hcd = pci_get_drvdata(pci_dev); 426 struct usb_hcd *hcd = pci_get_drvdata(pci_dev);
428 int retval; 427 int retval;
429 428
430 if (hcd->state != HC_STATE_SUSPENDED) { 429 if (HCD_RH_RUNNING(hcd)) {
431 dev_dbg(dev, "can't resume, not suspended!\n"); 430 dev_dbg(dev, "can't resume, not suspended!\n");
432 return 0; 431 return 0;
433 } 432 }
@@ -442,7 +441,7 @@ static int resume_common(struct device *dev, int event)
442 441
443 clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); 442 clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
444 443
445 if (hcd->driver->pci_resume) { 444 if (hcd->driver->pci_resume && !HCD_DEAD(hcd)) {
446 if (event != PM_EVENT_AUTO_RESUME) 445 if (event != PM_EVENT_AUTO_RESUME)
447 wait_for_companions(pci_dev, hcd); 446 wait_for_companions(pci_dev, hcd);
448 447
@@ -475,10 +474,10 @@ static int hcd_pci_suspend_noirq(struct device *dev)
475 474
476 pci_save_state(pci_dev); 475 pci_save_state(pci_dev);
477 476
478 /* If the root hub is HALTed rather than SUSPENDed, 477 /* If the root hub is dead rather than suspended,
479 * disallow remote wakeup. 478 * disallow remote wakeup.
480 */ 479 */
481 if (hcd->state == HC_STATE_HALT) 480 if (HCD_DEAD(hcd))
482 device_set_wakeup_enable(dev, 0); 481 device_set_wakeup_enable(dev, 0);
483 dev_dbg(dev, "wakeup: %d\n", device_may_wakeup(dev)); 482 dev_dbg(dev, "wakeup: %d\n", device_may_wakeup(dev));
484 483
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 24765fd6cf12..e7d0c4571bbe 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -983,7 +983,7 @@ static int register_root_hub(struct usb_hcd *hcd)
983 spin_unlock_irq (&hcd_root_hub_lock); 983 spin_unlock_irq (&hcd_root_hub_lock);
984 984
985 /* Did the HC die before the root hub was registered? */ 985 /* Did the HC die before the root hub was registered? */
986 if (hcd->state == HC_STATE_HALT) 986 if (HCD_DEAD(hcd) || hcd->state == HC_STATE_HALT)
987 usb_hc_died (hcd); /* This time clean up */ 987 usb_hc_died (hcd); /* This time clean up */
988 } 988 }
989 989
@@ -1089,13 +1089,10 @@ int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb)
1089 * Check the host controller's state and add the URB to the 1089 * Check the host controller's state and add the URB to the
1090 * endpoint's queue. 1090 * endpoint's queue.
1091 */ 1091 */
1092 switch (hcd->state) { 1092 if (HCD_RH_RUNNING(hcd)) {
1093 case HC_STATE_RUNNING:
1094 case HC_STATE_RESUMING:
1095 urb->unlinked = 0; 1093 urb->unlinked = 0;
1096 list_add_tail(&urb->urb_list, &urb->ep->urb_list); 1094 list_add_tail(&urb->urb_list, &urb->ep->urb_list);
1097 break; 1095 } else {
1098 default:
1099 rc = -ESHUTDOWN; 1096 rc = -ESHUTDOWN;
1100 goto done; 1097 goto done;
1101 } 1098 }
@@ -1931,7 +1928,7 @@ int usb_hcd_get_frame_number (struct usb_device *udev)
1931{ 1928{
1932 struct usb_hcd *hcd = bus_to_hcd(udev->bus); 1929 struct usb_hcd *hcd = bus_to_hcd(udev->bus);
1933 1930
1934 if (!HC_IS_RUNNING (hcd->state)) 1931 if (!HCD_RH_RUNNING(hcd))
1935 return -ESHUTDOWN; 1932 return -ESHUTDOWN;
1936 return hcd->driver->get_frame_number (hcd); 1933 return hcd->driver->get_frame_number (hcd);
1937} 1934}
@@ -1948,9 +1945,15 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)
1948 1945
1949 dev_dbg(&rhdev->dev, "bus %s%s\n", 1946 dev_dbg(&rhdev->dev, "bus %s%s\n",
1950 (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "suspend"); 1947 (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "suspend");
1948 if (HCD_DEAD(hcd)) {
1949 dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "suspend");
1950 return 0;
1951 }
1952
1951 if (!hcd->driver->bus_suspend) { 1953 if (!hcd->driver->bus_suspend) {
1952 status = -ENOENT; 1954 status = -ENOENT;
1953 } else { 1955 } else {
1956 clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
1954 hcd->state = HC_STATE_QUIESCING; 1957 hcd->state = HC_STATE_QUIESCING;
1955 status = hcd->driver->bus_suspend(hcd); 1958 status = hcd->driver->bus_suspend(hcd);
1956 } 1959 }
@@ -1958,7 +1961,12 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)
1958 usb_set_device_state(rhdev, USB_STATE_SUSPENDED); 1961 usb_set_device_state(rhdev, USB_STATE_SUSPENDED);
1959 hcd->state = HC_STATE_SUSPENDED; 1962 hcd->state = HC_STATE_SUSPENDED;
1960 } else { 1963 } else {
1961 hcd->state = old_state; 1964 spin_lock_irq(&hcd_root_hub_lock);
1965 if (!HCD_DEAD(hcd)) {
1966 set_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
1967 hcd->state = old_state;
1968 }
1969 spin_unlock_irq(&hcd_root_hub_lock);
1962 dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", 1970 dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
1963 "suspend", status); 1971 "suspend", status);
1964 } 1972 }
@@ -1973,9 +1981,13 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
1973 1981
1974 dev_dbg(&rhdev->dev, "usb %s%s\n", 1982 dev_dbg(&rhdev->dev, "usb %s%s\n",
1975 (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume"); 1983 (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume");
1984 if (HCD_DEAD(hcd)) {
1985 dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "resume");
1986 return 0;
1987 }
1976 if (!hcd->driver->bus_resume) 1988 if (!hcd->driver->bus_resume)
1977 return -ENOENT; 1989 return -ENOENT;
1978 if (hcd->state == HC_STATE_RUNNING) 1990 if (HCD_RH_RUNNING(hcd))
1979 return 0; 1991 return 0;
1980 1992
1981 hcd->state = HC_STATE_RESUMING; 1993 hcd->state = HC_STATE_RESUMING;
@@ -1984,10 +1996,15 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
1984 if (status == 0) { 1996 if (status == 0) {
1985 /* TRSMRCY = 10 msec */ 1997 /* TRSMRCY = 10 msec */
1986 msleep(10); 1998 msleep(10);
1987 usb_set_device_state(rhdev, rhdev->actconfig 1999 spin_lock_irq(&hcd_root_hub_lock);
1988 ? USB_STATE_CONFIGURED 2000 if (!HCD_DEAD(hcd)) {
1989 : USB_STATE_ADDRESS); 2001 usb_set_device_state(rhdev, rhdev->actconfig
1990 hcd->state = HC_STATE_RUNNING; 2002 ? USB_STATE_CONFIGURED
2003 : USB_STATE_ADDRESS);
2004 set_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
2005 hcd->state = HC_STATE_RUNNING;
2006 }
2007 spin_unlock_irq(&hcd_root_hub_lock);
1991 } else { 2008 } else {
1992 hcd->state = old_state; 2009 hcd->state = old_state;
1993 dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", 2010 dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
@@ -2098,7 +2115,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd)
2098 */ 2115 */
2099 local_irq_save(flags); 2116 local_irq_save(flags);
2100 2117
2101 if (unlikely(hcd->state == HC_STATE_HALT || !HCD_HW_ACCESSIBLE(hcd))) { 2118 if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) {
2102 rc = IRQ_NONE; 2119 rc = IRQ_NONE;
2103 } else if (hcd->driver->irq(hcd) == IRQ_NONE) { 2120 } else if (hcd->driver->irq(hcd) == IRQ_NONE) {
2104 rc = IRQ_NONE; 2121 rc = IRQ_NONE;
@@ -2132,6 +2149,8 @@ void usb_hc_died (struct usb_hcd *hcd)
2132 dev_err (hcd->self.controller, "HC died; cleaning up\n"); 2149 dev_err (hcd->self.controller, "HC died; cleaning up\n");
2133 2150
2134 spin_lock_irqsave (&hcd_root_hub_lock, flags); 2151 spin_lock_irqsave (&hcd_root_hub_lock, flags);
2152 clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
2153 set_bit(HCD_FLAG_DEAD, &hcd->flags);
2135 if (hcd->rh_registered) { 2154 if (hcd->rh_registered) {
2136 clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); 2155 clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
2137 2156
@@ -2274,6 +2293,12 @@ int usb_add_hcd(struct usb_hcd *hcd,
2274 */ 2293 */
2275 device_init_wakeup(&rhdev->dev, 1); 2294 device_init_wakeup(&rhdev->dev, 1);
2276 2295
2296 /* HCD_FLAG_RH_RUNNING doesn't matter until the root hub is
2297 * registered. But since the controller can die at any time,
2298 * let's initialize the flag before touching the hardware.
2299 */
2300 set_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
2301
2277 /* "reset" is misnamed; its role is now one-time init. the controller 2302 /* "reset" is misnamed; its role is now one-time init. the controller
2278 * should already have been reset (and boot firmware kicked off etc). 2303 * should already have been reset (and boot firmware kicked off etc).
2279 */ 2304 */
@@ -2341,6 +2366,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
2341 return retval; 2366 return retval;
2342 2367
2343error_create_attr_group: 2368error_create_attr_group:
2369 clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
2344 if (HC_IS_RUNNING(hcd->state)) 2370 if (HC_IS_RUNNING(hcd->state))
2345 hcd->state = HC_STATE_QUIESCING; 2371 hcd->state = HC_STATE_QUIESCING;
2346 spin_lock_irq(&hcd_root_hub_lock); 2372 spin_lock_irq(&hcd_root_hub_lock);
@@ -2393,6 +2419,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
2393 usb_get_dev(rhdev); 2419 usb_get_dev(rhdev);
2394 sysfs_remove_group(&rhdev->dev.kobj, &usb_bus_attr_group); 2420 sysfs_remove_group(&rhdev->dev.kobj, &usb_bus_attr_group);
2395 2421
2422 clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
2396 if (HC_IS_RUNNING (hcd->state)) 2423 if (HC_IS_RUNNING (hcd->state))
2397 hcd->state = HC_STATE_QUIESCING; 2424 hcd->state = HC_STATE_QUIESCING;
2398 2425