summaryrefslogtreecommitdiff
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.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 991089eee117..3d149f359a70 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -155,7 +155,6 @@ static int acm_start_wb(struct acm *acm, struct acm_wb *wb)
wb->urb->transfer_dma = wb->dmah;
wb->urb->transfer_buffer_length = wb->len;
wb->urb->dev = acm->dev;
-
rc = usb_submit_urb(wb->urb, GFP_ATOMIC);
if (rc < 0) {
dev_err(&acm->data->dev,
@@ -183,6 +182,15 @@ static int acm_write_start(struct acm *acm, int wbn)
acm->susp_count);
usb_autopm_get_interface_async(acm->control);
if (acm->susp_count) {
+#ifdef CONFIG_PM
+ printk("%s buffer urb\n", __func__);
+ acm->transmitting++;
+ wb->urb->transfer_buffer = wb->buf;
+ wb->urb->transfer_dma = wb->dmah;
+ wb->urb->transfer_buffer_length = wb->len;
+ wb->urb->dev = acm->dev;
+ usb_anchor_urb(wb->urb, &acm->deferred);
+#endif
if (!acm->delayed_wb)
acm->delayed_wb = wb;
else
@@ -476,7 +484,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
if (usb_autopm_get_interface(acm->control) < 0)
goto early_bail;
else
- acm->control->needs_remote_wakeup = 1;
+ acm->control->needs_remote_wakeup = 0;
mutex_lock(&acm->mutex);
if (acm->port.count++) {
@@ -1080,6 +1088,9 @@ made_compressed_probe:
acm->readsize = readsize;
acm->rx_buflimit = num_rx_buf;
INIT_WORK(&acm->work, acm_softint);
+ init_usb_anchor(&acm->deferred);
+ init_waitqueue_head(&acm->drain_wait);
+ spin_lock_init(&acm->throttle_lock);
spin_lock_init(&acm->write_lock);
spin_lock_init(&acm->read_lock);
mutex_init(&acm->mutex);
@@ -1349,6 +1360,7 @@ static int acm_resume(struct usb_interface *intf)
struct acm *acm = usb_get_intfdata(intf);
struct acm_wb *wb;
int rv = 0;
+ struct urb *res;
int cnt;
spin_lock_irq(&acm->read_lock);
@@ -1359,10 +1371,21 @@ static int acm_resume(struct usb_interface *intf)
if (cnt)
return 0;
+
mutex_lock(&acm->mutex);
+
+#ifdef CONFIG_PM
+ while ((res = usb_get_from_anchor(&acm->deferred))) {
+ printk("%s process buffered request \n", __func__);
+ rv = usb_submit_urb(res, GFP_ATOMIC);
+ if (rv < 0) {
+ dbg("usb_submit_urb(pending request) failed: %d", rv);
+ }
+ }
+#endif
+
if (acm->port.count) {
rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);
-
spin_lock_irq(&acm->write_lock);
if (acm->delayed_wb) {
wb = acm->delayed_wb;
@@ -1373,6 +1396,7 @@ static int acm_resume(struct usb_interface *intf)
spin_unlock_irq(&acm->write_lock);
}
+
/*
* delayed error checking because we must
* do the write path at all cost