diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/usb/class/cdc-acm.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/usb/class/cdc-acm.c')
-rw-r--r-- | drivers/usb/class/cdc-acm.c | 493 |
1 files changed, 211 insertions, 282 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index bc62fae0680f..dac7676ce21b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -7,35 +7,12 @@ | |||
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 | * |
13 | * Sponsored by SuSE | 14 | * Sponsored by SuSE |
14 | * | 15 | * |
15 | * ChangeLog: | ||
16 | * v0.9 - thorough cleaning, URBification, almost a rewrite | ||
17 | * v0.10 - some more cleanups | ||
18 | * v0.11 - fixed flow control, read error doesn't stop reads | ||
19 | * v0.12 - added TIOCM ioctls, added break handling, made struct acm | ||
20 | * kmalloced | ||
21 | * v0.13 - added termios, added hangup | ||
22 | * v0.14 - sized down struct acm | ||
23 | * v0.15 - fixed flow control again - characters could be lost | ||
24 | * v0.16 - added code for modems with swapped data and control interfaces | ||
25 | * v0.17 - added new style probing | ||
26 | * v0.18 - fixed new style probing for devices with more configurations | ||
27 | * v0.19 - fixed CLOCAL handling (thanks to Richard Shih-Ping Chan) | ||
28 | * v0.20 - switched to probing on interface (rather than device) class | ||
29 | * v0.21 - revert to probing on device for devices with multiple configs | ||
30 | * v0.22 - probe only the control interface. if usbcore doesn't choose the | ||
31 | * config we want, sysadmin changes bConfigurationValue in sysfs. | ||
32 | * v0.23 - use softirq for rx processing, as needed by tty layer | ||
33 | * v0.24 - change probe method to evaluate CDC union descriptor | ||
34 | * v0.25 - downstream tasks paralelized to maximize throughput | ||
35 | * v0.26 - multiple write urbs, writesize increased | ||
36 | */ | ||
37 | |||
38 | /* | ||
39 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
40 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
41 | * the Free Software Foundation; either version 2 of the License, or | 18 | * the Free Software Foundation; either version 2 of the License, or |
@@ -74,13 +51,7 @@ | |||
74 | #include "cdc-acm.h" | 51 | #include "cdc-acm.h" |
75 | 52 | ||
76 | 53 | ||
77 | #define ACM_CLOSE_TIMEOUT 15 /* seconds to let writes drain */ | 54 | #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek, Johan Hovold" |
78 | |||
79 | /* | ||
80 | * Version Information | ||
81 | */ | ||
82 | #define DRIVER_VERSION "v0.26" | ||
83 | #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek" | ||
84 | #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" |
85 | 56 | ||
86 | static struct usb_driver acm_driver; | 57 | static struct usb_driver acm_driver; |
@@ -94,12 +65,6 @@ static DEFINE_MUTEX(open_mutex); | |||
94 | static const struct tty_port_operations acm_port_ops = { | 65 | static const struct tty_port_operations acm_port_ops = { |
95 | }; | 66 | }; |
96 | 67 | ||
97 | #ifdef VERBOSE_DEBUG | ||
98 | #define verbose 1 | ||
99 | #else | ||
100 | #define verbose 0 | ||
101 | #endif | ||
102 | |||
103 | /* | 68 | /* |
104 | * Functions for ACM control messages. | 69 | * Functions for ACM control messages. |
105 | */ | 70 | */ |
@@ -111,8 +76,9 @@ static int acm_ctrl_msg(struct acm *acm, int request, int value, | |||
111 | request, USB_RT_ACM, value, | 76 | request, USB_RT_ACM, value, |
112 | acm->control->altsetting[0].desc.bInterfaceNumber, | 77 | acm->control->altsetting[0].desc.bInterfaceNumber, |
113 | buf, len, 5000); | 78 | buf, len, 5000); |
114 | dbg("acm_control_msg: rq: 0x%02x val: %#x len: %#x result: %d", | 79 | dev_dbg(&acm->control->dev, |
115 | request, value, len, retval); | 80 | "%s - rq 0x%02x, val %#x, len %#x, result %d\n", |
81 | __func__, request, value, len, retval); | ||
116 | return retval < 0 ? retval : 0; | 82 | return retval < 0 ? retval : 0; |
117 | } | 83 | } |
118 | 84 | ||
@@ -192,7 +158,9 @@ static int acm_start_wb(struct acm *acm, struct acm_wb *wb) | |||
192 | 158 | ||
193 | rc = usb_submit_urb(wb->urb, GFP_ATOMIC); | 159 | rc = usb_submit_urb(wb->urb, GFP_ATOMIC); |
194 | if (rc < 0) { | 160 | if (rc < 0) { |
195 | dbg("usb_submit_urb(write bulk) failed: %d", rc); | 161 | dev_err(&acm->data->dev, |
162 | "%s - usb_submit_urb(write bulk) failed: %d\n", | ||
163 | __func__, rc); | ||
196 | acm_write_done(acm, wb); | 164 | acm_write_done(acm, wb); |
197 | } | 165 | } |
198 | return rc; | 166 | return rc; |
@@ -211,7 +179,8 @@ static int acm_write_start(struct acm *acm, int wbn) | |||
211 | return -ENODEV; | 179 | return -ENODEV; |
212 | } | 180 | } |
213 | 181 | ||
214 | dbg("%s susp_count: %d", __func__, acm->susp_count); | 182 | dev_vdbg(&acm->data->dev, "%s - susp_count %d\n", __func__, |
183 | acm->susp_count); | ||
215 | usb_autopm_get_interface_async(acm->control); | 184 | usb_autopm_get_interface_async(acm->control); |
216 | if (acm->susp_count) { | 185 | if (acm->susp_count) { |
217 | if (!acm->delayed_wb) | 186 | if (!acm->delayed_wb) |
@@ -287,21 +256,27 @@ static void acm_ctrl_irq(struct urb *urb) | |||
287 | case -ENOENT: | 256 | case -ENOENT: |
288 | case -ESHUTDOWN: | 257 | case -ESHUTDOWN: |
289 | /* this urb is terminated, clean up */ | 258 | /* this urb is terminated, clean up */ |
290 | dbg("%s - urb shutting down with status: %d", __func__, status); | 259 | dev_dbg(&acm->control->dev, |
260 | "%s - urb shutting down with status: %d\n", | ||
261 | __func__, status); | ||
291 | return; | 262 | return; |
292 | default: | 263 | default: |
293 | dbg("%s - nonzero urb status received: %d", __func__, status); | 264 | dev_dbg(&acm->control->dev, |
265 | "%s - nonzero urb status received: %d\n", | ||
266 | __func__, status); | ||
294 | goto exit; | 267 | goto exit; |
295 | } | 268 | } |
296 | 269 | ||
297 | if (!ACM_READY(acm)) | 270 | if (!ACM_READY(acm)) |
298 | goto exit; | 271 | goto exit; |
299 | 272 | ||
273 | usb_mark_last_busy(acm->dev); | ||
274 | |||
300 | data = (unsigned char *)(dr + 1); | 275 | data = (unsigned char *)(dr + 1); |
301 | switch (dr->bNotificationType) { | 276 | switch (dr->bNotificationType) { |
302 | case USB_CDC_NOTIFY_NETWORK_CONNECTION: | 277 | case USB_CDC_NOTIFY_NETWORK_CONNECTION: |
303 | dbg("%s network", dr->wValue ? | 278 | dev_dbg(&acm->control->dev, "%s - network connection: %d\n", |
304 | "connected to" : "disconnected from"); | 279 | __func__, dr->wValue); |
305 | break; | 280 | break; |
306 | 281 | ||
307 | case USB_CDC_NOTIFY_SERIAL_STATE: | 282 | case USB_CDC_NOTIFY_SERIAL_STATE: |
@@ -311,7 +286,8 @@ static void acm_ctrl_irq(struct urb *urb) | |||
311 | if (tty) { | 286 | if (tty) { |
312 | if (!acm->clocal && | 287 | if (!acm->clocal && |
313 | (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { | 288 | (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { |
314 | dbg("calling hangup"); | 289 | dev_dbg(&acm->control->dev, |
290 | "%s - calling hangup\n", __func__); | ||
315 | tty_hangup(tty); | 291 | tty_hangup(tty); |
316 | } | 292 | } |
317 | tty_kref_put(tty); | 293 | tty_kref_put(tty); |
@@ -319,7 +295,10 @@ static void acm_ctrl_irq(struct urb *urb) | |||
319 | 295 | ||
320 | acm->ctrlin = newctrl; | 296 | acm->ctrlin = newctrl; |
321 | 297 | ||
322 | dbg("input control lines: dcd%c dsr%c break%c ring%c framing%c parity%c overrun%c", | 298 | dev_dbg(&acm->control->dev, |
299 | "%s - input control lines: dcd%c dsr%c break%c " | ||
300 | "ring%c framing%c parity%c overrun%c\n", | ||
301 | __func__, | ||
323 | acm->ctrlin & ACM_CTRL_DCD ? '+' : '-', | 302 | acm->ctrlin & ACM_CTRL_DCD ? '+' : '-', |
324 | acm->ctrlin & ACM_CTRL_DSR ? '+' : '-', | 303 | acm->ctrlin & ACM_CTRL_DSR ? '+' : '-', |
325 | acm->ctrlin & ACM_CTRL_BRK ? '+' : '-', | 304 | acm->ctrlin & ACM_CTRL_BRK ? '+' : '-', |
@@ -330,175 +309,107 @@ static void acm_ctrl_irq(struct urb *urb) | |||
330 | break; | 309 | break; |
331 | 310 | ||
332 | default: | 311 | default: |
333 | dbg("unknown notification %d received: index %d len %d data0 %d data1 %d", | 312 | dev_dbg(&acm->control->dev, |
313 | "%s - unknown notification %d received: index %d " | ||
314 | "len %d data0 %d data1 %d\n", | ||
315 | __func__, | ||
334 | dr->bNotificationType, dr->wIndex, | 316 | dr->bNotificationType, dr->wIndex, |
335 | dr->wLength, data[0], data[1]); | 317 | dr->wLength, data[0], data[1]); |
336 | break; | 318 | break; |
337 | } | 319 | } |
338 | exit: | 320 | exit: |
339 | usb_mark_last_busy(acm->dev); | ||
340 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 321 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
341 | if (retval) | 322 | if (retval) |
342 | dev_err(&urb->dev->dev, "%s - usb_submit_urb failed with " | 323 | dev_err(&acm->control->dev, "%s - usb_submit_urb failed: %d\n", |
343 | "result %d", __func__, retval); | 324 | __func__, retval); |
344 | } | 325 | } |
345 | 326 | ||
346 | /* data interface returns incoming bytes, or we got unthrottled */ | 327 | static int acm_submit_read_urb(struct acm *acm, int index, gfp_t mem_flags) |
347 | static void acm_read_bulk(struct urb *urb) | ||
348 | { | 328 | { |
349 | struct acm_rb *buf; | 329 | int res; |
350 | struct acm_ru *rcv = urb->context; | ||
351 | struct acm *acm = rcv->instance; | ||
352 | int status = urb->status; | ||
353 | 330 | ||
354 | dbg("Entering acm_read_bulk with status %d", status); | 331 | if (!test_and_clear_bit(index, &acm->read_urbs_free)) |
332 | return 0; | ||
355 | 333 | ||
356 | if (!ACM_READY(acm)) { | 334 | dev_vdbg(&acm->data->dev, "%s - urb %d\n", __func__, index); |
357 | dev_dbg(&acm->data->dev, "Aborting, acm not ready"); | 335 | |
358 | 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; | ||
359 | } | 345 | } |
360 | usb_mark_last_busy(acm->dev); | ||
361 | 346 | ||
362 | if (status) | 347 | return 0; |
363 | dev_dbg(&acm->data->dev, "bulk rx status %d\n", status); | 348 | } |
364 | 349 | ||
365 | buf = rcv->buffer; | 350 | static int acm_submit_read_urbs(struct acm *acm, gfp_t mem_flags) |
366 | buf->size = urb->actual_length; | 351 | { |
352 | int res; | ||
353 | int i; | ||
367 | 354 | ||
368 | if (likely(status == 0)) { | 355 | for (i = 0; i < acm->rx_buflimit; ++i) { |
369 | spin_lock(&acm->read_lock); | 356 | res = acm_submit_read_urb(acm, i, mem_flags); |
370 | acm->processing++; | 357 | if (res) |
371 | list_add_tail(&rcv->list, &acm->spare_read_urbs); | 358 | return res; |
372 | list_add_tail(&buf->list, &acm->filled_read_bufs); | ||
373 | spin_unlock(&acm->read_lock); | ||
374 | } else { | ||
375 | /* we drop the buffer due to an error */ | ||
376 | spin_lock(&acm->read_lock); | ||
377 | list_add_tail(&rcv->list, &acm->spare_read_urbs); | ||
378 | list_add(&buf->list, &acm->spare_read_bufs); | ||
379 | spin_unlock(&acm->read_lock); | ||
380 | /* nevertheless the tasklet must be kicked unconditionally | ||
381 | so the queue cannot dry up */ | ||
382 | } | 359 | } |
383 | if (likely(!acm->susp_count)) | 360 | |
384 | tasklet_schedule(&acm->urb_task); | 361 | return 0; |
385 | } | 362 | } |
386 | 363 | ||
387 | static void acm_rx_tasklet(unsigned long _acm) | 364 | static void acm_process_read_urb(struct acm *acm, struct urb *urb) |
388 | { | 365 | { |
389 | struct acm *acm = (void *)_acm; | ||
390 | struct acm_rb *buf; | ||
391 | struct tty_struct *tty; | 366 | struct tty_struct *tty; |
392 | struct acm_ru *rcv; | ||
393 | unsigned long flags; | ||
394 | unsigned char throttled; | ||
395 | |||
396 | dbg("Entering acm_rx_tasklet"); | ||
397 | |||
398 | if (!ACM_READY(acm)) { | ||
399 | dbg("acm_rx_tasklet: ACM not ready"); | ||
400 | return; | ||
401 | } | ||
402 | 367 | ||
403 | spin_lock_irqsave(&acm->throttle_lock, flags); | 368 | if (!urb->actual_length) |
404 | throttled = acm->throttle; | ||
405 | spin_unlock_irqrestore(&acm->throttle_lock, flags); | ||
406 | if (throttled) { | ||
407 | dbg("acm_rx_tasklet: throttled"); | ||
408 | return; | 369 | return; |
409 | } | ||
410 | 370 | ||
411 | tty = tty_port_tty_get(&acm->port); | 371 | tty = tty_port_tty_get(&acm->port); |
372 | if (!tty) | ||
373 | return; | ||
412 | 374 | ||
413 | next_buffer: | 375 | tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length); |
414 | spin_lock_irqsave(&acm->read_lock, flags); | 376 | tty_flip_buffer_push(tty); |
415 | if (list_empty(&acm->filled_read_bufs)) { | ||
416 | spin_unlock_irqrestore(&acm->read_lock, flags); | ||
417 | goto urbs; | ||
418 | } | ||
419 | buf = list_entry(acm->filled_read_bufs.next, | ||
420 | struct acm_rb, list); | ||
421 | list_del(&buf->list); | ||
422 | spin_unlock_irqrestore(&acm->read_lock, flags); | ||
423 | |||
424 | dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size); | ||
425 | |||
426 | if (tty) { | ||
427 | spin_lock_irqsave(&acm->throttle_lock, flags); | ||
428 | throttled = acm->throttle; | ||
429 | spin_unlock_irqrestore(&acm->throttle_lock, flags); | ||
430 | if (!throttled) { | ||
431 | tty_insert_flip_string(tty, buf->base, buf->size); | ||
432 | tty_flip_buffer_push(tty); | ||
433 | } else { | ||
434 | tty_kref_put(tty); | ||
435 | dbg("Throttling noticed"); | ||
436 | spin_lock_irqsave(&acm->read_lock, flags); | ||
437 | list_add(&buf->list, &acm->filled_read_bufs); | ||
438 | spin_unlock_irqrestore(&acm->read_lock, flags); | ||
439 | return; | ||
440 | } | ||
441 | } | ||
442 | |||
443 | spin_lock_irqsave(&acm->read_lock, flags); | ||
444 | list_add(&buf->list, &acm->spare_read_bufs); | ||
445 | spin_unlock_irqrestore(&acm->read_lock, flags); | ||
446 | goto next_buffer; | ||
447 | 377 | ||
448 | urbs: | ||
449 | tty_kref_put(tty); | 378 | tty_kref_put(tty); |
379 | } | ||
450 | 380 | ||
451 | while (!list_empty(&acm->spare_read_bufs)) { | 381 | static void acm_read_bulk_callback(struct urb *urb) |
452 | spin_lock_irqsave(&acm->read_lock, flags); | 382 | { |
453 | if (list_empty(&acm->spare_read_urbs)) { | 383 | struct acm_rb *rb = urb->context; |
454 | acm->processing = 0; | 384 | struct acm *acm = rb->instance; |
455 | spin_unlock_irqrestore(&acm->read_lock, flags); | 385 | unsigned long flags; |
456 | return; | ||
457 | } | ||
458 | rcv = list_entry(acm->spare_read_urbs.next, | ||
459 | struct acm_ru, list); | ||
460 | list_del(&rcv->list); | ||
461 | spin_unlock_irqrestore(&acm->read_lock, flags); | ||
462 | 386 | ||
463 | buf = list_entry(acm->spare_read_bufs.next, | 387 | dev_vdbg(&acm->data->dev, "%s - urb %d, len %d\n", __func__, |
464 | struct acm_rb, list); | 388 | rb->index, urb->actual_length); |
465 | list_del(&buf->list); | 389 | set_bit(rb->index, &acm->read_urbs_free); |
466 | 390 | ||
467 | 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); | ||
468 | 396 | ||
469 | if (acm->is_int_ep) | 397 | if (urb->status) { |
470 | usb_fill_int_urb(rcv->urb, acm->dev, | 398 | dev_dbg(&acm->data->dev, "%s - non-zero urb status: %d\n", |
471 | acm->rx_endpoint, | 399 | __func__, urb->status); |
472 | buf->base, | 400 | return; |
473 | acm->readsize, | ||
474 | acm_read_bulk, rcv, acm->bInterval); | ||
475 | else | ||
476 | usb_fill_bulk_urb(rcv->urb, acm->dev, | ||
477 | acm->rx_endpoint, | ||
478 | buf->base, | ||
479 | acm->readsize, | ||
480 | acm_read_bulk, rcv); | ||
481 | rcv->urb->transfer_dma = buf->dma; | ||
482 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
483 | |||
484 | /* This shouldn't kill the driver as unsuccessful URBs are | ||
485 | returned to the free-urbs-pool and resubmited ASAP */ | ||
486 | spin_lock_irqsave(&acm->read_lock, flags); | ||
487 | if (acm->susp_count || | ||
488 | usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) { | ||
489 | list_add(&buf->list, &acm->spare_read_bufs); | ||
490 | list_add(&rcv->list, &acm->spare_read_urbs); | ||
491 | acm->processing = 0; | ||
492 | spin_unlock_irqrestore(&acm->read_lock, flags); | ||
493 | return; | ||
494 | } else { | ||
495 | spin_unlock_irqrestore(&acm->read_lock, flags); | ||
496 | dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p", rcv->urb, rcv, buf); | ||
497 | } | ||
498 | } | 401 | } |
402 | acm_process_read_urb(acm, urb); | ||
403 | |||
404 | /* throttle device if requested by tty */ | ||
499 | spin_lock_irqsave(&acm->read_lock, flags); | 405 | spin_lock_irqsave(&acm->read_lock, flags); |
500 | acm->processing = 0; | 406 | acm->throttled = acm->throttle_req; |
501 | 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 | } | ||
502 | } | 413 | } |
503 | 414 | ||
504 | /* data interface wrote those outgoing bytes */ | 415 | /* data interface wrote those outgoing bytes */ |
@@ -508,9 +419,9 @@ static void acm_write_bulk(struct urb *urb) | |||
508 | struct acm *acm = wb->instance; | 419 | struct acm *acm = wb->instance; |
509 | unsigned long flags; | 420 | unsigned long flags; |
510 | 421 | ||
511 | if (verbose || urb->status | 422 | if (urb->status || (urb->actual_length != urb->transfer_buffer_length)) |
512 | || (urb->actual_length != urb->transfer_buffer_length)) | 423 | dev_vdbg(&acm->data->dev, "%s - len %d/%d, status %d\n", |
513 | dev_dbg(&acm->data->dev, "tx %d/%d bytes -- > %d\n", | 424 | __func__, |
514 | urb->actual_length, | 425 | urb->actual_length, |
515 | urb->transfer_buffer_length, | 426 | urb->transfer_buffer_length, |
516 | urb->status); | 427 | urb->status); |
@@ -520,8 +431,6 @@ static void acm_write_bulk(struct urb *urb) | |||
520 | spin_unlock_irqrestore(&acm->write_lock, flags); | 431 | spin_unlock_irqrestore(&acm->write_lock, flags); |
521 | if (ACM_READY(acm)) | 432 | if (ACM_READY(acm)) |
522 | schedule_work(&acm->work); | 433 | schedule_work(&acm->work); |
523 | else | ||
524 | wake_up_interruptible(&acm->drain_wait); | ||
525 | } | 434 | } |
526 | 435 | ||
527 | static void acm_softint(struct work_struct *work) | 436 | static void acm_softint(struct work_struct *work) |
@@ -529,10 +438,13 @@ static void acm_softint(struct work_struct *work) | |||
529 | struct acm *acm = container_of(work, struct acm, work); | 438 | struct acm *acm = container_of(work, struct acm, work); |
530 | struct tty_struct *tty; | 439 | struct tty_struct *tty; |
531 | 440 | ||
532 | dev_vdbg(&acm->data->dev, "tx work\n"); | 441 | dev_vdbg(&acm->data->dev, "%s\n", __func__); |
442 | |||
533 | if (!ACM_READY(acm)) | 443 | if (!ACM_READY(acm)) |
534 | return; | 444 | return; |
535 | tty = tty_port_tty_get(&acm->port); | 445 | tty = tty_port_tty_get(&acm->port); |
446 | if (!tty) | ||
447 | return; | ||
536 | tty_wakeup(tty); | 448 | tty_wakeup(tty); |
537 | tty_kref_put(tty); | 449 | tty_kref_put(tty); |
538 | } | 450 | } |
@@ -545,8 +457,6 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
545 | { | 457 | { |
546 | struct acm *acm; | 458 | struct acm *acm; |
547 | int rv = -ENODEV; | 459 | int rv = -ENODEV; |
548 | int i; | ||
549 | dbg("Entering acm_tty_open."); | ||
550 | 460 | ||
551 | mutex_lock(&open_mutex); | 461 | mutex_lock(&open_mutex); |
552 | 462 | ||
@@ -556,6 +466,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
556 | else | 466 | else |
557 | rv = 0; | 467 | rv = 0; |
558 | 468 | ||
469 | dev_dbg(&acm->control->dev, "%s\n", __func__); | ||
470 | |||
559 | set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); | 471 | set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); |
560 | 472 | ||
561 | tty->driver_data = acm; | 473 | tty->driver_data = acm; |
@@ -575,38 +487,28 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
575 | 487 | ||
576 | acm->ctrlurb->dev = acm->dev; | 488 | acm->ctrlurb->dev = acm->dev; |
577 | if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { | 489 | if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { |
578 | dbg("usb_submit_urb(ctrl irq) failed"); | 490 | dev_err(&acm->control->dev, |
491 | "%s - usb_submit_urb(ctrl irq) failed\n", __func__); | ||
579 | goto bail_out; | 492 | goto bail_out; |
580 | } | 493 | } |
581 | 494 | ||
582 | if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) && | 495 | if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) && |
583 | (acm->ctrl_caps & USB_CDC_CAP_LINE)) | 496 | (acm->ctrl_caps & USB_CDC_CAP_LINE)) |
584 | goto full_bailout; | 497 | goto bail_out; |
585 | 498 | ||
586 | usb_autopm_put_interface(acm->control); | 499 | usb_autopm_put_interface(acm->control); |
587 | 500 | ||
588 | INIT_LIST_HEAD(&acm->spare_read_urbs); | 501 | if (acm_submit_read_urbs(acm, GFP_KERNEL)) |
589 | INIT_LIST_HEAD(&acm->spare_read_bufs); | 502 | goto bail_out; |
590 | INIT_LIST_HEAD(&acm->filled_read_bufs); | ||
591 | |||
592 | for (i = 0; i < acm->rx_buflimit; i++) | ||
593 | list_add(&(acm->ru[i].list), &acm->spare_read_urbs); | ||
594 | for (i = 0; i < acm->rx_buflimit; i++) | ||
595 | list_add(&(acm->rb[i].list), &acm->spare_read_bufs); | ||
596 | |||
597 | acm->throttle = 0; | ||
598 | 503 | ||
599 | set_bit(ASYNCB_INITIALIZED, &acm->port.flags); | 504 | set_bit(ASYNCB_INITIALIZED, &acm->port.flags); |
600 | rv = tty_port_block_til_ready(&acm->port, tty, filp); | 505 | rv = tty_port_block_til_ready(&acm->port, tty, filp); |
601 | tasklet_schedule(&acm->urb_task); | ||
602 | 506 | ||
603 | mutex_unlock(&acm->mutex); | 507 | mutex_unlock(&acm->mutex); |
604 | out: | 508 | out: |
605 | mutex_unlock(&open_mutex); | 509 | mutex_unlock(&open_mutex); |
606 | return rv; | 510 | return rv; |
607 | 511 | ||
608 | full_bailout: | ||
609 | usb_kill_urb(acm->ctrlurb); | ||
610 | bail_out: | 512 | bail_out: |
611 | acm->port.count--; | 513 | acm->port.count--; |
612 | mutex_unlock(&acm->mutex); | 514 | mutex_unlock(&acm->mutex); |
@@ -619,26 +521,24 @@ early_bail: | |||
619 | 521 | ||
620 | static void acm_tty_unregister(struct acm *acm) | 522 | static void acm_tty_unregister(struct acm *acm) |
621 | { | 523 | { |
622 | int i, nr; | 524 | int i; |
623 | 525 | ||
624 | nr = acm->rx_buflimit; | ||
625 | tty_unregister_device(acm_tty_driver, acm->minor); | 526 | tty_unregister_device(acm_tty_driver, acm->minor); |
626 | usb_put_intf(acm->control); | 527 | usb_put_intf(acm->control); |
627 | acm_table[acm->minor] = NULL; | 528 | acm_table[acm->minor] = NULL; |
628 | usb_free_urb(acm->ctrlurb); | 529 | usb_free_urb(acm->ctrlurb); |
629 | for (i = 0; i < ACM_NW; i++) | 530 | for (i = 0; i < ACM_NW; i++) |
630 | usb_free_urb(acm->wb[i].urb); | 531 | usb_free_urb(acm->wb[i].urb); |
631 | for (i = 0; i < nr; i++) | 532 | for (i = 0; i < acm->rx_buflimit; i++) |
632 | usb_free_urb(acm->ru[i].urb); | 533 | usb_free_urb(acm->read_urbs[i]); |
633 | kfree(acm->country_codes); | 534 | kfree(acm->country_codes); |
634 | kfree(acm); | 535 | kfree(acm); |
635 | } | 536 | } |
636 | 537 | ||
637 | static int acm_tty_chars_in_buffer(struct tty_struct *tty); | ||
638 | |||
639 | static void acm_port_down(struct acm *acm) | 538 | static void acm_port_down(struct acm *acm) |
640 | { | 539 | { |
641 | int i, nr = acm->rx_buflimit; | 540 | int i; |
541 | |||
642 | mutex_lock(&open_mutex); | 542 | mutex_lock(&open_mutex); |
643 | if (acm->dev) { | 543 | if (acm->dev) { |
644 | usb_autopm_get_interface(acm->control); | 544 | usb_autopm_get_interface(acm->control); |
@@ -646,8 +546,8 @@ static void acm_port_down(struct acm *acm) | |||
646 | usb_kill_urb(acm->ctrlurb); | 546 | usb_kill_urb(acm->ctrlurb); |
647 | for (i = 0; i < ACM_NW; i++) | 547 | for (i = 0; i < ACM_NW; i++) |
648 | usb_kill_urb(acm->wb[i].urb); | 548 | usb_kill_urb(acm->wb[i].urb); |
649 | for (i = 0; i < nr; i++) | 549 | for (i = 0; i < acm->rx_buflimit; i++) |
650 | usb_kill_urb(acm->ru[i].urb); | 550 | usb_kill_urb(acm->read_urbs[i]); |
651 | acm->control->needs_remote_wakeup = 0; | 551 | acm->control->needs_remote_wakeup = 0; |
652 | usb_autopm_put_interface(acm->control); | 552 | usb_autopm_put_interface(acm->control); |
653 | } | 553 | } |
@@ -693,13 +593,13 @@ static int acm_tty_write(struct tty_struct *tty, | |||
693 | int wbn; | 593 | int wbn; |
694 | struct acm_wb *wb; | 594 | struct acm_wb *wb; |
695 | 595 | ||
696 | dbg("Entering acm_tty_write to write %d bytes,", count); | ||
697 | |||
698 | if (!ACM_READY(acm)) | 596 | if (!ACM_READY(acm)) |
699 | return -EINVAL; | 597 | return -EINVAL; |
700 | if (!count) | 598 | if (!count) |
701 | return 0; | 599 | return 0; |
702 | 600 | ||
601 | dev_vdbg(&acm->data->dev, "%s - count %d\n", __func__, count); | ||
602 | |||
703 | spin_lock_irqsave(&acm->write_lock, flags); | 603 | spin_lock_irqsave(&acm->write_lock, flags); |
704 | wbn = acm_wb_alloc(acm); | 604 | wbn = acm_wb_alloc(acm); |
705 | if (wbn < 0) { | 605 | if (wbn < 0) { |
@@ -709,7 +609,7 @@ static int acm_tty_write(struct tty_struct *tty, | |||
709 | wb = &acm->wb[wbn]; | 609 | wb = &acm->wb[wbn]; |
710 | 610 | ||
711 | count = (count > acm->writesize) ? acm->writesize : count; | 611 | count = (count > acm->writesize) ? acm->writesize : count; |
712 | dbg("Get %d bytes...", count); | 612 | dev_vdbg(&acm->data->dev, "%s - write %d\n", __func__, count); |
713 | memcpy(wb->buf, buf, count); | 613 | memcpy(wb->buf, buf, count); |
714 | wb->len = count; | 614 | wb->len = count; |
715 | spin_unlock_irqrestore(&acm->write_lock, flags); | 615 | spin_unlock_irqrestore(&acm->write_lock, flags); |
@@ -746,22 +646,31 @@ static int acm_tty_chars_in_buffer(struct tty_struct *tty) | |||
746 | static void acm_tty_throttle(struct tty_struct *tty) | 646 | static void acm_tty_throttle(struct tty_struct *tty) |
747 | { | 647 | { |
748 | struct acm *acm = tty->driver_data; | 648 | struct acm *acm = tty->driver_data; |
649 | |||
749 | if (!ACM_READY(acm)) | 650 | if (!ACM_READY(acm)) |
750 | return; | 651 | return; |
751 | spin_lock_bh(&acm->throttle_lock); | 652 | |
752 | acm->throttle = 1; | 653 | spin_lock_irq(&acm->read_lock); |
753 | spin_unlock_bh(&acm->throttle_lock); | 654 | acm->throttle_req = 1; |
655 | spin_unlock_irq(&acm->read_lock); | ||
754 | } | 656 | } |
755 | 657 | ||
756 | static void acm_tty_unthrottle(struct tty_struct *tty) | 658 | static void acm_tty_unthrottle(struct tty_struct *tty) |
757 | { | 659 | { |
758 | struct acm *acm = tty->driver_data; | 660 | struct acm *acm = tty->driver_data; |
661 | unsigned int was_throttled; | ||
662 | |||
759 | if (!ACM_READY(acm)) | 663 | if (!ACM_READY(acm)) |
760 | return; | 664 | return; |
761 | spin_lock_bh(&acm->throttle_lock); | 665 | |
762 | acm->throttle = 0; | 666 | spin_lock_irq(&acm->read_lock); |
763 | spin_unlock_bh(&acm->throttle_lock); | 667 | was_throttled = acm->throttled; |
764 | 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); | ||
765 | } | 674 | } |
766 | 675 | ||
767 | static int acm_tty_break_ctl(struct tty_struct *tty, int state) | 676 | static int acm_tty_break_ctl(struct tty_struct *tty, int state) |
@@ -772,11 +681,12 @@ static int acm_tty_break_ctl(struct tty_struct *tty, int state) | |||
772 | return -EINVAL; | 681 | return -EINVAL; |
773 | retval = acm_send_break(acm, state ? 0xffff : 0); | 682 | retval = acm_send_break(acm, state ? 0xffff : 0); |
774 | if (retval < 0) | 683 | if (retval < 0) |
775 | dbg("send break failed"); | 684 | dev_dbg(&acm->control->dev, "%s - send break failed\n", |
685 | __func__); | ||
776 | return retval; | 686 | return retval; |
777 | } | 687 | } |
778 | 688 | ||
779 | static int acm_tty_tiocmget(struct tty_struct *tty, struct file *file) | 689 | static int acm_tty_tiocmget(struct tty_struct *tty) |
780 | { | 690 | { |
781 | struct acm *acm = tty->driver_data; | 691 | struct acm *acm = tty->driver_data; |
782 | 692 | ||
@@ -791,7 +701,7 @@ static int acm_tty_tiocmget(struct tty_struct *tty, struct file *file) | |||
791 | TIOCM_CTS; | 701 | TIOCM_CTS; |
792 | } | 702 | } |
793 | 703 | ||
794 | static int acm_tty_tiocmset(struct tty_struct *tty, struct file *file, | 704 | static int acm_tty_tiocmset(struct tty_struct *tty, |
795 | unsigned int set, unsigned int clear) | 705 | unsigned int set, unsigned int clear) |
796 | { | 706 | { |
797 | struct acm *acm = tty->driver_data; | 707 | struct acm *acm = tty->driver_data; |
@@ -813,7 +723,7 @@ static int acm_tty_tiocmset(struct tty_struct *tty, struct file *file, | |||
813 | return acm_set_control(acm, acm->ctrlout = newctrl); | 723 | return acm_set_control(acm, acm->ctrlout = newctrl); |
814 | } | 724 | } |
815 | 725 | ||
816 | static int acm_tty_ioctl(struct tty_struct *tty, struct file *file, | 726 | static int acm_tty_ioctl(struct tty_struct *tty, |
817 | unsigned int cmd, unsigned long arg) | 727 | unsigned int cmd, unsigned long arg) |
818 | { | 728 | { |
819 | struct acm *acm = tty->driver_data; | 729 | struct acm *acm = tty->driver_data; |
@@ -867,7 +777,9 @@ static void acm_tty_set_termios(struct tty_struct *tty, | |||
867 | 777 | ||
868 | if (memcmp(&acm->line, &newline, sizeof newline)) { | 778 | if (memcmp(&acm->line, &newline, sizeof newline)) { |
869 | memcpy(&acm->line, &newline, sizeof newline); | 779 | memcpy(&acm->line, &newline, sizeof newline); |
870 | dbg("set line: %d %d %d %d", le32_to_cpu(newline.dwDTERate), | 780 | dev_dbg(&acm->control->dev, "%s - set line: %d %d %d %d\n", |
781 | __func__, | ||
782 | le32_to_cpu(newline.dwDTERate), | ||
871 | newline.bCharFormat, newline.bParityType, | 783 | newline.bCharFormat, newline.bParityType, |
872 | newline.bDataBits); | 784 | newline.bDataBits); |
873 | acm_set_line(acm, &acm->line); | 785 | acm_set_line(acm, &acm->line); |
@@ -892,11 +804,11 @@ static void acm_write_buffers_free(struct acm *acm) | |||
892 | static void acm_read_buffers_free(struct acm *acm) | 804 | static void acm_read_buffers_free(struct acm *acm) |
893 | { | 805 | { |
894 | struct usb_device *usb_dev = interface_to_usbdev(acm->control); | 806 | struct usb_device *usb_dev = interface_to_usbdev(acm->control); |
895 | int i, n = acm->rx_buflimit; | 807 | int i; |
896 | 808 | ||
897 | for (i = 0; i < n; i++) | 809 | for (i = 0; i < acm->rx_buflimit; i++) |
898 | usb_free_coherent(usb_dev, acm->readsize, | 810 | usb_free_coherent(usb_dev, acm->readsize, |
899 | acm->rb[i].base, acm->rb[i].dma); | 811 | acm->read_buffers[i].base, acm->read_buffers[i].dma); |
900 | } | 812 | } |
901 | 813 | ||
902 | /* Little helper: write buffers allocate */ | 814 | /* Little helper: write buffers allocate */ |
@@ -941,7 +853,7 @@ static int acm_probe(struct usb_interface *intf, | |||
941 | u8 ac_management_function = 0; | 853 | u8 ac_management_function = 0; |
942 | u8 call_management_function = 0; | 854 | u8 call_management_function = 0; |
943 | int call_interface_num = -1; | 855 | int call_interface_num = -1; |
944 | int data_interface_num; | 856 | int data_interface_num = -1; |
945 | unsigned long quirks; | 857 | unsigned long quirks; |
946 | int num_rx_buf; | 858 | int num_rx_buf; |
947 | int i; | 859 | int i; |
@@ -1025,7 +937,11 @@ next_desc: | |||
1025 | if (!union_header) { | 937 | if (!union_header) { |
1026 | if (call_interface_num > 0) { | 938 | if (call_interface_num > 0) { |
1027 | dev_dbg(&intf->dev, "No union descriptor, using call management descriptor\n"); | 939 | dev_dbg(&intf->dev, "No union descriptor, using call management descriptor\n"); |
1028 | data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); | 940 | /* quirks for Droids MuIn LCD */ |
941 | if (quirks & NO_DATA_INTERFACE) | ||
942 | data_interface = usb_ifnum_to_if(usb_dev, 0); | ||
943 | else | ||
944 | data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); | ||
1029 | control_interface = intf; | 945 | control_interface = intf; |
1030 | } else { | 946 | } else { |
1031 | if (intf->cur_altsetting->desc.bNumEndpoints != 3) { | 947 | if (intf->cur_altsetting->desc.bNumEndpoints != 3) { |
@@ -1128,7 +1044,7 @@ skip_normal_probe: | |||
1128 | epwrite = t; | 1044 | epwrite = t; |
1129 | } | 1045 | } |
1130 | made_compressed_probe: | 1046 | made_compressed_probe: |
1131 | dbg("interfaces are valid"); | 1047 | dev_dbg(&intf->dev, "interfaces are valid\n"); |
1132 | for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); | 1048 | for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); |
1133 | 1049 | ||
1134 | if (minor == ACM_TTY_MINORS) { | 1050 | if (minor == ACM_TTY_MINORS) { |
@@ -1138,7 +1054,7 @@ made_compressed_probe: | |||
1138 | 1054 | ||
1139 | acm = kzalloc(sizeof(struct acm), GFP_KERNEL); | 1055 | acm = kzalloc(sizeof(struct acm), GFP_KERNEL); |
1140 | if (acm == NULL) { | 1056 | if (acm == NULL) { |
1141 | dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n"); | 1057 | dev_err(&intf->dev, "out of memory (acm kzalloc)\n"); |
1142 | goto alloc_fail; | 1058 | goto alloc_fail; |
1143 | } | 1059 | } |
1144 | 1060 | ||
@@ -1157,11 +1073,7 @@ made_compressed_probe: | |||
1157 | acm->ctrlsize = ctrlsize; | 1073 | acm->ctrlsize = ctrlsize; |
1158 | acm->readsize = readsize; | 1074 | acm->readsize = readsize; |
1159 | acm->rx_buflimit = num_rx_buf; | 1075 | acm->rx_buflimit = num_rx_buf; |
1160 | acm->urb_task.func = acm_rx_tasklet; | ||
1161 | acm->urb_task.data = (unsigned long) acm; | ||
1162 | INIT_WORK(&acm->work, acm_softint); | 1076 | INIT_WORK(&acm->work, acm_softint); |
1163 | init_waitqueue_head(&acm->drain_wait); | ||
1164 | spin_lock_init(&acm->throttle_lock); | ||
1165 | spin_lock_init(&acm->write_lock); | 1077 | spin_lock_init(&acm->write_lock); |
1166 | spin_lock_init(&acm->read_lock); | 1078 | spin_lock_init(&acm->read_lock); |
1167 | mutex_init(&acm->mutex); | 1079 | mutex_init(&acm->mutex); |
@@ -1174,53 +1086,69 @@ made_compressed_probe: | |||
1174 | 1086 | ||
1175 | buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); | 1087 | buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); |
1176 | if (!buf) { | 1088 | if (!buf) { |
1177 | dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n"); | 1089 | dev_err(&intf->dev, "out of memory (ctrl buffer alloc)\n"); |
1178 | goto alloc_fail2; | 1090 | goto alloc_fail2; |
1179 | } | 1091 | } |
1180 | acm->ctrl_buffer = buf; | 1092 | acm->ctrl_buffer = buf; |
1181 | 1093 | ||
1182 | if (acm_write_buffers_alloc(acm) < 0) { | 1094 | if (acm_write_buffers_alloc(acm) < 0) { |
1183 | dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); | 1095 | dev_err(&intf->dev, "out of memory (write buffer alloc)\n"); |
1184 | goto alloc_fail4; | 1096 | goto alloc_fail4; |
1185 | } | 1097 | } |
1186 | 1098 | ||
1187 | acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); | 1099 | acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); |
1188 | if (!acm->ctrlurb) { | 1100 | if (!acm->ctrlurb) { |
1189 | dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); | 1101 | dev_err(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); |
1190 | goto alloc_fail5; | 1102 | goto alloc_fail5; |
1191 | } | 1103 | } |
1192 | for (i = 0; i < num_rx_buf; i++) { | 1104 | for (i = 0; i < num_rx_buf; i++) { |
1193 | struct acm_ru *rcv = &(acm->ru[i]); | 1105 | struct acm_rb *rb = &(acm->read_buffers[i]); |
1106 | struct urb *urb; | ||
1194 | 1107 | ||
1195 | rcv->urb = usb_alloc_urb(0, GFP_KERNEL); | 1108 | rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, |
1196 | if (rcv->urb == NULL) { | 1109 | &rb->dma); |
1197 | dev_dbg(&intf->dev, | 1110 | if (!rb->base) { |
1198 | "out of memory (read urbs usb_alloc_urb)\n"); | 1111 | dev_err(&intf->dev, "out of memory " |
1112 | "(read bufs usb_alloc_coherent)\n"); | ||
1199 | goto alloc_fail6; | 1113 | goto alloc_fail6; |
1200 | } | 1114 | } |
1115 | rb->index = i; | ||
1116 | rb->instance = acm; | ||
1201 | 1117 | ||
1202 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1118 | urb = usb_alloc_urb(0, GFP_KERNEL); |
1203 | rcv->instance = acm; | 1119 | if (!urb) { |
1204 | } | 1120 | dev_err(&intf->dev, |
1205 | for (i = 0; i < num_rx_buf; i++) { | 1121 | "out of memory (read urbs usb_alloc_urb)\n"); |
1206 | struct acm_rb *rb = &(acm->rb[i]); | 1122 | goto alloc_fail6; |
1207 | |||
1208 | rb->base = usb_alloc_coherent(acm->dev, readsize, | ||
1209 | GFP_KERNEL, &rb->dma); | ||
1210 | if (!rb->base) { | ||
1211 | dev_dbg(&intf->dev, | ||
1212 | "out of memory (read bufs usb_alloc_coherent)\n"); | ||
1213 | goto alloc_fail7; | ||
1214 | } | 1123 | } |
1124 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
1125 | urb->transfer_dma = rb->dma; | ||
1126 | if (acm->is_int_ep) { | ||
1127 | usb_fill_int_urb(urb, acm->dev, | ||
1128 | acm->rx_endpoint, | ||
1129 | rb->base, | ||
1130 | acm->readsize, | ||
1131 | acm_read_bulk_callback, rb, | ||
1132 | acm->bInterval); | ||
1133 | } else { | ||
1134 | usb_fill_bulk_urb(urb, acm->dev, | ||
1135 | acm->rx_endpoint, | ||
1136 | rb->base, | ||
1137 | acm->readsize, | ||
1138 | acm_read_bulk_callback, rb); | ||
1139 | } | ||
1140 | |||
1141 | acm->read_urbs[i] = urb; | ||
1142 | __set_bit(i, &acm->read_urbs_free); | ||
1215 | } | 1143 | } |
1216 | for (i = 0; i < ACM_NW; i++) { | 1144 | for (i = 0; i < ACM_NW; i++) { |
1217 | struct acm_wb *snd = &(acm->wb[i]); | 1145 | struct acm_wb *snd = &(acm->wb[i]); |
1218 | 1146 | ||
1219 | snd->urb = usb_alloc_urb(0, GFP_KERNEL); | 1147 | snd->urb = usb_alloc_urb(0, GFP_KERNEL); |
1220 | if (snd->urb == NULL) { | 1148 | if (snd->urb == NULL) { |
1221 | dev_dbg(&intf->dev, | 1149 | dev_err(&intf->dev, |
1222 | "out of memory (write urbs usb_alloc_urb)"); | 1150 | "out of memory (write urbs usb_alloc_urb)\n"); |
1223 | goto alloc_fail8; | 1151 | goto alloc_fail7; |
1224 | } | 1152 | } |
1225 | 1153 | ||
1226 | if (usb_endpoint_xfer_int(epwrite)) | 1154 | if (usb_endpoint_xfer_int(epwrite)) |
@@ -1239,7 +1167,7 @@ made_compressed_probe: | |||
1239 | 1167 | ||
1240 | i = device_create_file(&intf->dev, &dev_attr_bmCapabilities); | 1168 | i = device_create_file(&intf->dev, &dev_attr_bmCapabilities); |
1241 | if (i < 0) | 1169 | if (i < 0) |
1242 | goto alloc_fail8; | 1170 | goto alloc_fail7; |
1243 | 1171 | ||
1244 | if (cfd) { /* export the country data */ | 1172 | if (cfd) { /* export the country data */ |
1245 | acm->country_codes = kmalloc(cfd->bLength - 4, GFP_KERNEL); | 1173 | acm->country_codes = kmalloc(cfd->bLength - 4, GFP_KERNEL); |
@@ -1291,14 +1219,13 @@ skip_countries: | |||
1291 | acm_table[minor] = acm; | 1219 | acm_table[minor] = acm; |
1292 | 1220 | ||
1293 | return 0; | 1221 | return 0; |
1294 | alloc_fail8: | 1222 | alloc_fail7: |
1295 | for (i = 0; i < ACM_NW; i++) | 1223 | for (i = 0; i < ACM_NW; i++) |
1296 | usb_free_urb(acm->wb[i].urb); | 1224 | usb_free_urb(acm->wb[i].urb); |
1297 | alloc_fail7: | ||
1298 | acm_read_buffers_free(acm); | ||
1299 | alloc_fail6: | 1225 | alloc_fail6: |
1300 | for (i = 0; i < num_rx_buf; i++) | 1226 | for (i = 0; i < num_rx_buf; i++) |
1301 | usb_free_urb(acm->ru[i].urb); | 1227 | usb_free_urb(acm->read_urbs[i]); |
1228 | acm_read_buffers_free(acm); | ||
1302 | usb_free_urb(acm->ctrlurb); | 1229 | usb_free_urb(acm->ctrlurb); |
1303 | alloc_fail5: | 1230 | alloc_fail5: |
1304 | acm_write_buffers_free(acm); | 1231 | acm_write_buffers_free(acm); |
@@ -1313,17 +1240,14 @@ alloc_fail: | |||
1313 | static void stop_data_traffic(struct acm *acm) | 1240 | static void stop_data_traffic(struct acm *acm) |
1314 | { | 1241 | { |
1315 | int i; | 1242 | int i; |
1316 | dbg("Entering stop_data_traffic"); | ||
1317 | 1243 | ||
1318 | tasklet_disable(&acm->urb_task); | 1244 | dev_dbg(&acm->control->dev, "%s\n", __func__); |
1319 | 1245 | ||
1320 | usb_kill_urb(acm->ctrlurb); | 1246 | usb_kill_urb(acm->ctrlurb); |
1321 | for (i = 0; i < ACM_NW; i++) | 1247 | for (i = 0; i < ACM_NW; i++) |
1322 | usb_kill_urb(acm->wb[i].urb); | 1248 | usb_kill_urb(acm->wb[i].urb); |
1323 | for (i = 0; i < acm->rx_buflimit; i++) | 1249 | for (i = 0; i < acm->rx_buflimit; i++) |
1324 | usb_kill_urb(acm->ru[i].urb); | 1250 | usb_kill_urb(acm->read_urbs[i]); |
1325 | |||
1326 | tasklet_enable(&acm->urb_task); | ||
1327 | 1251 | ||
1328 | cancel_work_sync(&acm->work); | 1252 | cancel_work_sync(&acm->work); |
1329 | } | 1253 | } |
@@ -1384,11 +1308,9 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message) | |||
1384 | if (message.event & PM_EVENT_AUTO) { | 1308 | if (message.event & PM_EVENT_AUTO) { |
1385 | int b; | 1309 | int b; |
1386 | 1310 | ||
1387 | spin_lock_irq(&acm->read_lock); | 1311 | spin_lock_irq(&acm->write_lock); |
1388 | spin_lock(&acm->write_lock); | 1312 | b = acm->transmitting; |
1389 | b = acm->processing + acm->transmitting; | 1313 | spin_unlock_irq(&acm->write_lock); |
1390 | spin_unlock(&acm->write_lock); | ||
1391 | spin_unlock_irq(&acm->read_lock); | ||
1392 | if (b) | 1314 | if (b) |
1393 | return -EBUSY; | 1315 | return -EBUSY; |
1394 | } | 1316 | } |
@@ -1450,7 +1372,7 @@ static int acm_resume(struct usb_interface *intf) | |||
1450 | if (rv < 0) | 1372 | if (rv < 0) |
1451 | goto err_out; | 1373 | goto err_out; |
1452 | 1374 | ||
1453 | tasklet_schedule(&acm->urb_task); | 1375 | rv = acm_submit_read_urbs(acm, GFP_NOIO); |
1454 | } | 1376 | } |
1455 | 1377 | ||
1456 | err_out: | 1378 | err_out: |
@@ -1607,6 +1529,9 @@ static const struct usb_device_id acm_ids[] = { | |||
1607 | { NOKIA_PCSUITE_ACM_INFO(0x0154), }, /* Nokia 5800 XpressMusic */ | 1529 | { NOKIA_PCSUITE_ACM_INFO(0x0154), }, /* Nokia 5800 XpressMusic */ |
1608 | { NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */ | 1530 | { NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */ |
1609 | { NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */ | 1531 | { NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */ |
1532 | { NOKIA_PCSUITE_ACM_INFO(0x0302), }, /* Nokia N8 */ | ||
1533 | { NOKIA_PCSUITE_ACM_INFO(0x0335), }, /* Nokia E7 */ | ||
1534 | { NOKIA_PCSUITE_ACM_INFO(0x03cd), }, /* Nokia C7 */ | ||
1610 | { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ | 1535 | { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ |
1611 | 1536 | ||
1612 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ | 1537 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ |
@@ -1614,7 +1539,12 @@ static const struct usb_device_id acm_ids[] = { | |||
1614 | /* Support Lego NXT using pbLua firmware */ | 1539 | /* Support Lego NXT using pbLua firmware */ |
1615 | { USB_DEVICE(0x0694, 0xff00), | 1540 | { USB_DEVICE(0x0694, 0xff00), |
1616 | .driver_info = NOT_A_MODEM, | 1541 | .driver_info = NOT_A_MODEM, |
1617 | }, | 1542 | }, |
1543 | |||
1544 | /* Support for Droids MuIn LCD */ | ||
1545 | { USB_DEVICE(0x04d8, 0x000b), | ||
1546 | .driver_info = NO_DATA_INTERFACE, | ||
1547 | }, | ||
1618 | 1548 | ||
1619 | /* control interfaces without any protocol set */ | 1549 | /* control interfaces without any protocol set */ |
1620 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, | 1550 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, |
@@ -1710,8 +1640,7 @@ static int __init acm_init(void) | |||
1710 | return retval; | 1640 | return retval; |
1711 | } | 1641 | } |
1712 | 1642 | ||
1713 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" | 1643 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); |
1714 | DRIVER_DESC "\n"); | ||
1715 | 1644 | ||
1716 | return 0; | 1645 | return 0; |
1717 | } | 1646 | } |