aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/cdc-acm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/class/cdc-acm.c')
-rw-r--r--drivers/usb/class/cdc-acm.c52
1 files changed, 19 insertions, 33 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 9b1cbcf8fb7f..9f49bfe4c6f4 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -216,38 +216,6 @@ static int acm_start_wb(struct acm *acm, struct acm_wb *wb)
216 return rc; 216 return rc;
217} 217}
218 218
219static int acm_write_start(struct acm *acm, int wbn)
220{
221 unsigned long flags;
222 struct acm_wb *wb = &acm->wb[wbn];
223 int rc;
224
225 spin_lock_irqsave(&acm->write_lock, flags);
226 if (!acm->dev) {
227 wb->use = 0;
228 spin_unlock_irqrestore(&acm->write_lock, flags);
229 return -ENODEV;
230 }
231
232 dev_vdbg(&acm->data->dev, "%s - susp_count %d\n", __func__,
233 acm->susp_count);
234 usb_autopm_get_interface_async(acm->control);
235 if (acm->susp_count) {
236 if (!acm->delayed_wb)
237 acm->delayed_wb = wb;
238 else
239 usb_autopm_put_interface_async(acm->control);
240 spin_unlock_irqrestore(&acm->write_lock, flags);
241 return 0; /* A white lie */
242 }
243 usb_mark_last_busy(acm->dev);
244
245 rc = acm_start_wb(acm, wb);
246 spin_unlock_irqrestore(&acm->write_lock, flags);
247
248 return rc;
249
250}
251/* 219/*
252 * attributes exported through sysfs 220 * attributes exported through sysfs
253 */ 221 */
@@ -653,13 +621,31 @@ static int acm_tty_write(struct tty_struct *tty,
653 } 621 }
654 wb = &acm->wb[wbn]; 622 wb = &acm->wb[wbn];
655 623
624 if (!acm->dev) {
625 wb->use = 0;
626 spin_unlock_irqrestore(&acm->write_lock, flags);
627 return -ENODEV;
628 }
629
656 count = (count > acm->writesize) ? acm->writesize : count; 630 count = (count > acm->writesize) ? acm->writesize : count;
657 dev_vdbg(&acm->data->dev, "%s - write %d\n", __func__, count); 631 dev_vdbg(&acm->data->dev, "%s - write %d\n", __func__, count);
658 memcpy(wb->buf, buf, count); 632 memcpy(wb->buf, buf, count);
659 wb->len = count; 633 wb->len = count;
634
635 usb_autopm_get_interface_async(acm->control);
636 if (acm->susp_count) {
637 if (!acm->delayed_wb)
638 acm->delayed_wb = wb;
639 else
640 usb_autopm_put_interface_async(acm->control);
641 spin_unlock_irqrestore(&acm->write_lock, flags);
642 return count; /* A white lie */
643 }
644 usb_mark_last_busy(acm->dev);
645
646 stat = acm_start_wb(acm, wb);
660 spin_unlock_irqrestore(&acm->write_lock, flags); 647 spin_unlock_irqrestore(&acm->write_lock, flags);
661 648
662 stat = acm_write_start(acm, wbn);
663 if (stat < 0) 649 if (stat < 0)
664 return stat; 650 return stat;
665 return count; 651 return count;