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.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 98199628e394..d38a25f36ea5 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -326,10 +326,16 @@ static void acm_rx_tasklet(unsigned long _acm)
326 struct tty_struct *tty = acm->tty; 326 struct tty_struct *tty = acm->tty;
327 struct acm_ru *rcv; 327 struct acm_ru *rcv;
328 unsigned long flags; 328 unsigned long flags;
329 int i = 0; 329 unsigned char throttled;
330 dbg("Entering acm_rx_tasklet"); 330 dbg("Entering acm_rx_tasklet");
331 331
332 if (!ACM_READY(acm) || acm->throttle) 332 if (!ACM_READY(acm))
333 return;
334
335 spin_lock(&acm->throttle_lock);
336 throttled = acm->throttle;
337 spin_unlock(&acm->throttle_lock);
338 if (throttled)
333 return; 339 return;
334 340
335next_buffer: 341next_buffer:
@@ -346,22 +352,20 @@ next_buffer:
346 dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size); 352 dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size);
347 353
348 tty_buffer_request_room(tty, buf->size); 354 tty_buffer_request_room(tty, buf->size);
349 if (!acm->throttle) 355 spin_lock(&acm->throttle_lock);
356 throttled = acm->throttle;
357 spin_unlock(&acm->throttle_lock);
358 if (!throttled)
350 tty_insert_flip_string(tty, buf->base, buf->size); 359 tty_insert_flip_string(tty, buf->base, buf->size);
351 tty_flip_buffer_push(tty); 360 tty_flip_buffer_push(tty);
352 361
353 spin_lock(&acm->throttle_lock); 362 if (throttled) {
354 if (acm->throttle) { 363 dbg("Throttling noticed");
355 dbg("Throtteling noticed");
356 memmove(buf->base, buf->base + i, buf->size - i);
357 buf->size -= i;
358 spin_unlock(&acm->throttle_lock);
359 spin_lock_irqsave(&acm->read_lock, flags); 364 spin_lock_irqsave(&acm->read_lock, flags);
360 list_add(&buf->list, &acm->filled_read_bufs); 365 list_add(&buf->list, &acm->filled_read_bufs);
361 spin_unlock_irqrestore(&acm->read_lock, flags); 366 spin_unlock_irqrestore(&acm->read_lock, flags);
362 return; 367 return;
363 } 368 }
364 spin_unlock(&acm->throttle_lock);
365 369
366 spin_lock_irqsave(&acm->read_lock, flags); 370 spin_lock_irqsave(&acm->read_lock, flags);
367 list_add(&buf->list, &acm->spare_read_bufs); 371 list_add(&buf->list, &acm->spare_read_bufs);
@@ -467,7 +471,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
467 goto bail_out; 471 goto bail_out;
468 } 472 }
469 473
470 if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS)) 474 if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) &&
475 (acm->ctrl_caps & USB_CDC_CAP_LINE))
471 goto full_bailout; 476 goto full_bailout;
472 477
473 INIT_LIST_HEAD(&acm->spare_read_urbs); 478 INIT_LIST_HEAD(&acm->spare_read_urbs);
@@ -480,6 +485,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
480 list_add(&(acm->rb[i].list), &acm->spare_read_bufs); 485 list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
481 } 486 }
482 487
488 acm->throttle = 0;
489
483 tasklet_schedule(&acm->urb_task); 490 tasklet_schedule(&acm->urb_task);
484 491
485done: 492done:
@@ -1092,6 +1099,10 @@ static struct usb_device_id acm_ids[] = {
1092 { USB_DEVICE(0x0ace, 0x1611), /* ZyDAS 56K USB MODEM - new version */ 1099 { USB_DEVICE(0x0ace, 0x1611), /* ZyDAS 56K USB MODEM - new version */
1093 .driver_info = SINGLE_RX_URB, /* firmware bug */ 1100 .driver_info = SINGLE_RX_URB, /* firmware bug */
1094 }, 1101 },
1102 { USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */
1103 .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
1104 },
1105
1095 /* control interfaces with various AT-command sets */ 1106 /* control interfaces with various AT-command sets */
1096 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, 1107 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
1097 USB_CDC_ACM_PROTO_AT_V25TER) }, 1108 USB_CDC_ACM_PROTO_AT_V25TER) },