diff options
Diffstat (limited to 'drivers/usb/core/hcd.c')
-rw-r--r-- | drivers/usb/core/hcd.c | 79 |
1 files changed, 59 insertions, 20 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 12742f152f4..5cca00a6d09 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -667,7 +667,7 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd) | |||
667 | unsigned long flags; | 667 | unsigned long flags; |
668 | char buffer[6]; /* Any root hubs with > 31 ports? */ | 668 | char buffer[6]; /* Any root hubs with > 31 ports? */ |
669 | 669 | ||
670 | if (unlikely(!hcd->rh_registered)) | 670 | if (unlikely(!hcd->rh_pollable)) |
671 | return; | 671 | return; |
672 | if (!hcd->uses_new_polling && !hcd->status_urb) | 672 | if (!hcd->uses_new_polling && !hcd->status_urb) |
673 | return; | 673 | return; |
@@ -679,7 +679,7 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd) | |||
679 | spin_lock_irqsave(&hcd_root_hub_lock, flags); | 679 | spin_lock_irqsave(&hcd_root_hub_lock, flags); |
680 | urb = hcd->status_urb; | 680 | urb = hcd->status_urb; |
681 | if (urb) { | 681 | if (urb) { |
682 | hcd->poll_pending = 0; | 682 | clear_bit(HCD_FLAG_POLL_PENDING, &hcd->flags); |
683 | hcd->status_urb = NULL; | 683 | hcd->status_urb = NULL; |
684 | urb->actual_length = length; | 684 | urb->actual_length = length; |
685 | memcpy(urb->transfer_buffer, buffer, length); | 685 | memcpy(urb->transfer_buffer, buffer, length); |
@@ -690,7 +690,7 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd) | |||
690 | spin_lock(&hcd_root_hub_lock); | 690 | spin_lock(&hcd_root_hub_lock); |
691 | } else { | 691 | } else { |
692 | length = 0; | 692 | length = 0; |
693 | hcd->poll_pending = 1; | 693 | set_bit(HCD_FLAG_POLL_PENDING, &hcd->flags); |
694 | } | 694 | } |
695 | spin_unlock_irqrestore(&hcd_root_hub_lock, flags); | 695 | spin_unlock_irqrestore(&hcd_root_hub_lock, flags); |
696 | } | 696 | } |
@@ -699,7 +699,7 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd) | |||
699 | * exceed that limit if HZ is 100. The math is more clunky than | 699 | * exceed that limit if HZ is 100. The math is more clunky than |
700 | * maybe expected, this is to make sure that all timers for USB devices | 700 | * maybe expected, this is to make sure that all timers for USB devices |
701 | * fire at the same time to give the CPU a break inbetween */ | 701 | * fire at the same time to give the CPU a break inbetween */ |
702 | if (hcd->uses_new_polling ? hcd->poll_rh : | 702 | if (hcd->uses_new_polling ? HCD_POLL_RH(hcd) : |
703 | (length == 0 && hcd->status_urb != NULL)) | 703 | (length == 0 && hcd->status_urb != NULL)) |
704 | mod_timer (&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4)); | 704 | mod_timer (&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4)); |
705 | } | 705 | } |
@@ -736,7 +736,7 @@ static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb) | |||
736 | mod_timer(&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4)); | 736 | mod_timer(&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4)); |
737 | 737 | ||
738 | /* If a status change has already occurred, report it ASAP */ | 738 | /* If a status change has already occurred, report it ASAP */ |
739 | else if (hcd->poll_pending) | 739 | else if (HCD_POLL_PENDING(hcd)) |
740 | mod_timer(&hcd->rh_timer, jiffies); | 740 | mod_timer(&hcd->rh_timer, jiffies); |
741 | retval = 0; | 741 | retval = 0; |
742 | done: | 742 | done: |
@@ -1150,8 +1150,7 @@ int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, | |||
1150 | * finish unlinking the initial failed usb_set_address() | 1150 | * finish unlinking the initial failed usb_set_address() |
1151 | * or device descriptor fetch. | 1151 | * or device descriptor fetch. |
1152 | */ | 1152 | */ |
1153 | if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags) && | 1153 | if (!HCD_SAW_IRQ(hcd) && !is_root_hub(urb->dev)) { |
1154 | !is_root_hub(urb->dev)) { | ||
1155 | dev_warn(hcd->self.controller, "Unlink after no-IRQ? " | 1154 | dev_warn(hcd->self.controller, "Unlink after no-IRQ? " |
1156 | "Controller is probably using the wrong IRQ.\n"); | 1155 | "Controller is probably using the wrong IRQ.\n"); |
1157 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | 1156 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); |
@@ -1219,6 +1218,11 @@ static int hcd_alloc_coherent(struct usb_bus *bus, | |||
1219 | { | 1218 | { |
1220 | unsigned char *vaddr; | 1219 | unsigned char *vaddr; |
1221 | 1220 | ||
1221 | if (*vaddr_handle == NULL) { | ||
1222 | WARN_ON_ONCE(1); | ||
1223 | return -EFAULT; | ||
1224 | } | ||
1225 | |||
1222 | vaddr = hcd_buffer_alloc(bus, size + sizeof(vaddr), | 1226 | vaddr = hcd_buffer_alloc(bus, size + sizeof(vaddr), |
1223 | mem_flags, dma_handle); | 1227 | mem_flags, dma_handle); |
1224 | if (!vaddr) | 1228 | if (!vaddr) |
@@ -1941,6 +1945,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) | |||
1941 | 1945 | ||
1942 | dev_dbg(&rhdev->dev, "usb %s%s\n", | 1946 | dev_dbg(&rhdev->dev, "usb %s%s\n", |
1943 | (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume"); | 1947 | (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume"); |
1948 | clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags); | ||
1944 | if (!hcd->driver->bus_resume) | 1949 | if (!hcd->driver->bus_resume) |
1945 | return -ENOENT; | 1950 | return -ENOENT; |
1946 | if (hcd->state == HC_STATE_RUNNING) | 1951 | if (hcd->state == HC_STATE_RUNNING) |
@@ -1994,8 +1999,10 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd) | |||
1994 | unsigned long flags; | 1999 | unsigned long flags; |
1995 | 2000 | ||
1996 | spin_lock_irqsave (&hcd_root_hub_lock, flags); | 2001 | spin_lock_irqsave (&hcd_root_hub_lock, flags); |
1997 | if (hcd->rh_registered) | 2002 | if (hcd->rh_registered) { |
2003 | set_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags); | ||
1998 | queue_work(pm_wq, &hcd->wakeup_work); | 2004 | queue_work(pm_wq, &hcd->wakeup_work); |
2005 | } | ||
1999 | spin_unlock_irqrestore (&hcd_root_hub_lock, flags); | 2006 | spin_unlock_irqrestore (&hcd_root_hub_lock, flags); |
2000 | } | 2007 | } |
2001 | EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub); | 2008 | EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub); |
@@ -2063,8 +2070,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) | |||
2063 | */ | 2070 | */ |
2064 | local_irq_save(flags); | 2071 | local_irq_save(flags); |
2065 | 2072 | ||
2066 | if (unlikely(hcd->state == HC_STATE_HALT || | 2073 | if (unlikely(hcd->state == HC_STATE_HALT || !HCD_HW_ACCESSIBLE(hcd))) { |
2067 | !test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) { | ||
2068 | rc = IRQ_NONE; | 2074 | rc = IRQ_NONE; |
2069 | } else if (hcd->driver->irq(hcd) == IRQ_NONE) { | 2075 | } else if (hcd->driver->irq(hcd) == IRQ_NONE) { |
2070 | rc = IRQ_NONE; | 2076 | rc = IRQ_NONE; |
@@ -2079,6 +2085,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) | |||
2079 | local_irq_restore(flags); | 2085 | local_irq_restore(flags); |
2080 | return rc; | 2086 | return rc; |
2081 | } | 2087 | } |
2088 | EXPORT_SYMBOL_GPL(usb_hcd_irq); | ||
2082 | 2089 | ||
2083 | /*-------------------------------------------------------------------------*/ | 2090 | /*-------------------------------------------------------------------------*/ |
2084 | 2091 | ||
@@ -2098,7 +2105,7 @@ void usb_hc_died (struct usb_hcd *hcd) | |||
2098 | 2105 | ||
2099 | spin_lock_irqsave (&hcd_root_hub_lock, flags); | 2106 | spin_lock_irqsave (&hcd_root_hub_lock, flags); |
2100 | if (hcd->rh_registered) { | 2107 | if (hcd->rh_registered) { |
2101 | hcd->poll_rh = 0; | 2108 | clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); |
2102 | 2109 | ||
2103 | /* make khubd clean up old urbs and devices */ | 2110 | /* make khubd clean up old urbs and devices */ |
2104 | usb_set_device_state (hcd->self.root_hub, | 2111 | usb_set_device_state (hcd->self.root_hub, |
@@ -2217,6 +2224,7 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
2217 | retval = -ENOMEM; | 2224 | retval = -ENOMEM; |
2218 | goto err_allocate_root_hub; | 2225 | goto err_allocate_root_hub; |
2219 | } | 2226 | } |
2227 | hcd->self.root_hub = rhdev; | ||
2220 | 2228 | ||
2221 | switch (hcd->driver->flags & HCD_MASK) { | 2229 | switch (hcd->driver->flags & HCD_MASK) { |
2222 | case HCD_USB11: | 2230 | case HCD_USB11: |
@@ -2229,9 +2237,8 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
2229 | rhdev->speed = USB_SPEED_SUPER; | 2237 | rhdev->speed = USB_SPEED_SUPER; |
2230 | break; | 2238 | break; |
2231 | default: | 2239 | default: |
2232 | goto err_allocate_root_hub; | 2240 | goto err_set_rh_speed; |
2233 | } | 2241 | } |
2234 | hcd->self.root_hub = rhdev; | ||
2235 | 2242 | ||
2236 | /* wakeup flag init defaults to "everything works" for root hubs, | 2243 | /* wakeup flag init defaults to "everything works" for root hubs, |
2237 | * but drivers can override it in reset() if needed, along with | 2244 | * but drivers can override it in reset() if needed, along with |
@@ -2246,6 +2253,7 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
2246 | dev_err(hcd->self.controller, "can't setup\n"); | 2253 | dev_err(hcd->self.controller, "can't setup\n"); |
2247 | goto err_hcd_driver_setup; | 2254 | goto err_hcd_driver_setup; |
2248 | } | 2255 | } |
2256 | hcd->rh_pollable = 1; | ||
2249 | 2257 | ||
2250 | /* NOTE: root hub and controller capabilities may not be the same */ | 2258 | /* NOTE: root hub and controller capabilities may not be the same */ |
2251 | if (device_can_wakeup(hcd->self.controller) | 2259 | if (device_can_wakeup(hcd->self.controller) |
@@ -2300,23 +2308,38 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
2300 | retval); | 2308 | retval); |
2301 | goto error_create_attr_group; | 2309 | goto error_create_attr_group; |
2302 | } | 2310 | } |
2303 | if (hcd->uses_new_polling && hcd->poll_rh) | 2311 | if (hcd->uses_new_polling && HCD_POLL_RH(hcd)) |
2304 | usb_hcd_poll_rh_status(hcd); | 2312 | usb_hcd_poll_rh_status(hcd); |
2305 | return retval; | 2313 | return retval; |
2306 | 2314 | ||
2307 | error_create_attr_group: | 2315 | error_create_attr_group: |
2316 | if (HC_IS_RUNNING(hcd->state)) | ||
2317 | hcd->state = HC_STATE_QUIESCING; | ||
2318 | spin_lock_irq(&hcd_root_hub_lock); | ||
2319 | hcd->rh_registered = 0; | ||
2320 | spin_unlock_irq(&hcd_root_hub_lock); | ||
2321 | |||
2322 | #ifdef CONFIG_USB_SUSPEND | ||
2323 | cancel_work_sync(&hcd->wakeup_work); | ||
2324 | #endif | ||
2308 | mutex_lock(&usb_bus_list_lock); | 2325 | mutex_lock(&usb_bus_list_lock); |
2309 | usb_disconnect(&hcd->self.root_hub); | 2326 | usb_disconnect(&rhdev); /* Sets rhdev to NULL */ |
2310 | mutex_unlock(&usb_bus_list_lock); | 2327 | mutex_unlock(&usb_bus_list_lock); |
2311 | err_register_root_hub: | 2328 | err_register_root_hub: |
2329 | hcd->rh_pollable = 0; | ||
2330 | clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); | ||
2331 | del_timer_sync(&hcd->rh_timer); | ||
2312 | hcd->driver->stop(hcd); | 2332 | hcd->driver->stop(hcd); |
2333 | hcd->state = HC_STATE_HALT; | ||
2334 | clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); | ||
2335 | del_timer_sync(&hcd->rh_timer); | ||
2313 | err_hcd_driver_start: | 2336 | err_hcd_driver_start: |
2314 | if (hcd->irq >= 0) | 2337 | if (hcd->irq >= 0) |
2315 | free_irq(irqnum, hcd); | 2338 | free_irq(irqnum, hcd); |
2316 | err_request_irq: | 2339 | err_request_irq: |
2317 | err_hcd_driver_setup: | 2340 | err_hcd_driver_setup: |
2318 | hcd->self.root_hub = NULL; | 2341 | err_set_rh_speed: |
2319 | usb_put_dev(rhdev); | 2342 | usb_put_dev(hcd->self.root_hub); |
2320 | err_allocate_root_hub: | 2343 | err_allocate_root_hub: |
2321 | usb_deregister_bus(&hcd->self); | 2344 | usb_deregister_bus(&hcd->self); |
2322 | err_register_bus: | 2345 | err_register_bus: |
@@ -2335,8 +2358,13 @@ EXPORT_SYMBOL_GPL(usb_add_hcd); | |||
2335 | */ | 2358 | */ |
2336 | void usb_remove_hcd(struct usb_hcd *hcd) | 2359 | void usb_remove_hcd(struct usb_hcd *hcd) |
2337 | { | 2360 | { |
2361 | struct usb_device *rhdev = hcd->self.root_hub; | ||
2362 | |||
2338 | dev_info(hcd->self.controller, "remove, state %x\n", hcd->state); | 2363 | dev_info(hcd->self.controller, "remove, state %x\n", hcd->state); |
2339 | 2364 | ||
2365 | usb_get_dev(rhdev); | ||
2366 | sysfs_remove_group(&rhdev->dev.kobj, &usb_bus_attr_group); | ||
2367 | |||
2340 | if (HC_IS_RUNNING (hcd->state)) | 2368 | if (HC_IS_RUNNING (hcd->state)) |
2341 | hcd->state = HC_STATE_QUIESCING; | 2369 | hcd->state = HC_STATE_QUIESCING; |
2342 | 2370 | ||
@@ -2349,19 +2377,30 @@ void usb_remove_hcd(struct usb_hcd *hcd) | |||
2349 | cancel_work_sync(&hcd->wakeup_work); | 2377 | cancel_work_sync(&hcd->wakeup_work); |
2350 | #endif | 2378 | #endif |
2351 | 2379 | ||
2352 | sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group); | ||
2353 | mutex_lock(&usb_bus_list_lock); | 2380 | mutex_lock(&usb_bus_list_lock); |
2354 | usb_disconnect(&hcd->self.root_hub); | 2381 | usb_disconnect(&rhdev); /* Sets rhdev to NULL */ |
2355 | mutex_unlock(&usb_bus_list_lock); | 2382 | mutex_unlock(&usb_bus_list_lock); |
2356 | 2383 | ||
2384 | /* Prevent any more root-hub status calls from the timer. | ||
2385 | * The HCD might still restart the timer (if a port status change | ||
2386 | * interrupt occurs), but usb_hcd_poll_rh_status() won't invoke | ||
2387 | * the hub_status_data() callback. | ||
2388 | */ | ||
2389 | hcd->rh_pollable = 0; | ||
2390 | clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); | ||
2391 | del_timer_sync(&hcd->rh_timer); | ||
2392 | |||
2357 | hcd->driver->stop(hcd); | 2393 | hcd->driver->stop(hcd); |
2358 | hcd->state = HC_STATE_HALT; | 2394 | hcd->state = HC_STATE_HALT; |
2359 | 2395 | ||
2360 | hcd->poll_rh = 0; | 2396 | /* In case the HCD restarted the timer, stop it again. */ |
2397 | clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); | ||
2361 | del_timer_sync(&hcd->rh_timer); | 2398 | del_timer_sync(&hcd->rh_timer); |
2362 | 2399 | ||
2363 | if (hcd->irq >= 0) | 2400 | if (hcd->irq >= 0) |
2364 | free_irq(hcd->irq, hcd); | 2401 | free_irq(hcd->irq, hcd); |
2402 | |||
2403 | usb_put_dev(hcd->self.root_hub); | ||
2365 | usb_deregister_bus(&hcd->self); | 2404 | usb_deregister_bus(&hcd->self); |
2366 | hcd_buffer_destroy(hcd); | 2405 | hcd_buffer_destroy(hcd); |
2367 | } | 2406 | } |