aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/cdc-acm.c
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2011-03-25 06:06:02 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-04-13 19:18:34 -0400
commit088c64f812847b3623b03d167ed329f90f3e38a4 (patch)
tree2c76790cf12fddf227b4ab21d43002713837c948 /drivers/usb/class/cdc-acm.c
parent74f5e1babde76149c2bb35ca5dbf4d0b9b38f161 (diff)
USB: cdc-acm: re-write read processing
Kill rx tasklet, which is no longer needed, and re-write read processing. Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/class/cdc-acm.c')
-rw-r--r--drivers/usb/class/cdc-acm.c295
1 files changed, 114 insertions, 181 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 519c7b933508..58754b508a0f 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -7,6 +7,7 @@
7 * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> 7 * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz>
8 * Copyright (c) 2004 Oliver Neukum <oliver@neukum.name> 8 * Copyright (c) 2004 Oliver Neukum <oliver@neukum.name>
9 * Copyright (c) 2005 David Kubicek <dave@awk.cz> 9 * Copyright (c) 2005 David Kubicek <dave@awk.cz>
10 * Copyright (c) 2011 Johan Hovold <jhovold@gmail.com>
10 * 11 *
11 * USB Abstract Control Model driver for USB modems and ISDN adapters 12 * USB Abstract Control Model driver for USB modems and ISDN adapters
12 * 13 *
@@ -50,7 +51,7 @@
50#include "cdc-acm.h" 51#include "cdc-acm.h"
51 52
52 53
53#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek" 54#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek, Johan Hovold"
54#define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" 55#define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
55 56
56static struct usb_driver acm_driver; 57static struct usb_driver acm_driver;
@@ -323,166 +324,92 @@ exit:
323 __func__, retval); 324 __func__, retval);
324} 325}
325 326
326/* data interface returns incoming bytes, or we got unthrottled */ 327static int acm_submit_read_urb(struct acm *acm, int index, gfp_t mem_flags)
327static void acm_read_bulk(struct urb *urb)
328{ 328{
329 struct acm_rb *buf; 329 int res;
330 struct acm_ru *rcv = urb->context;
331 struct acm *acm = rcv->instance;
332 int status = urb->status;
333 330
334 dev_vdbg(&acm->data->dev, "%s - status %d\n", __func__, status); 331 if (!test_and_clear_bit(index, &acm->read_urbs_free))
332 return 0;
335 333
336 if (!ACM_READY(acm)) { 334 dev_vdbg(&acm->data->dev, "%s - urb %d\n", __func__, index);
337 dev_dbg(&acm->data->dev, "%s - acm not ready\n", __func__); 335
338 return; 336 res = usb_submit_urb(acm->read_urbs[index], mem_flags);
337 if (res) {
338 if (res != -EPERM) {
339 dev_err(&acm->data->dev,
340 "%s - usb_submit_urb failed: %d\n",
341 __func__, res);
342 }
343 set_bit(index, &acm->read_urbs_free);
344 return res;
339 } 345 }
340 usb_mark_last_busy(acm->dev);
341 346
342 if (status) 347 return 0;
343 dev_dbg(&acm->data->dev, "%s - non-zero urb status: %d\n", 348}
344 __func__, status);
345 349
346 buf = rcv->buffer; 350static int acm_submit_read_urbs(struct acm *acm, gfp_t mem_flags)
347 buf->size = urb->actual_length; 351{
352 int res;
353 int i;
348 354
349 if (likely(status == 0)) { 355 for (i = 0; i < acm->rx_buflimit; ++i) {
350 spin_lock(&acm->read_lock); 356 res = acm_submit_read_urb(acm, i, mem_flags);
351 acm->processing++; 357 if (res)
352 list_add_tail(&rcv->list, &acm->spare_read_urbs); 358 return res;
353 list_add_tail(&buf->list, &acm->filled_read_bufs);
354 spin_unlock(&acm->read_lock);
355 } else {
356 /* we drop the buffer due to an error */
357 spin_lock(&acm->read_lock);
358 list_add_tail(&rcv->list, &acm->spare_read_urbs);
359 list_add(&buf->list, &acm->spare_read_bufs);
360 spin_unlock(&acm->read_lock);
361 /* nevertheless the tasklet must be kicked unconditionally
362 so the queue cannot dry up */
363 } 359 }
364 if (likely(!acm->susp_count)) 360
365 tasklet_schedule(&acm->urb_task); 361 return 0;
366} 362}
367 363
368static void acm_rx_tasklet(unsigned long _acm) 364static void acm_process_read_urb(struct acm *acm, struct urb *urb)
369{ 365{
370 struct acm *acm = (void *)_acm;
371 struct acm_rb *buf;
372 struct tty_struct *tty; 366 struct tty_struct *tty;
373 struct acm_ru *rcv;
374 unsigned long flags;
375 unsigned char throttled;
376
377 dev_vdbg(&acm->data->dev, "%s\n", __func__);
378 367
379 if (!ACM_READY(acm)) { 368 if (!urb->actual_length)
380 dev_dbg(&acm->data->dev, "%s - acm not ready\n", __func__);
381 return; 369 return;
382 }
383
384 spin_lock_irqsave(&acm->throttle_lock, flags);
385 throttled = acm->throttle;
386 spin_unlock_irqrestore(&acm->throttle_lock, flags);
387 if (throttled) {
388 dev_dbg(&acm->data->dev, "%s - throttled\n", __func__);
389 return;
390 }
391 370
392 tty = tty_port_tty_get(&acm->port); 371 tty = tty_port_tty_get(&acm->port);
372 if (!tty)
373 return;
393 374
394next_buffer: 375 tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length);
395 spin_lock_irqsave(&acm->read_lock, flags); 376 tty_flip_buffer_push(tty);
396 if (list_empty(&acm->filled_read_bufs)) {
397 spin_unlock_irqrestore(&acm->read_lock, flags);
398 goto urbs;
399 }
400 buf = list_entry(acm->filled_read_bufs.next,
401 struct acm_rb, list);
402 list_del(&buf->list);
403 spin_unlock_irqrestore(&acm->read_lock, flags);
404
405 dev_vdbg(&acm->data->dev, "%s - processing buf 0x%p, size = %d\n",
406 __func__, buf, buf->size);
407 if (tty) {
408 spin_lock_irqsave(&acm->throttle_lock, flags);
409 throttled = acm->throttle;
410 spin_unlock_irqrestore(&acm->throttle_lock, flags);
411 if (!throttled) {
412 tty_insert_flip_string(tty, buf->base, buf->size);
413 tty_flip_buffer_push(tty);
414 } else {
415 tty_kref_put(tty);
416 dev_dbg(&acm->data->dev, "%s - throttling noticed\n",
417 __func__);
418 spin_lock_irqsave(&acm->read_lock, flags);
419 list_add(&buf->list, &acm->filled_read_bufs);
420 spin_unlock_irqrestore(&acm->read_lock, flags);
421 return;
422 }
423 }
424
425 spin_lock_irqsave(&acm->read_lock, flags);
426 list_add(&buf->list, &acm->spare_read_bufs);
427 spin_unlock_irqrestore(&acm->read_lock, flags);
428 goto next_buffer;
429 377
430urbs:
431 tty_kref_put(tty); 378 tty_kref_put(tty);
379}
432 380
433 while (!list_empty(&acm->spare_read_bufs)) { 381static void acm_read_bulk_callback(struct urb *urb)
434 spin_lock_irqsave(&acm->read_lock, flags); 382{
435 if (list_empty(&acm->spare_read_urbs)) { 383 struct acm_rb *rb = urb->context;
436 acm->processing = 0; 384 struct acm *acm = rb->instance;
437 spin_unlock_irqrestore(&acm->read_lock, flags); 385 unsigned long flags;
438 return;
439 }
440 rcv = list_entry(acm->spare_read_urbs.next,
441 struct acm_ru, list);
442 list_del(&rcv->list);
443 spin_unlock_irqrestore(&acm->read_lock, flags);
444 386
445 buf = list_entry(acm->spare_read_bufs.next, 387 dev_vdbg(&acm->data->dev, "%s - urb %d, len %d\n", __func__,
446 struct acm_rb, list); 388 rb->index, urb->actual_length);
447 list_del(&buf->list); 389 set_bit(rb->index, &acm->read_urbs_free);
448 390
449 rcv->buffer = buf; 391 if (!acm->dev) {
392 dev_dbg(&acm->data->dev, "%s - disconnected\n", __func__);
393 return;
394 }
395 usb_mark_last_busy(acm->dev);
450 396
451 if (acm->is_int_ep) 397 if (urb->status) {
452 usb_fill_int_urb(rcv->urb, acm->dev, 398 dev_dbg(&acm->data->dev, "%s - non-zero urb status: %d\n",
453 acm->rx_endpoint, 399 __func__, urb->status);
454 buf->base, 400 return;
455 acm->readsize,
456 acm_read_bulk, rcv, acm->bInterval);
457 else
458 usb_fill_bulk_urb(rcv->urb, acm->dev,
459 acm->rx_endpoint,
460 buf->base,
461 acm->readsize,
462 acm_read_bulk, rcv);
463 rcv->urb->transfer_dma = buf->dma;
464 rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
465
466 /* This shouldn't kill the driver as unsuccessful URBs are
467 returned to the free-urbs-pool and resubmited ASAP */
468 spin_lock_irqsave(&acm->read_lock, flags);
469 if (acm->susp_count ||
470 usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) {
471 list_add(&buf->list, &acm->spare_read_bufs);
472 list_add(&rcv->list, &acm->spare_read_urbs);
473 acm->processing = 0;
474 spin_unlock_irqrestore(&acm->read_lock, flags);
475 return;
476 } else {
477 spin_unlock_irqrestore(&acm->read_lock, flags);
478 dev_vdbg(&acm->data->dev,
479 "%s - sending urb 0x%p, rcv 0x%p, buf 0x%p\n",
480 __func__, rcv->urb, rcv, buf);
481 }
482 } 401 }
402 acm_process_read_urb(acm, urb);
403
404 /* throttle device if requested by tty */
483 spin_lock_irqsave(&acm->read_lock, flags); 405 spin_lock_irqsave(&acm->read_lock, flags);
484 acm->processing = 0; 406 acm->throttled = acm->throttle_req;
485 spin_unlock_irqrestore(&acm->read_lock, flags); 407 if (!acm->throttled && !acm->susp_count) {
408 spin_unlock_irqrestore(&acm->read_lock, flags);
409 acm_submit_read_urb(acm, rb->index, GFP_ATOMIC);
410 } else {
411 spin_unlock_irqrestore(&acm->read_lock, flags);
412 }
486} 413}
487 414
488/* data interface wrote those outgoing bytes */ 415/* data interface wrote those outgoing bytes */
@@ -530,7 +457,6 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
530{ 457{
531 struct acm *acm; 458 struct acm *acm;
532 int rv = -ENODEV; 459 int rv = -ENODEV;
533 int i;
534 460
535 mutex_lock(&open_mutex); 461 mutex_lock(&open_mutex);
536 462
@@ -572,20 +498,11 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
572 498
573 usb_autopm_put_interface(acm->control); 499 usb_autopm_put_interface(acm->control);
574 500
575 INIT_LIST_HEAD(&acm->spare_read_urbs); 501 if (acm_submit_read_urbs(acm, GFP_KERNEL))
576 INIT_LIST_HEAD(&acm->spare_read_bufs); 502 goto bail_out;
577 INIT_LIST_HEAD(&acm->filled_read_bufs);
578
579 for (i = 0; i < acm->rx_buflimit; i++)
580 list_add(&(acm->ru[i].list), &acm->spare_read_urbs);
581 for (i = 0; i < acm->rx_buflimit; i++)
582 list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
583
584 acm->throttle = 0;
585 503
586 set_bit(ASYNCB_INITIALIZED, &acm->port.flags); 504 set_bit(ASYNCB_INITIALIZED, &acm->port.flags);
587 rv = tty_port_block_til_ready(&acm->port, tty, filp); 505 rv = tty_port_block_til_ready(&acm->port, tty, filp);
588 tasklet_schedule(&acm->urb_task);
589 506
590 mutex_unlock(&acm->mutex); 507 mutex_unlock(&acm->mutex);
591out: 508out:
@@ -613,7 +530,7 @@ static void acm_tty_unregister(struct acm *acm)
613 for (i = 0; i < ACM_NW; i++) 530 for (i = 0; i < ACM_NW; i++)
614 usb_free_urb(acm->wb[i].urb); 531 usb_free_urb(acm->wb[i].urb);
615 for (i = 0; i < acm->rx_buflimit; i++) 532 for (i = 0; i < acm->rx_buflimit; i++)
616 usb_free_urb(acm->ru[i].urb); 533 usb_free_urb(acm->read_urbs[i]);
617 kfree(acm->country_codes); 534 kfree(acm->country_codes);
618 kfree(acm); 535 kfree(acm);
619} 536}
@@ -629,10 +546,8 @@ static void acm_port_down(struct acm *acm)
629 usb_kill_urb(acm->ctrlurb); 546 usb_kill_urb(acm->ctrlurb);
630 for (i = 0; i < ACM_NW; i++) 547 for (i = 0; i < ACM_NW; i++)
631 usb_kill_urb(acm->wb[i].urb); 548 usb_kill_urb(acm->wb[i].urb);
632 tasklet_disable(&acm->urb_task);
633 for (i = 0; i < acm->rx_buflimit; i++) 549 for (i = 0; i < acm->rx_buflimit; i++)
634 usb_kill_urb(acm->ru[i].urb); 550 usb_kill_urb(acm->read_urbs[i]);
635 tasklet_enable(&acm->urb_task);
636 acm->control->needs_remote_wakeup = 0; 551 acm->control->needs_remote_wakeup = 0;
637 usb_autopm_put_interface(acm->control); 552 usb_autopm_put_interface(acm->control);
638 } 553 }
@@ -731,22 +646,31 @@ static int acm_tty_chars_in_buffer(struct tty_struct *tty)
731static void acm_tty_throttle(struct tty_struct *tty) 646static void acm_tty_throttle(struct tty_struct *tty)
732{ 647{
733 struct acm *acm = tty->driver_data; 648 struct acm *acm = tty->driver_data;
649
734 if (!ACM_READY(acm)) 650 if (!ACM_READY(acm))
735 return; 651 return;
736 spin_lock_bh(&acm->throttle_lock); 652
737 acm->throttle = 1; 653 spin_lock_irq(&acm->read_lock);
738 spin_unlock_bh(&acm->throttle_lock); 654 acm->throttle_req = 1;
655 spin_unlock_irq(&acm->read_lock);
739} 656}
740 657
741static void acm_tty_unthrottle(struct tty_struct *tty) 658static void acm_tty_unthrottle(struct tty_struct *tty)
742{ 659{
743 struct acm *acm = tty->driver_data; 660 struct acm *acm = tty->driver_data;
661 unsigned int was_throttled;
662
744 if (!ACM_READY(acm)) 663 if (!ACM_READY(acm))
745 return; 664 return;
746 spin_lock_bh(&acm->throttle_lock); 665
747 acm->throttle = 0; 666 spin_lock_irq(&acm->read_lock);
748 spin_unlock_bh(&acm->throttle_lock); 667 was_throttled = acm->throttled;
749 tasklet_schedule(&acm->urb_task); 668 acm->throttled = 0;
669 acm->throttle_req = 0;
670 spin_unlock_irq(&acm->read_lock);
671
672 if (was_throttled)
673 acm_submit_read_urbs(acm, GFP_KERNEL);
750} 674}
751 675
752static int acm_tty_break_ctl(struct tty_struct *tty, int state) 676static int acm_tty_break_ctl(struct tty_struct *tty, int state)
@@ -884,7 +808,7 @@ static void acm_read_buffers_free(struct acm *acm)
884 808
885 for (i = 0; i < acm->rx_buflimit; i++) 809 for (i = 0; i < acm->rx_buflimit; i++)
886 usb_free_coherent(usb_dev, acm->readsize, 810 usb_free_coherent(usb_dev, acm->readsize,
887 acm->rb[i].base, acm->rb[i].dma); 811 acm->read_buffers[i].base, acm->read_buffers[i].dma);
888} 812}
889 813
890/* Little helper: write buffers allocate */ 814/* Little helper: write buffers allocate */
@@ -1145,10 +1069,7 @@ made_compressed_probe:
1145 acm->ctrlsize = ctrlsize; 1069 acm->ctrlsize = ctrlsize;
1146 acm->readsize = readsize; 1070 acm->readsize = readsize;
1147 acm->rx_buflimit = num_rx_buf; 1071 acm->rx_buflimit = num_rx_buf;
1148 acm->urb_task.func = acm_rx_tasklet;
1149 acm->urb_task.data = (unsigned long) acm;
1150 INIT_WORK(&acm->work, acm_softint); 1072 INIT_WORK(&acm->work, acm_softint);
1151 spin_lock_init(&acm->throttle_lock);
1152 spin_lock_init(&acm->write_lock); 1073 spin_lock_init(&acm->write_lock);
1153 spin_lock_init(&acm->read_lock); 1074 spin_lock_init(&acm->read_lock);
1154 mutex_init(&acm->mutex); 1075 mutex_init(&acm->mutex);
@@ -1177,8 +1098,8 @@ made_compressed_probe:
1177 goto alloc_fail5; 1098 goto alloc_fail5;
1178 } 1099 }
1179 for (i = 0; i < num_rx_buf; i++) { 1100 for (i = 0; i < num_rx_buf; i++) {
1180 struct acm_rb *rb = &(acm->rb[i]); 1101 struct acm_rb *rb = &(acm->read_buffers[i]);
1181 struct acm_ru *rcv = &(acm->ru[i]); 1102 struct urb *urb;
1182 1103
1183 rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, 1104 rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL,
1184 &rb->dma); 1105 &rb->dma);
@@ -1187,16 +1108,34 @@ made_compressed_probe:
1187 "(read bufs usb_alloc_coherent)\n"); 1108 "(read bufs usb_alloc_coherent)\n");
1188 goto alloc_fail6; 1109 goto alloc_fail6;
1189 } 1110 }
1111 rb->index = i;
1112 rb->instance = acm;
1190 1113
1191 rcv->urb = usb_alloc_urb(0, GFP_KERNEL); 1114 urb = usb_alloc_urb(0, GFP_KERNEL);
1192 if (rcv->urb == NULL) { 1115 if (!urb) {
1193 dev_err(&intf->dev, 1116 dev_err(&intf->dev,
1194 "out of memory (read urbs usb_alloc_urb)\n"); 1117 "out of memory (read urbs usb_alloc_urb)\n");
1195 goto alloc_fail6; 1118 goto alloc_fail6;
1196 } 1119 }
1120 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1121 urb->transfer_dma = rb->dma;
1122 if (acm->is_int_ep) {
1123 usb_fill_int_urb(urb, acm->dev,
1124 acm->rx_endpoint,
1125 rb->base,
1126 acm->readsize,
1127 acm_read_bulk_callback, rb,
1128 acm->bInterval);
1129 } else {
1130 usb_fill_bulk_urb(urb, acm->dev,
1131 acm->rx_endpoint,
1132 rb->base,
1133 acm->readsize,
1134 acm_read_bulk_callback, rb);
1135 }
1197 1136
1198 rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 1137 acm->read_urbs[i] = urb;
1199 rcv->instance = acm; 1138 __set_bit(i, &acm->read_urbs_free);
1200 } 1139 }
1201 for (i = 0; i < ACM_NW; i++) { 1140 for (i = 0; i < ACM_NW; i++) {
1202 struct acm_wb *snd = &(acm->wb[i]); 1141 struct acm_wb *snd = &(acm->wb[i]);
@@ -1281,7 +1220,7 @@ alloc_fail7:
1281 usb_free_urb(acm->wb[i].urb); 1220 usb_free_urb(acm->wb[i].urb);
1282alloc_fail6: 1221alloc_fail6:
1283 for (i = 0; i < num_rx_buf; i++) 1222 for (i = 0; i < num_rx_buf; i++)
1284 usb_free_urb(acm->ru[i].urb); 1223 usb_free_urb(acm->read_urbs[i]);
1285 acm_read_buffers_free(acm); 1224 acm_read_buffers_free(acm);
1286 usb_free_urb(acm->ctrlurb); 1225 usb_free_urb(acm->ctrlurb);
1287alloc_fail5: 1226alloc_fail5:
@@ -1300,15 +1239,11 @@ static void stop_data_traffic(struct acm *acm)
1300 1239
1301 dev_dbg(&acm->control->dev, "%s\n", __func__); 1240 dev_dbg(&acm->control->dev, "%s\n", __func__);
1302 1241
1303 tasklet_disable(&acm->urb_task);
1304
1305 usb_kill_urb(acm->ctrlurb); 1242 usb_kill_urb(acm->ctrlurb);
1306 for (i = 0; i < ACM_NW; i++) 1243 for (i = 0; i < ACM_NW; i++)
1307 usb_kill_urb(acm->wb[i].urb); 1244 usb_kill_urb(acm->wb[i].urb);
1308 for (i = 0; i < acm->rx_buflimit; i++) 1245 for (i = 0; i < acm->rx_buflimit; i++)
1309 usb_kill_urb(acm->ru[i].urb); 1246 usb_kill_urb(acm->read_urbs[i]);
1310
1311 tasklet_enable(&acm->urb_task);
1312 1247
1313 cancel_work_sync(&acm->work); 1248 cancel_work_sync(&acm->work);
1314} 1249}
@@ -1369,11 +1304,9 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
1369 if (message.event & PM_EVENT_AUTO) { 1304 if (message.event & PM_EVENT_AUTO) {
1370 int b; 1305 int b;
1371 1306
1372 spin_lock_irq(&acm->read_lock); 1307 spin_lock_irq(&acm->write_lock);
1373 spin_lock(&acm->write_lock); 1308 b = acm->transmitting;
1374 b = acm->processing + acm->transmitting; 1309 spin_unlock_irq(&acm->write_lock);
1375 spin_unlock(&acm->write_lock);
1376 spin_unlock_irq(&acm->read_lock);
1377 if (b) 1310 if (b)
1378 return -EBUSY; 1311 return -EBUSY;
1379 } 1312 }
@@ -1435,7 +1368,7 @@ static int acm_resume(struct usb_interface *intf)
1435 if (rv < 0) 1368 if (rv < 0)
1436 goto err_out; 1369 goto err_out;
1437 1370
1438 tasklet_schedule(&acm->urb_task); 1371 rv = acm_submit_read_urbs(acm, GFP_NOIO);
1439 } 1372 }
1440 1373
1441err_out: 1374err_out: