diff options
| -rw-r--r-- | drivers/usb/class/cdc-wdm.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index cf1c5fb918dc..940b17af162c 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
| @@ -52,6 +52,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); | |||
| 52 | #define WDM_READ 4 | 52 | #define WDM_READ 4 |
| 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 | 56 | ||
| 56 | 57 | ||
| 57 | #define WDM_MAX 16 | 58 | #define WDM_MAX 16 |
| @@ -115,21 +116,22 @@ static void wdm_in_callback(struct urb *urb) | |||
| 115 | int status = urb->status; | 116 | int status = urb->status; |
| 116 | 117 | ||
| 117 | spin_lock(&desc->iuspin); | 118 | spin_lock(&desc->iuspin); |
| 119 | clear_bit(WDM_RESPONDING, &desc->flags); | ||
| 118 | 120 | ||
| 119 | if (status) { | 121 | if (status) { |
| 120 | switch (status) { | 122 | switch (status) { |
| 121 | case -ENOENT: | 123 | case -ENOENT: |
| 122 | dev_dbg(&desc->intf->dev, | 124 | dev_dbg(&desc->intf->dev, |
| 123 | "nonzero urb status received: -ENOENT"); | 125 | "nonzero urb status received: -ENOENT"); |
| 124 | break; | 126 | goto skip_error; |
| 125 | case -ECONNRESET: | 127 | case -ECONNRESET: |
| 126 | dev_dbg(&desc->intf->dev, | 128 | dev_dbg(&desc->intf->dev, |
| 127 | "nonzero urb status received: -ECONNRESET"); | 129 | "nonzero urb status received: -ECONNRESET"); |
| 128 | break; | 130 | goto skip_error; |
| 129 | case -ESHUTDOWN: | 131 | case -ESHUTDOWN: |
| 130 | dev_dbg(&desc->intf->dev, | 132 | dev_dbg(&desc->intf->dev, |
| 131 | "nonzero urb status received: -ESHUTDOWN"); | 133 | "nonzero urb status received: -ESHUTDOWN"); |
| 132 | break; | 134 | goto skip_error; |
| 133 | case -EPIPE: | 135 | case -EPIPE: |
| 134 | dev_err(&desc->intf->dev, | 136 | dev_err(&desc->intf->dev, |
| 135 | "nonzero urb status received: -EPIPE\n"); | 137 | "nonzero urb status received: -EPIPE\n"); |
| @@ -145,6 +147,7 @@ static void wdm_in_callback(struct urb *urb) | |||
| 145 | desc->reslength = urb->actual_length; | 147 | desc->reslength = urb->actual_length; |
| 146 | memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); | 148 | memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); |
| 147 | desc->length += desc->reslength; | 149 | desc->length += desc->reslength; |
| 150 | skip_error: | ||
| 148 | wake_up(&desc->wait); | 151 | wake_up(&desc->wait); |
| 149 | 152 | ||
| 150 | set_bit(WDM_READ, &desc->flags); | 153 | set_bit(WDM_READ, &desc->flags); |
| @@ -227,6 +230,7 @@ static void wdm_int_callback(struct urb *urb) | |||
| 227 | desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 230 | desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
| 228 | spin_lock(&desc->iuspin); | 231 | spin_lock(&desc->iuspin); |
| 229 | clear_bit(WDM_READ, &desc->flags); | 232 | clear_bit(WDM_READ, &desc->flags); |
| 233 | set_bit(WDM_RESPONDING, &desc->flags); | ||
| 230 | if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { | 234 | if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { |
| 231 | rv = usb_submit_urb(desc->response, GFP_ATOMIC); | 235 | rv = usb_submit_urb(desc->response, GFP_ATOMIC); |
| 232 | dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", | 236 | dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", |
| @@ -234,6 +238,7 @@ static void wdm_int_callback(struct urb *urb) | |||
| 234 | } | 238 | } |
| 235 | spin_unlock(&desc->iuspin); | 239 | spin_unlock(&desc->iuspin); |
| 236 | if (rv < 0) { | 240 | if (rv < 0) { |
| 241 | clear_bit(WDM_RESPONDING, &desc->flags); | ||
| 237 | if (rv == -EPERM) | 242 | if (rv == -EPERM) |
| 238 | return; | 243 | return; |
| 239 | if (rv == -ENOMEM) { | 244 | if (rv == -ENOMEM) { |
| @@ -795,7 +800,8 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) | |||
| 795 | mutex_lock(&desc->lock); | 800 | mutex_lock(&desc->lock); |
| 796 | #ifdef CONFIG_PM | 801 | #ifdef CONFIG_PM |
| 797 | if ((message.event & PM_EVENT_AUTO) && | 802 | if ((message.event & PM_EVENT_AUTO) && |
| 798 | test_bit(WDM_IN_USE, &desc->flags)) { | 803 | (test_bit(WDM_IN_USE, &desc->flags) |
| 804 | || test_bit(WDM_RESPONDING, &desc->flags))) { | ||
| 799 | rv = -EBUSY; | 805 | rv = -EBUSY; |
| 800 | } else { | 806 | } else { |
| 801 | #endif | 807 | #endif |
