aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2010-06-22 16:39:10 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 17:35:37 -0400
commit541c7d432f76771079e7c295d596ea47cc6a3030 (patch)
tree9e04330713366d21849cecf0f3fd2f2c1834574d /drivers/usb/core
parent89ba85d4015b7fa738b35bcc228075c117a9a578 (diff)
USB: convert usb_hcd bitfields into atomic flags
This patch (as1393) converts several of the single-bit fields in struct usb_hcd to atomic flags. This is for safety's sake; not all CPUs can update bitfield values atomically, and these flags are used in multiple contexts. The flag fields that are set only during registration or removal can remain as they are, since non-atomic accesses at those times will not cause any problems. (Strictly speaking, the authorized_default flag should become atomic as well. I didn't bother with it because it gets changed only via sysfs. It can be done later, if anyone wants.) Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/hcd.c26
1 files changed, 12 insertions, 14 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 53f14c82ff2e..f2fe7c8e991d 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -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);
@@ -2063,8 +2062,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd)
2063 */ 2062 */
2064 local_irq_save(flags); 2063 local_irq_save(flags);
2065 2064
2066 if (unlikely(hcd->state == HC_STATE_HALT || 2065 if (unlikely(hcd->state == HC_STATE_HALT || !HCD_HW_ACCESSIBLE(hcd))) {
2067 !test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) {
2068 rc = IRQ_NONE; 2066 rc = IRQ_NONE;
2069 } else if (hcd->driver->irq(hcd) == IRQ_NONE) { 2067 } else if (hcd->driver->irq(hcd) == IRQ_NONE) {
2070 rc = IRQ_NONE; 2068 rc = IRQ_NONE;
@@ -2098,7 +2096,7 @@ void usb_hc_died (struct usb_hcd *hcd)
2098 2096
2099 spin_lock_irqsave (&hcd_root_hub_lock, flags); 2097 spin_lock_irqsave (&hcd_root_hub_lock, flags);
2100 if (hcd->rh_registered) { 2098 if (hcd->rh_registered) {
2101 hcd->poll_rh = 0; 2099 clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
2102 2100
2103 /* make khubd clean up old urbs and devices */ 2101 /* make khubd clean up old urbs and devices */
2104 usb_set_device_state (hcd->self.root_hub, 2102 usb_set_device_state (hcd->self.root_hub,
@@ -2301,7 +2299,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
2301 retval); 2299 retval);
2302 goto error_create_attr_group; 2300 goto error_create_attr_group;
2303 } 2301 }
2304 if (hcd->uses_new_polling && hcd->poll_rh) 2302 if (hcd->uses_new_polling && HCD_POLL_RH(hcd))
2305 usb_hcd_poll_rh_status(hcd); 2303 usb_hcd_poll_rh_status(hcd);
2306 return retval; 2304 return retval;
2307 2305
@@ -2320,11 +2318,11 @@ error_create_attr_group:
2320 mutex_unlock(&usb_bus_list_lock); 2318 mutex_unlock(&usb_bus_list_lock);
2321err_register_root_hub: 2319err_register_root_hub:
2322 hcd->rh_pollable = 0; 2320 hcd->rh_pollable = 0;
2323 hcd->poll_rh = 0; 2321 clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
2324 del_timer_sync(&hcd->rh_timer); 2322 del_timer_sync(&hcd->rh_timer);
2325 hcd->driver->stop(hcd); 2323 hcd->driver->stop(hcd);
2326 hcd->state = HC_STATE_HALT; 2324 hcd->state = HC_STATE_HALT;
2327 hcd->poll_rh = 0; 2325 clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
2328 del_timer_sync(&hcd->rh_timer); 2326 del_timer_sync(&hcd->rh_timer);
2329err_hcd_driver_start: 2327err_hcd_driver_start:
2330 if (hcd->irq >= 0) 2328 if (hcd->irq >= 0)
@@ -2380,14 +2378,14 @@ void usb_remove_hcd(struct usb_hcd *hcd)
2380 * the hub_status_data() callback. 2378 * the hub_status_data() callback.
2381 */ 2379 */
2382 hcd->rh_pollable = 0; 2380 hcd->rh_pollable = 0;
2383 hcd->poll_rh = 0; 2381 clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
2384 del_timer_sync(&hcd->rh_timer); 2382 del_timer_sync(&hcd->rh_timer);
2385 2383
2386 hcd->driver->stop(hcd); 2384 hcd->driver->stop(hcd);
2387 hcd->state = HC_STATE_HALT; 2385 hcd->state = HC_STATE_HALT;
2388 2386
2389 /* In case the HCD restarted the timer, stop it again. */ 2387 /* In case the HCD restarted the timer, stop it again. */
2390 hcd->poll_rh = 0; 2388 clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
2391 del_timer_sync(&hcd->rh_timer); 2389 del_timer_sync(&hcd->rh_timer);
2392 2390
2393 if (hcd->irq >= 0) 2391 if (hcd->irq >= 0)