diff options
author | Oliver Neukum <oliver@neukum.org> | 2010-02-27 14:55:52 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-19 10:24:16 -0400 |
commit | beb1d35f1690fe27694472a010a8e4a9ae11cc50 (patch) | |
tree | 645a2a6845e0a89d18f9dcd7373adf24ad89f95f | |
parent | d855fe2e9c19edaa47baba0e7f95e17f7a24dba8 (diff) |
usb: cdc-wdm: Fix submission of URB after suspension
There's a window under which cdc-wdm may submit
an URB to a device about to be suspended. This
introduces a flag to prevent it.
Signed-off-by: Oliver Neukum <neukum@b1-systems.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/class/cdc-wdm.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 72e2eb030459..a6b5e9fd0714 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -53,7 +53,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); | |||
53 | #define WDM_INT_STALL 5 | 53 | #define WDM_INT_STALL 5 |
54 | #define WDM_POLL_RUNNING 6 | 54 | #define WDM_POLL_RUNNING 6 |
55 | #define WDM_RESPONDING 7 | 55 | #define WDM_RESPONDING 7 |
56 | 56 | #define WDM_SUSPENDING 8 | |
57 | 57 | ||
58 | #define WDM_MAX 16 | 58 | #define WDM_MAX 16 |
59 | 59 | ||
@@ -231,7 +231,8 @@ static void wdm_int_callback(struct urb *urb) | |||
231 | spin_lock(&desc->iuspin); | 231 | spin_lock(&desc->iuspin); |
232 | clear_bit(WDM_READ, &desc->flags); | 232 | clear_bit(WDM_READ, &desc->flags); |
233 | set_bit(WDM_RESPONDING, &desc->flags); | 233 | set_bit(WDM_RESPONDING, &desc->flags); |
234 | if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { | 234 | if (!test_bit(WDM_DISCONNECTING, &desc->flags) |
235 | && !test_bit(WDM_SUSPENDING, &desc->flags)) { | ||
235 | rv = usb_submit_urb(desc->response, GFP_ATOMIC); | 236 | rv = usb_submit_urb(desc->response, GFP_ATOMIC); |
236 | dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", | 237 | dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", |
237 | __func__, rv); | 238 | __func__, rv); |
@@ -800,6 +801,7 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) | |||
800 | rv = -EBUSY; | 801 | rv = -EBUSY; |
801 | } else { | 802 | } else { |
802 | #endif | 803 | #endif |
804 | set_bit(WDM_SUSPENDING, &desc->flags); | ||
803 | cancel_work_sync(&desc->rxwork); | 805 | cancel_work_sync(&desc->rxwork); |
804 | kill_urbs(desc); | 806 | kill_urbs(desc); |
805 | #ifdef CONFIG_PM | 807 | #ifdef CONFIG_PM |
@@ -830,6 +832,7 @@ static int wdm_resume(struct usb_interface *intf) | |||
830 | dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); | 832 | dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); |
831 | mutex_lock(&desc->lock); | 833 | mutex_lock(&desc->lock); |
832 | rv = recover_from_urb_loss(desc); | 834 | rv = recover_from_urb_loss(desc); |
835 | clear_bit(WDM_SUSPENDING, &desc->flags); | ||
833 | mutex_unlock(&desc->lock); | 836 | mutex_unlock(&desc->lock); |
834 | return rv; | 837 | return rv; |
835 | } | 838 | } |