diff options
author | Oliver Neukum <oliver@neukum.org> | 2010-02-27 14:56:22 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-19 10:24:16 -0400 |
commit | 62e6685470fb04fb7688ecef96c39160498721d5 (patch) | |
tree | 2350c3c979dad7cbc73a7edbc22e9bfef188a867 | |
parent | beb1d35f1690fe27694472a010a8e4a9ae11cc50 (diff) |
usb: cdc-wdm:Fix loss of data due to autosuspend
The guarding flag must be set and tested under spinlock
and cleared before the URBs are resubmitted in resume.
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 | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index a6b5e9fd0714..07c12974fe14 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -794,14 +794,17 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) | |||
794 | dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); | 794 | dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); |
795 | 795 | ||
796 | mutex_lock(&desc->lock); | 796 | mutex_lock(&desc->lock); |
797 | spin_lock_irq(&desc->iuspin); | ||
797 | #ifdef CONFIG_PM | 798 | #ifdef CONFIG_PM |
798 | if ((message.event & PM_EVENT_AUTO) && | 799 | if ((message.event & PM_EVENT_AUTO) && |
799 | (test_bit(WDM_IN_USE, &desc->flags) | 800 | (test_bit(WDM_IN_USE, &desc->flags) |
800 | || test_bit(WDM_RESPONDING, &desc->flags))) { | 801 | || test_bit(WDM_RESPONDING, &desc->flags))) { |
802 | spin_unlock_irq(&desc->iuspin); | ||
801 | rv = -EBUSY; | 803 | rv = -EBUSY; |
802 | } else { | 804 | } else { |
803 | #endif | 805 | #endif |
804 | set_bit(WDM_SUSPENDING, &desc->flags); | 806 | set_bit(WDM_SUSPENDING, &desc->flags); |
807 | spin_unlock_irq(&desc->iuspin); | ||
805 | cancel_work_sync(&desc->rxwork); | 808 | cancel_work_sync(&desc->rxwork); |
806 | kill_urbs(desc); | 809 | kill_urbs(desc); |
807 | #ifdef CONFIG_PM | 810 | #ifdef CONFIG_PM |
@@ -831,8 +834,8 @@ static int wdm_resume(struct usb_interface *intf) | |||
831 | 834 | ||
832 | dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); | 835 | dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); |
833 | mutex_lock(&desc->lock); | 836 | mutex_lock(&desc->lock); |
834 | rv = recover_from_urb_loss(desc); | ||
835 | clear_bit(WDM_SUSPENDING, &desc->flags); | 837 | clear_bit(WDM_SUSPENDING, &desc->flags); |
838 | rv = recover_from_urb_loss(desc); | ||
836 | mutex_unlock(&desc->lock); | 839 | mutex_unlock(&desc->lock); |
837 | return rv; | 840 | return rv; |
838 | } | 841 | } |