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.c232
1 files changed, 158 insertions, 74 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 1b4751412970..248279e44c99 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -6,6 +6,7 @@
6 * Copyright (c) 1999 Johannes Erdfelt <johannes@erdfelt.com> 6 * Copyright (c) 1999 Johannes Erdfelt <johannes@erdfelt.com>
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 * 10 *
10 * USB Abstract Control Model driver for USB modems and ISDN adapters 11 * USB Abstract Control Model driver for USB modems and ISDN adapters
11 * 12 *
@@ -29,6 +30,7 @@
29 * config we want, sysadmin changes bConfigurationValue in sysfs. 30 * config we want, sysadmin changes bConfigurationValue in sysfs.
30 * v0.23 - use softirq for rx processing, as needed by tty layer 31 * v0.23 - use softirq for rx processing, as needed by tty layer
31 * v0.24 - change probe method to evaluate CDC union descriptor 32 * v0.24 - change probe method to evaluate CDC union descriptor
33 * v0.25 - downstream tasks paralelized to maximize throughput
32 */ 34 */
33 35
34/* 36/*
@@ -63,14 +65,15 @@
63#include <linux/usb_cdc.h> 65#include <linux/usb_cdc.h>
64#include <asm/byteorder.h> 66#include <asm/byteorder.h>
65#include <asm/unaligned.h> 67#include <asm/unaligned.h>
68#include <linux/list.h>
66 69
67#include "cdc-acm.h" 70#include "cdc-acm.h"
68 71
69/* 72/*
70 * Version Information 73 * Version Information
71 */ 74 */
72#define DRIVER_VERSION "v0.23" 75#define DRIVER_VERSION "v0.25"
73#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik" 76#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek"
74#define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" 77#define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
75 78
76static struct usb_driver acm_driver; 79static struct usb_driver acm_driver;
@@ -284,7 +287,9 @@ exit:
284/* data interface returns incoming bytes, or we got unthrottled */ 287/* data interface returns incoming bytes, or we got unthrottled */
285static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) 288static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
286{ 289{
287 struct acm *acm = urb->context; 290 struct acm_rb *buf;
291 struct acm_ru *rcv = urb->context;
292 struct acm *acm = rcv->instance;
288 dbg("Entering acm_read_bulk with status %d\n", urb->status); 293 dbg("Entering acm_read_bulk with status %d\n", urb->status);
289 294
290 if (!ACM_READY(acm)) 295 if (!ACM_READY(acm))
@@ -293,49 +298,109 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
293 if (urb->status) 298 if (urb->status)
294 dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status); 299 dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status);
295 300
296 /* calling tty_flip_buffer_push() in_irq() isn't allowed */ 301 buf = rcv->buffer;
297 tasklet_schedule(&acm->bh); 302 buf->size = urb->actual_length;
303
304 spin_lock(&acm->read_lock);
305 list_add_tail(&rcv->list, &acm->spare_read_urbs);
306 list_add_tail(&buf->list, &acm->filled_read_bufs);
307 spin_unlock(&acm->read_lock);
308
309 tasklet_schedule(&acm->urb_task);
298} 310}
299 311
300static void acm_rx_tasklet(unsigned long _acm) 312static void acm_rx_tasklet(unsigned long _acm)
301{ 313{
302 struct acm *acm = (void *)_acm; 314 struct acm *acm = (void *)_acm;
303 struct urb *urb = acm->readurb; 315 struct acm_rb *buf;
304 struct tty_struct *tty = acm->tty; 316 struct tty_struct *tty = acm->tty;
305 unsigned char *data = urb->transfer_buffer; 317 struct acm_ru *rcv;
318 //unsigned long flags;
306 int i = 0; 319 int i = 0;
307 dbg("Entering acm_rx_tasklet"); 320 dbg("Entering acm_rx_tasklet");
308 321
309 if (urb->actual_length > 0 && !acm->throttle) { 322 if (!ACM_READY(acm) || acm->throttle)
310 for (i = 0; i < urb->actual_length && !acm->throttle; i++) { 323 return;
311 /* if we insert more than TTY_FLIPBUF_SIZE characters, 324
312 * we drop them. */ 325next_buffer:
313 if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 326 spin_lock(&acm->read_lock);
314 tty_flip_buffer_push(tty); 327 if (list_empty(&acm->filled_read_bufs)) {
315 } 328 spin_unlock(&acm->read_lock);
316 tty_insert_flip_char(tty, data[i], 0); 329 goto urbs;
317 }
318 dbg("Handed %d bytes to tty layer", i+1);
319 tty_flip_buffer_push(tty);
320 } 330 }
331 buf = list_entry(acm->filled_read_bufs.next,
332 struct acm_rb, list);
333 list_del(&buf->list);
334 spin_unlock(&acm->read_lock);
335
336 dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size);
337
338 for (i = 0; i < buf->size && !acm->throttle; i++) {
339 /* if we insert more than TTY_FLIPBUF_SIZE characters,
340 we drop them. */
341 if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
342 tty_flip_buffer_push(tty);
343 }
344 tty_insert_flip_char(tty, buf->base[i], 0);
345 }
346 tty_flip_buffer_push(tty);
321 347
322 spin_lock(&acm->throttle_lock); 348 spin_lock(&acm->throttle_lock);
323 if (acm->throttle) { 349 if (acm->throttle) {
324 dbg("Throtteling noticed"); 350 dbg("Throtteling noticed");
325 memmove(data, data + i, urb->actual_length - i); 351 memmove(buf->base, buf->base + i, buf->size - i);
326 urb->actual_length -= i; 352 buf->size -= i;
327 acm->resubmit_to_unthrottle = 1;
328 spin_unlock(&acm->throttle_lock); 353 spin_unlock(&acm->throttle_lock);
354 spin_lock(&acm->read_lock);
355 list_add(&buf->list, &acm->filled_read_bufs);
356 spin_unlock(&acm->read_lock);
329 return; 357 return;
330 } 358 }
331 spin_unlock(&acm->throttle_lock); 359 spin_unlock(&acm->throttle_lock);
332 360
333 urb->actual_length = 0; 361 spin_lock(&acm->read_lock);
334 urb->dev = acm->dev; 362 list_add(&buf->list, &acm->spare_read_bufs);
335 363 spin_unlock(&acm->read_lock);
336 i = usb_submit_urb(urb, GFP_ATOMIC); 364 goto next_buffer;
337 if (i) 365
338 dev_dbg(&acm->data->dev, "bulk rx resubmit %d\n", i); 366urbs:
367 while (!list_empty(&acm->spare_read_bufs)) {
368 spin_lock(&acm->read_lock);
369 if (list_empty(&acm->spare_read_urbs)) {
370 spin_unlock(&acm->read_lock);
371 return;
372 }
373 rcv = list_entry(acm->spare_read_urbs.next,
374 struct acm_ru, list);
375 list_del(&rcv->list);
376 spin_unlock(&acm->read_lock);
377
378 buf = list_entry(acm->spare_read_bufs.next,
379 struct acm_rb, list);
380 list_del(&buf->list);
381
382 rcv->buffer = buf;
383
384 usb_fill_bulk_urb(rcv->urb, acm->dev,
385 acm->rx_endpoint,
386 buf->base,
387 acm->readsize,
388 acm_read_bulk, rcv);
389 rcv->urb->transfer_dma = buf->dma;
390 rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
391
392 dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p\n", rcv->urb, rcv, buf);
393
394 /* This shouldn't kill the driver as unsuccessful URBs are returned to the
395 free-urbs-pool and resubmited ASAP */
396 if (usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) {
397 list_add(&buf->list, &acm->spare_read_bufs);
398 spin_lock(&acm->read_lock);
399 list_add(&rcv->list, &acm->spare_read_urbs);
400 spin_unlock(&acm->read_lock);
401 return;
402 }
403 }
339} 404}
340 405
341/* data interface wrote those outgoing bytes */ 406/* data interface wrote those outgoing bytes */
@@ -369,6 +434,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
369{ 434{
370 struct acm *acm; 435 struct acm *acm;
371 int rv = -EINVAL; 436 int rv = -EINVAL;
437 int i;
372 dbg("Entering acm_tty_open.\n"); 438 dbg("Entering acm_tty_open.\n");
373 439
374 down(&open_sem); 440 down(&open_sem);
@@ -382,7 +448,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
382 tty->driver_data = acm; 448 tty->driver_data = acm;
383 acm->tty = tty; 449 acm->tty = tty;
384 450
385 451 /* force low_latency on so that our tty_push actually forces the data through,
452 otherwise it is scheduled, and with high data rates data can get lost. */
453 tty->low_latency = 1;
386 454
387 if (acm->used++) { 455 if (acm->used++) {
388 goto done; 456 goto done;
@@ -394,18 +462,20 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
394 goto bail_out; 462 goto bail_out;
395 } 463 }
396 464
397 acm->readurb->dev = acm->dev;
398 if (usb_submit_urb(acm->readurb, GFP_KERNEL)) {
399 dbg("usb_submit_urb(read bulk) failed");
400 goto bail_out_and_unlink;
401 }
402
403 if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS)) 465 if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS))
404 goto full_bailout; 466 goto full_bailout;
405 467
406 /* force low_latency on so that our tty_push actually forces the data through, 468 INIT_LIST_HEAD(&acm->spare_read_urbs);
407 otherwise it is scheduled, and with high data rates data can get lost. */ 469 INIT_LIST_HEAD(&acm->spare_read_bufs);
408 tty->low_latency = 1; 470 INIT_LIST_HEAD(&acm->filled_read_bufs);
471 for (i = 0; i < ACM_NRU; i++) {
472 list_add(&(acm->ru[i].list), &acm->spare_read_urbs);
473 }
474 for (i = 0; i < ACM_NRB; i++) {
475 list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
476 }
477
478 tasklet_schedule(&acm->urb_task);
409 479
410done: 480done:
411err_out: 481err_out:
@@ -413,8 +483,6 @@ err_out:
413 return rv; 483 return rv;
414 484
415full_bailout: 485full_bailout:
416 usb_kill_urb(acm->readurb);
417bail_out_and_unlink:
418 usb_kill_urb(acm->ctrlurb); 486 usb_kill_urb(acm->ctrlurb);
419bail_out: 487bail_out:
420 acm->used--; 488 acm->used--;
@@ -424,18 +492,22 @@ bail_out:
424 492
425static void acm_tty_unregister(struct acm *acm) 493static void acm_tty_unregister(struct acm *acm)
426{ 494{
495 int i;
496
427 tty_unregister_device(acm_tty_driver, acm->minor); 497 tty_unregister_device(acm_tty_driver, acm->minor);
428 usb_put_intf(acm->control); 498 usb_put_intf(acm->control);
429 acm_table[acm->minor] = NULL; 499 acm_table[acm->minor] = NULL;
430 usb_free_urb(acm->ctrlurb); 500 usb_free_urb(acm->ctrlurb);
431 usb_free_urb(acm->readurb);
432 usb_free_urb(acm->writeurb); 501 usb_free_urb(acm->writeurb);
502 for (i = 0; i < ACM_NRU; i++)
503 usb_free_urb(acm->ru[i].urb);
433 kfree(acm); 504 kfree(acm);
434} 505}
435 506
436static void acm_tty_close(struct tty_struct *tty, struct file *filp) 507static void acm_tty_close(struct tty_struct *tty, struct file *filp)
437{ 508{
438 struct acm *acm = tty->driver_data; 509 struct acm *acm = tty->driver_data;
510 int i;
439 511
440 if (!acm || !acm->used) 512 if (!acm || !acm->used)
441 return; 513 return;
@@ -446,7 +518,8 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
446 acm_set_control(acm, acm->ctrlout = 0); 518 acm_set_control(acm, acm->ctrlout = 0);
447 usb_kill_urb(acm->ctrlurb); 519 usb_kill_urb(acm->ctrlurb);
448 usb_kill_urb(acm->writeurb); 520 usb_kill_urb(acm->writeurb);
449 usb_kill_urb(acm->readurb); 521 for (i = 0; i < ACM_NRU; i++)
522 usb_kill_urb(acm->ru[i].urb);
450 } else 523 } else
451 acm_tty_unregister(acm); 524 acm_tty_unregister(acm);
452 } 525 }
@@ -528,10 +601,7 @@ static void acm_tty_unthrottle(struct tty_struct *tty)
528 spin_lock_bh(&acm->throttle_lock); 601 spin_lock_bh(&acm->throttle_lock);
529 acm->throttle = 0; 602 acm->throttle = 0;
530 spin_unlock_bh(&acm->throttle_lock); 603 spin_unlock_bh(&acm->throttle_lock);
531 if (acm->resubmit_to_unthrottle) { 604 tasklet_schedule(&acm->urb_task);
532 acm->resubmit_to_unthrottle = 0;
533 acm_read_bulk(acm->readurb, NULL);
534 }
535} 605}
536 606
537static void acm_tty_break_ctl(struct tty_struct *tty, int state) 607static void acm_tty_break_ctl(struct tty_struct *tty, int state)
@@ -588,7 +658,7 @@ static int acm_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int
588 return -ENOIOCTLCMD; 658 return -ENOIOCTLCMD;
589} 659}
590 660
591static __u32 acm_tty_speed[] = { 661static const __u32 acm_tty_speed[] = {
592 0, 50, 75, 110, 134, 150, 200, 300, 600, 662 0, 50, 75, 110, 134, 150, 200, 300, 600,
593 1200, 1800, 2400, 4800, 9600, 19200, 38400, 663 1200, 1800, 2400, 4800, 9600, 19200, 38400,
594 57600, 115200, 230400, 460800, 500000, 576000, 664 57600, 115200, 230400, 460800, 500000, 576000,
@@ -596,7 +666,7 @@ static __u32 acm_tty_speed[] = {
596 2500000, 3000000, 3500000, 4000000 666 2500000, 3000000, 3500000, 4000000
597}; 667};
598 668
599static __u8 acm_tty_size[] = { 669static const __u8 acm_tty_size[] = {
600 5, 6, 7, 8 670 5, 6, 7, 8
601}; 671};
602 672
@@ -694,6 +764,7 @@ static int acm_probe (struct usb_interface *intf,
694 int call_interface_num = -1; 764 int call_interface_num = -1;
695 int data_interface_num; 765 int data_interface_num;
696 unsigned long quirks; 766 unsigned long quirks;
767 int i;
697 768
698 /* handle quirks deadly to normal probing*/ 769 /* handle quirks deadly to normal probing*/
699 quirks = (unsigned long)id->driver_info; 770 quirks = (unsigned long)id->driver_info;
@@ -833,7 +904,7 @@ skip_normal_probe:
833 } 904 }
834 905
835 ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); 906 ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize);
836 readsize = le16_to_cpu(epread->wMaxPacketSize); 907 readsize = le16_to_cpu(epread->wMaxPacketSize)*2;
837 acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize); 908 acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize);
838 acm->control = control_interface; 909 acm->control = control_interface;
839 acm->data = data_interface; 910 acm->data = data_interface;
@@ -842,12 +913,14 @@ skip_normal_probe:
842 acm->ctrl_caps = ac_management_function; 913 acm->ctrl_caps = ac_management_function;
843 acm->ctrlsize = ctrlsize; 914 acm->ctrlsize = ctrlsize;
844 acm->readsize = readsize; 915 acm->readsize = readsize;
845 acm->bh.func = acm_rx_tasklet; 916 acm->urb_task.func = acm_rx_tasklet;
846 acm->bh.data = (unsigned long) acm; 917 acm->urb_task.data = (unsigned long) acm;
847 INIT_WORK(&acm->work, acm_softint, acm); 918 INIT_WORK(&acm->work, acm_softint, acm);
848 spin_lock_init(&acm->throttle_lock); 919 spin_lock_init(&acm->throttle_lock);
849 spin_lock_init(&acm->write_lock); 920 spin_lock_init(&acm->write_lock);
921 spin_lock_init(&acm->read_lock);
850 acm->write_ready = 1; 922 acm->write_ready = 1;
923 acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress);
851 924
852 buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); 925 buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
853 if (!buf) { 926 if (!buf) {
@@ -856,13 +929,6 @@ skip_normal_probe:
856 } 929 }
857 acm->ctrl_buffer = buf; 930 acm->ctrl_buffer = buf;
858 931
859 buf = usb_buffer_alloc(usb_dev, readsize, GFP_KERNEL, &acm->read_dma);
860 if (!buf) {
861 dev_dbg(&intf->dev, "out of memory (read buffer alloc)\n");
862 goto alloc_fail3;
863 }
864 acm->read_buffer = buf;
865
866 if (acm_write_buffers_alloc(acm) < 0) { 932 if (acm_write_buffers_alloc(acm) < 0) {
867 dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); 933 dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n");
868 goto alloc_fail4; 934 goto alloc_fail4;
@@ -873,10 +939,25 @@ skip_normal_probe:
873 dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); 939 dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n");
874 goto alloc_fail5; 940 goto alloc_fail5;
875 } 941 }
876 acm->readurb = usb_alloc_urb(0, GFP_KERNEL); 942 for (i = 0; i < ACM_NRU; i++) {
877 if (!acm->readurb) { 943 struct acm_ru *rcv = &(acm->ru[i]);
878 dev_dbg(&intf->dev, "out of memory (readurb kmalloc)\n"); 944
879 goto alloc_fail6; 945 if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
946 dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n");
947 goto alloc_fail7;
948 }
949
950 rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
951 rcv->instance = acm;
952 }
953 for (i = 0; i < ACM_NRB; i++) {
954 struct acm_rb *buf = &(acm->rb[i]);
955
956 // Using usb_buffer_alloc instead of kmalloc as Oliver suggested
957 if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) {
958 dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n");
959 goto alloc_fail7;
960 }
880 } 961 }
881 acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); 962 acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
882 if (!acm->writeurb) { 963 if (!acm->writeurb) {
@@ -889,15 +970,9 @@ skip_normal_probe:
889 acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 970 acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
890 acm->ctrlurb->transfer_dma = acm->ctrl_dma; 971 acm->ctrlurb->transfer_dma = acm->ctrl_dma;
891 972
892 usb_fill_bulk_urb(acm->readurb, usb_dev, usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress),
893 acm->read_buffer, readsize, acm_read_bulk, acm);
894 acm->readurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP;
895 acm->readurb->transfer_dma = acm->read_dma;
896
897 usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), 973 usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
898 NULL, acm->writesize, acm_write_bulk, acm); 974 NULL, acm->writesize, acm_write_bulk, acm);
899 acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; 975 acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP;
900 /* acm->writeurb->transfer_dma = 0; */
901 976
902 dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); 977 dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
903 978
@@ -917,14 +992,14 @@ skip_normal_probe:
917 return 0; 992 return 0;
918 993
919alloc_fail7: 994alloc_fail7:
920 usb_free_urb(acm->readurb); 995 for (i = 0; i < ACM_NRB; i++)
921alloc_fail6: 996 usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
997 for (i = 0; i < ACM_NRU; i++)
998 usb_free_urb(acm->ru[i].urb);
922 usb_free_urb(acm->ctrlurb); 999 usb_free_urb(acm->ctrlurb);
923alloc_fail5: 1000alloc_fail5:
924 acm_write_buffers_free(acm); 1001 acm_write_buffers_free(acm);
925alloc_fail4: 1002alloc_fail4:
926 usb_buffer_free(usb_dev, readsize, acm->read_buffer, acm->read_dma);
927alloc_fail3:
928 usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); 1003 usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
929alloc_fail2: 1004alloc_fail2:
930 kfree(acm); 1005 kfree(acm);
@@ -936,6 +1011,7 @@ static void acm_disconnect(struct usb_interface *intf)
936{ 1011{
937 struct acm *acm = usb_get_intfdata (intf); 1012 struct acm *acm = usb_get_intfdata (intf);
938 struct usb_device *usb_dev = interface_to_usbdev(intf); 1013 struct usb_device *usb_dev = interface_to_usbdev(intf);
1014 int i;
939 1015
940 if (!acm || !acm->dev) { 1016 if (!acm || !acm->dev) {
941 dbg("disconnect on nonexisting interface"); 1017 dbg("disconnect on nonexisting interface");
@@ -946,15 +1022,24 @@ static void acm_disconnect(struct usb_interface *intf)
946 acm->dev = NULL; 1022 acm->dev = NULL;
947 usb_set_intfdata (intf, NULL); 1023 usb_set_intfdata (intf, NULL);
948 1024
1025 tasklet_disable(&acm->urb_task);
1026
949 usb_kill_urb(acm->ctrlurb); 1027 usb_kill_urb(acm->ctrlurb);
950 usb_kill_urb(acm->readurb);
951 usb_kill_urb(acm->writeurb); 1028 usb_kill_urb(acm->writeurb);
1029 for (i = 0; i < ACM_NRU; i++)
1030 usb_kill_urb(acm->ru[i].urb);
1031
1032 INIT_LIST_HEAD(&acm->filled_read_bufs);
1033 INIT_LIST_HEAD(&acm->spare_read_bufs);
1034
1035 tasklet_enable(&acm->urb_task);
952 1036
953 flush_scheduled_work(); /* wait for acm_softint */ 1037 flush_scheduled_work(); /* wait for acm_softint */
954 1038
955 acm_write_buffers_free(acm); 1039 acm_write_buffers_free(acm);
956 usb_buffer_free(usb_dev, acm->readsize, acm->read_buffer, acm->read_dma);
957 usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); 1040 usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
1041 for (i = 0; i < ACM_NRB; i++)
1042 usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
958 1043
959 usb_driver_release_interface(&acm_driver, acm->data); 1044 usb_driver_release_interface(&acm_driver, acm->data);
960 1045
@@ -1003,7 +1088,6 @@ static struct usb_device_id acm_ids[] = {
1003MODULE_DEVICE_TABLE (usb, acm_ids); 1088MODULE_DEVICE_TABLE (usb, acm_ids);
1004 1089
1005static struct usb_driver acm_driver = { 1090static struct usb_driver acm_driver = {
1006 .owner = THIS_MODULE,
1007 .name = "cdc_acm", 1091 .name = "cdc_acm",
1008 .probe = acm_probe, 1092 .probe = acm_probe,
1009 .disconnect = acm_disconnect, 1093 .disconnect = acm_disconnect,