diff options
Diffstat (limited to 'drivers/usb/class/cdc-acm.c')
| -rw-r--r-- | drivers/usb/class/cdc-acm.c | 479 |
1 files changed, 200 insertions, 279 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index e057e5381465..395a347f2ebb 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,10 +256,14 @@ 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 | ||
| @@ -302,8 +275,8 @@ static void acm_ctrl_irq(struct urb *urb) | |||
| 302 | data = (unsigned char *)(dr + 1); | 275 | data = (unsigned char *)(dr + 1); |
| 303 | switch (dr->bNotificationType) { | 276 | switch (dr->bNotificationType) { |
| 304 | case USB_CDC_NOTIFY_NETWORK_CONNECTION: | 277 | case USB_CDC_NOTIFY_NETWORK_CONNECTION: |
| 305 | dbg("%s network", dr->wValue ? | 278 | dev_dbg(&acm->control->dev, "%s - network connection: %d\n", |
| 306 | "connected to" : "disconnected from"); | 279 | __func__, dr->wValue); |
| 307 | break; | 280 | break; |
| 308 | 281 | ||
| 309 | case USB_CDC_NOTIFY_SERIAL_STATE: | 282 | case USB_CDC_NOTIFY_SERIAL_STATE: |
| @@ -313,7 +286,8 @@ static void acm_ctrl_irq(struct urb *urb) | |||
| 313 | if (tty) { | 286 | if (tty) { |
| 314 | if (!acm->clocal && | 287 | if (!acm->clocal && |
| 315 | (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { | 288 | (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { |
| 316 | dbg("calling hangup"); | 289 | dev_dbg(&acm->control->dev, |
| 290 | "%s - calling hangup\n", __func__); | ||
| 317 | tty_hangup(tty); | 291 | tty_hangup(tty); |
| 318 | } | 292 | } |
| 319 | tty_kref_put(tty); | 293 | tty_kref_put(tty); |
| @@ -321,7 +295,10 @@ static void acm_ctrl_irq(struct urb *urb) | |||
| 321 | 295 | ||
| 322 | acm->ctrlin = newctrl; | 296 | acm->ctrlin = newctrl; |
| 323 | 297 | ||
| 324 | 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__, | ||
| 325 | acm->ctrlin & ACM_CTRL_DCD ? '+' : '-', | 302 | acm->ctrlin & ACM_CTRL_DCD ? '+' : '-', |
| 326 | acm->ctrlin & ACM_CTRL_DSR ? '+' : '-', | 303 | acm->ctrlin & ACM_CTRL_DSR ? '+' : '-', |
| 327 | acm->ctrlin & ACM_CTRL_BRK ? '+' : '-', | 304 | acm->ctrlin & ACM_CTRL_BRK ? '+' : '-', |
| @@ -332,7 +309,10 @@ static void acm_ctrl_irq(struct urb *urb) | |||
| 332 | break; | 309 | break; |
| 333 | 310 | ||
| 334 | default: | 311 | default: |
| 335 | 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__, | ||
| 336 | dr->bNotificationType, dr->wIndex, | 316 | dr->bNotificationType, dr->wIndex, |
| 337 | dr->wLength, data[0], data[1]); | 317 | dr->wLength, data[0], data[1]); |
| 338 | break; | 318 | break; |
| @@ -340,166 +320,96 @@ static void acm_ctrl_irq(struct urb *urb) | |||
| 340 | exit: | 320 | exit: |
| 341 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 321 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
| 342 | if (retval) | 322 | if (retval) |
| 343 | dev_err(&urb->dev->dev, "%s - usb_submit_urb failed with " | 323 | dev_err(&acm->control->dev, "%s - usb_submit_urb failed: %d\n", |
| 344 | "result %d", __func__, retval); | 324 | __func__, retval); |
| 345 | } | 325 | } |
| 346 | 326 | ||
| 347 | /* 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) |
| 348 | static void acm_read_bulk(struct urb *urb) | ||
| 349 | { | 328 | { |
| 350 | struct acm_rb *buf; | 329 | int res; |
| 351 | struct acm_ru *rcv = urb->context; | 330 | |
| 352 | struct acm *acm = rcv->instance; | 331 | if (!test_and_clear_bit(index, &acm->read_urbs_free)) |
| 353 | int status = urb->status; | 332 | return 0; |
| 354 | 333 | ||
| 355 | dbg("Entering acm_read_bulk with status %d", status); | 334 | dev_vdbg(&acm->data->dev, "%s - urb %d\n", __func__, index); |
| 356 | 335 | ||
| 357 | if (!ACM_READY(acm)) { | 336 | res = usb_submit_urb(acm->read_urbs[index], mem_flags); |
| 358 | dev_dbg(&acm->data->dev, "Aborting, acm not ready"); | 337 | if (res) { |
| 359 | return; | 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; | ||
| 360 | } | 345 | } |
| 361 | usb_mark_last_busy(acm->dev); | ||
| 362 | 346 | ||
| 363 | if (status) | 347 | return 0; |
| 364 | dev_dbg(&acm->data->dev, "bulk rx status %d\n", status); | 348 | } |
| 365 | 349 | ||
| 366 | buf = rcv->buffer; | 350 | static int acm_submit_read_urbs(struct acm *acm, gfp_t mem_flags) |
| 367 | buf->size = urb->actual_length; | 351 | { |
| 352 | int res; | ||
| 353 | int i; | ||
| 368 | 354 | ||
| 369 | if (likely(status == 0)) { | 355 | for (i = 0; i < acm->rx_buflimit; ++i) { |
| 370 | spin_lock(&acm->read_lock); | 356 | res = acm_submit_read_urb(acm, i, mem_flags); |
| 371 | acm->processing++; | 357 | if (res) |
| 372 | list_add_tail(&rcv->list, &acm->spare_read_urbs); | 358 | return res; |
| 373 | list_add_tail(&buf->list, &acm->filled_read_bufs); | ||
| 374 | spin_unlock(&acm->read_lock); | ||
| 375 | } else { | ||
| 376 | /* we drop the buffer due to an error */ | ||
| 377 | spin_lock(&acm->read_lock); | ||
| 378 | list_add_tail(&rcv->list, &acm->spare_read_urbs); | ||
| 379 | list_add(&buf->list, &acm->spare_read_bufs); | ||
| 380 | spin_unlock(&acm->read_lock); | ||
| 381 | /* nevertheless the tasklet must be kicked unconditionally | ||
| 382 | so the queue cannot dry up */ | ||
| 383 | } | 359 | } |
| 384 | if (likely(!acm->susp_count)) | 360 | |
| 385 | tasklet_schedule(&acm->urb_task); | 361 | return 0; |
| 386 | } | 362 | } |
| 387 | 363 | ||
| 388 | static void acm_rx_tasklet(unsigned long _acm) | 364 | static void acm_process_read_urb(struct acm *acm, struct urb *urb) |
| 389 | { | 365 | { |
| 390 | struct acm *acm = (void *)_acm; | ||
| 391 | struct acm_rb *buf; | ||
| 392 | struct tty_struct *tty; | 366 | struct tty_struct *tty; |
| 393 | struct acm_ru *rcv; | ||
| 394 | unsigned long flags; | ||
| 395 | unsigned char throttled; | ||
| 396 | 367 | ||
| 397 | dbg("Entering acm_rx_tasklet"); | 368 | if (!urb->actual_length) |
| 398 | |||
| 399 | if (!ACM_READY(acm)) { | ||
| 400 | dbg("acm_rx_tasklet: ACM not ready"); | ||
| 401 | return; | 369 | return; |
| 402 | } | ||
| 403 | |||
| 404 | spin_lock_irqsave(&acm->throttle_lock, flags); | ||
| 405 | throttled = acm->throttle; | ||
| 406 | spin_unlock_irqrestore(&acm->throttle_lock, flags); | ||
| 407 | if (throttled) { | ||
| 408 | dbg("acm_rx_tasklet: throttled"); | ||
| 409 | return; | ||
| 410 | } | ||
| 411 | 370 | ||
| 412 | tty = tty_port_tty_get(&acm->port); | 371 | tty = tty_port_tty_get(&acm->port); |
| 372 | if (!tty) | ||
| 373 | return; | ||
| 413 | 374 | ||
| 414 | next_buffer: | 375 | tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length); |
| 415 | spin_lock_irqsave(&acm->read_lock, flags); | 376 | tty_flip_buffer_push(tty); |
| 416 | if (list_empty(&acm->filled_read_bufs)) { | ||
| 417 | spin_unlock_irqrestore(&acm->read_lock, flags); | ||
| 418 | goto urbs; | ||
| 419 | } | ||
| 420 | buf = list_entry(acm->filled_read_bufs.next, | ||
| 421 | struct acm_rb, list); | ||
| 422 | list_del(&buf->list); | ||
| 423 | spin_unlock_irqrestore(&acm->read_lock, flags); | ||
| 424 | |||
| 425 | dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size); | ||
| 426 | |||
| 427 | if (tty) { | ||
| 428 | spin_lock_irqsave(&acm->throttle_lock, flags); | ||
| 429 | throttled = acm->throttle; | ||
| 430 | spin_unlock_irqrestore(&acm->throttle_lock, flags); | ||
| 431 | if (!throttled) { | ||
| 432 | tty_insert_flip_string(tty, buf->base, buf->size); | ||
| 433 | tty_flip_buffer_push(tty); | ||
| 434 | } else { | ||
| 435 | tty_kref_put(tty); | ||
| 436 | dbg("Throttling noticed"); | ||
| 437 | spin_lock_irqsave(&acm->read_lock, flags); | ||
| 438 | list_add(&buf->list, &acm->filled_read_bufs); | ||
| 439 | spin_unlock_irqrestore(&acm->read_lock, flags); | ||
| 440 | return; | ||
| 441 | } | ||
| 442 | } | ||
| 443 | |||
| 444 | spin_lock_irqsave(&acm->read_lock, flags); | ||
| 445 | list_add(&buf->list, &acm->spare_read_bufs); | ||
| 446 | spin_unlock_irqrestore(&acm->read_lock, flags); | ||
| 447 | goto next_buffer; | ||
| 448 | 377 | ||
| 449 | urbs: | ||
| 450 | tty_kref_put(tty); | 378 | tty_kref_put(tty); |
| 379 | } | ||
| 451 | 380 | ||
| 452 | while (!list_empty(&acm->spare_read_bufs)) { | 381 | static void acm_read_bulk_callback(struct urb *urb) |
| 453 | spin_lock_irqsave(&acm->read_lock, flags); | 382 | { |
| 454 | if (list_empty(&acm->spare_read_urbs)) { | 383 | struct acm_rb *rb = urb->context; |
| 455 | acm->processing = 0; | 384 | struct acm *acm = rb->instance; |
| 456 | spin_unlock_irqrestore(&acm->read_lock, flags); | 385 | unsigned long flags; |
| 457 | return; | ||
| 458 | } | ||
| 459 | rcv = list_entry(acm->spare_read_urbs.next, | ||
| 460 | struct acm_ru, list); | ||
| 461 | list_del(&rcv->list); | ||
| 462 | spin_unlock_irqrestore(&acm->read_lock, flags); | ||
| 463 | 386 | ||
| 464 | buf = list_entry(acm->spare_read_bufs.next, | 387 | dev_vdbg(&acm->data->dev, "%s - urb %d, len %d\n", __func__, |
| 465 | struct acm_rb, list); | 388 | rb->index, urb->actual_length); |
| 466 | list_del(&buf->list); | 389 | set_bit(rb->index, &acm->read_urbs_free); |
| 467 | 390 | ||
| 468 | 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); | ||
| 469 | 396 | ||
| 470 | if (acm->is_int_ep) | 397 | if (urb->status) { |
| 471 | usb_fill_int_urb(rcv->urb, acm->dev, | 398 | dev_dbg(&acm->data->dev, "%s - non-zero urb status: %d\n", |
| 472 | acm->rx_endpoint, | 399 | __func__, urb->status); |
| 473 | buf->base, | 400 | return; |
| 474 | acm->readsize, | ||
| 475 | acm_read_bulk, rcv, acm->bInterval); | ||
| 476 | else | ||
| 477 | usb_fill_bulk_urb(rcv->urb, acm->dev, | ||
| 478 | acm->rx_endpoint, | ||
| 479 | buf->base, | ||
| 480 | acm->readsize, | ||
| 481 | acm_read_bulk, rcv); | ||
| 482 | rcv->urb->transfer_dma = buf->dma; | ||
| 483 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
| 484 | |||
| 485 | /* This shouldn't kill the driver as unsuccessful URBs are | ||
| 486 | returned to the free-urbs-pool and resubmited ASAP */ | ||
| 487 | spin_lock_irqsave(&acm->read_lock, flags); | ||
| 488 | if (acm->susp_count || | ||
| 489 | usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) { | ||
| 490 | list_add(&buf->list, &acm->spare_read_bufs); | ||
| 491 | list_add(&rcv->list, &acm->spare_read_urbs); | ||
| 492 | acm->processing = 0; | ||
| 493 | spin_unlock_irqrestore(&acm->read_lock, flags); | ||
| 494 | return; | ||
| 495 | } else { | ||
| 496 | spin_unlock_irqrestore(&acm->read_lock, flags); | ||
| 497 | dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p", rcv->urb, rcv, buf); | ||
| 498 | } | ||
| 499 | } | 401 | } |
| 402 | acm_process_read_urb(acm, urb); | ||
| 403 | |||
| 404 | /* throttle device if requested by tty */ | ||
| 500 | spin_lock_irqsave(&acm->read_lock, flags); | 405 | spin_lock_irqsave(&acm->read_lock, flags); |
| 501 | acm->processing = 0; | 406 | acm->throttled = acm->throttle_req; |
| 502 | 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 | } | ||
| 503 | } | 413 | } |
| 504 | 414 | ||
| 505 | /* data interface wrote those outgoing bytes */ | 415 | /* data interface wrote those outgoing bytes */ |
| @@ -509,9 +419,9 @@ static void acm_write_bulk(struct urb *urb) | |||
| 509 | struct acm *acm = wb->instance; | 419 | struct acm *acm = wb->instance; |
| 510 | unsigned long flags; | 420 | unsigned long flags; |
| 511 | 421 | ||
| 512 | if (verbose || urb->status | 422 | if (urb->status || (urb->actual_length != urb->transfer_buffer_length)) |
| 513 | || (urb->actual_length != urb->transfer_buffer_length)) | 423 | dev_vdbg(&acm->data->dev, "%s - len %d/%d, status %d\n", |
| 514 | dev_dbg(&acm->data->dev, "tx %d/%d bytes -- > %d\n", | 424 | __func__, |
| 515 | urb->actual_length, | 425 | urb->actual_length, |
| 516 | urb->transfer_buffer_length, | 426 | urb->transfer_buffer_length, |
| 517 | urb->status); | 427 | urb->status); |
| @@ -521,8 +431,6 @@ static void acm_write_bulk(struct urb *urb) | |||
| 521 | spin_unlock_irqrestore(&acm->write_lock, flags); | 431 | spin_unlock_irqrestore(&acm->write_lock, flags); |
| 522 | if (ACM_READY(acm)) | 432 | if (ACM_READY(acm)) |
| 523 | schedule_work(&acm->work); | 433 | schedule_work(&acm->work); |
| 524 | else | ||
| 525 | wake_up_interruptible(&acm->drain_wait); | ||
| 526 | } | 434 | } |
| 527 | 435 | ||
| 528 | static void acm_softint(struct work_struct *work) | 436 | static void acm_softint(struct work_struct *work) |
| @@ -530,7 +438,8 @@ static void acm_softint(struct work_struct *work) | |||
| 530 | struct acm *acm = container_of(work, struct acm, work); | 438 | struct acm *acm = container_of(work, struct acm, work); |
| 531 | struct tty_struct *tty; | 439 | struct tty_struct *tty; |
| 532 | 440 | ||
| 533 | dev_vdbg(&acm->data->dev, "tx work\n"); | 441 | dev_vdbg(&acm->data->dev, "%s\n", __func__); |
| 442 | |||
| 534 | if (!ACM_READY(acm)) | 443 | if (!ACM_READY(acm)) |
| 535 | return; | 444 | return; |
| 536 | tty = tty_port_tty_get(&acm->port); | 445 | tty = tty_port_tty_get(&acm->port); |
| @@ -548,8 +457,6 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 548 | { | 457 | { |
| 549 | struct acm *acm; | 458 | struct acm *acm; |
| 550 | int rv = -ENODEV; | 459 | int rv = -ENODEV; |
| 551 | int i; | ||
| 552 | dbg("Entering acm_tty_open."); | ||
| 553 | 460 | ||
| 554 | mutex_lock(&open_mutex); | 461 | mutex_lock(&open_mutex); |
| 555 | 462 | ||
| @@ -559,6 +466,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 559 | else | 466 | else |
| 560 | rv = 0; | 467 | rv = 0; |
| 561 | 468 | ||
| 469 | dev_dbg(&acm->control->dev, "%s\n", __func__); | ||
| 470 | |||
| 562 | set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); | 471 | set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); |
| 563 | 472 | ||
| 564 | tty->driver_data = acm; | 473 | tty->driver_data = acm; |
| @@ -578,38 +487,28 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 578 | 487 | ||
| 579 | acm->ctrlurb->dev = acm->dev; | 488 | acm->ctrlurb->dev = acm->dev; |
| 580 | if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { | 489 | if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { |
| 581 | dbg("usb_submit_urb(ctrl irq) failed"); | 490 | dev_err(&acm->control->dev, |
| 491 | "%s - usb_submit_urb(ctrl irq) failed\n", __func__); | ||
| 582 | goto bail_out; | 492 | goto bail_out; |
| 583 | } | 493 | } |
| 584 | 494 | ||
| 585 | 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) && |
| 586 | (acm->ctrl_caps & USB_CDC_CAP_LINE)) | 496 | (acm->ctrl_caps & USB_CDC_CAP_LINE)) |
| 587 | goto full_bailout; | 497 | goto bail_out; |
| 588 | 498 | ||
| 589 | usb_autopm_put_interface(acm->control); | 499 | usb_autopm_put_interface(acm->control); |
| 590 | 500 | ||
| 591 | INIT_LIST_HEAD(&acm->spare_read_urbs); | 501 | if (acm_submit_read_urbs(acm, GFP_KERNEL)) |
| 592 | INIT_LIST_HEAD(&acm->spare_read_bufs); | 502 | goto bail_out; |
| 593 | INIT_LIST_HEAD(&acm->filled_read_bufs); | ||
| 594 | |||
| 595 | for (i = 0; i < acm->rx_buflimit; i++) | ||
| 596 | list_add(&(acm->ru[i].list), &acm->spare_read_urbs); | ||
| 597 | for (i = 0; i < acm->rx_buflimit; i++) | ||
| 598 | list_add(&(acm->rb[i].list), &acm->spare_read_bufs); | ||
| 599 | |||
| 600 | acm->throttle = 0; | ||
| 601 | 503 | ||
| 602 | set_bit(ASYNCB_INITIALIZED, &acm->port.flags); | 504 | set_bit(ASYNCB_INITIALIZED, &acm->port.flags); |
| 603 | rv = tty_port_block_til_ready(&acm->port, tty, filp); | 505 | rv = tty_port_block_til_ready(&acm->port, tty, filp); |
| 604 | tasklet_schedule(&acm->urb_task); | ||
| 605 | 506 | ||
| 606 | mutex_unlock(&acm->mutex); | 507 | mutex_unlock(&acm->mutex); |
| 607 | out: | 508 | out: |
| 608 | mutex_unlock(&open_mutex); | 509 | mutex_unlock(&open_mutex); |
| 609 | return rv; | 510 | return rv; |
| 610 | 511 | ||
| 611 | full_bailout: | ||
| 612 | usb_kill_urb(acm->ctrlurb); | ||
| 613 | bail_out: | 512 | bail_out: |
| 614 | acm->port.count--; | 513 | acm->port.count--; |
| 615 | mutex_unlock(&acm->mutex); | 514 | mutex_unlock(&acm->mutex); |
| @@ -622,26 +521,24 @@ early_bail: | |||
| 622 | 521 | ||
| 623 | static void acm_tty_unregister(struct acm *acm) | 522 | static void acm_tty_unregister(struct acm *acm) |
| 624 | { | 523 | { |
| 625 | int i, nr; | 524 | int i; |
| 626 | 525 | ||
| 627 | nr = acm->rx_buflimit; | ||
| 628 | tty_unregister_device(acm_tty_driver, acm->minor); | 526 | tty_unregister_device(acm_tty_driver, acm->minor); |
| 629 | usb_put_intf(acm->control); | 527 | usb_put_intf(acm->control); |
| 630 | acm_table[acm->minor] = NULL; | 528 | acm_table[acm->minor] = NULL; |
| 631 | usb_free_urb(acm->ctrlurb); | 529 | usb_free_urb(acm->ctrlurb); |
| 632 | for (i = 0; i < ACM_NW; i++) | 530 | for (i = 0; i < ACM_NW; i++) |
| 633 | usb_free_urb(acm->wb[i].urb); | 531 | usb_free_urb(acm->wb[i].urb); |
| 634 | for (i = 0; i < nr; i++) | 532 | for (i = 0; i < acm->rx_buflimit; i++) |
| 635 | usb_free_urb(acm->ru[i].urb); | 533 | usb_free_urb(acm->read_urbs[i]); |
| 636 | kfree(acm->country_codes); | 534 | kfree(acm->country_codes); |
| 637 | kfree(acm); | 535 | kfree(acm); |
| 638 | } | 536 | } |
| 639 | 537 | ||
| 640 | static int acm_tty_chars_in_buffer(struct tty_struct *tty); | ||
| 641 | |||
| 642 | static void acm_port_down(struct acm *acm) | 538 | static void acm_port_down(struct acm *acm) |
| 643 | { | 539 | { |
| 644 | int i, nr = acm->rx_buflimit; | 540 | int i; |
| 541 | |||
| 645 | mutex_lock(&open_mutex); | 542 | mutex_lock(&open_mutex); |
| 646 | if (acm->dev) { | 543 | if (acm->dev) { |
| 647 | usb_autopm_get_interface(acm->control); | 544 | usb_autopm_get_interface(acm->control); |
| @@ -649,10 +546,8 @@ static void acm_port_down(struct acm *acm) | |||
| 649 | usb_kill_urb(acm->ctrlurb); | 546 | usb_kill_urb(acm->ctrlurb); |
| 650 | for (i = 0; i < ACM_NW; i++) | 547 | for (i = 0; i < ACM_NW; i++) |
| 651 | usb_kill_urb(acm->wb[i].urb); | 548 | usb_kill_urb(acm->wb[i].urb); |
| 652 | tasklet_disable(&acm->urb_task); | 549 | for (i = 0; i < acm->rx_buflimit; i++) |
| 653 | for (i = 0; i < nr; i++) | 550 | usb_kill_urb(acm->read_urbs[i]); |
| 654 | usb_kill_urb(acm->ru[i].urb); | ||
| 655 | tasklet_enable(&acm->urb_task); | ||
| 656 | acm->control->needs_remote_wakeup = 0; | 551 | acm->control->needs_remote_wakeup = 0; |
| 657 | usb_autopm_put_interface(acm->control); | 552 | usb_autopm_put_interface(acm->control); |
| 658 | } | 553 | } |
| @@ -698,13 +593,13 @@ static int acm_tty_write(struct tty_struct *tty, | |||
| 698 | int wbn; | 593 | int wbn; |
| 699 | struct acm_wb *wb; | 594 | struct acm_wb *wb; |
| 700 | 595 | ||
| 701 | dbg("Entering acm_tty_write to write %d bytes,", count); | ||
| 702 | |||
| 703 | if (!ACM_READY(acm)) | 596 | if (!ACM_READY(acm)) |
| 704 | return -EINVAL; | 597 | return -EINVAL; |
| 705 | if (!count) | 598 | if (!count) |
| 706 | return 0; | 599 | return 0; |
| 707 | 600 | ||
| 601 | dev_vdbg(&acm->data->dev, "%s - count %d\n", __func__, count); | ||
| 602 | |||
| 708 | spin_lock_irqsave(&acm->write_lock, flags); | 603 | spin_lock_irqsave(&acm->write_lock, flags); |
| 709 | wbn = acm_wb_alloc(acm); | 604 | wbn = acm_wb_alloc(acm); |
| 710 | if (wbn < 0) { | 605 | if (wbn < 0) { |
| @@ -714,7 +609,7 @@ static int acm_tty_write(struct tty_struct *tty, | |||
| 714 | wb = &acm->wb[wbn]; | 609 | wb = &acm->wb[wbn]; |
| 715 | 610 | ||
| 716 | count = (count > acm->writesize) ? acm->writesize : count; | 611 | count = (count > acm->writesize) ? acm->writesize : count; |
| 717 | dbg("Get %d bytes...", count); | 612 | dev_vdbg(&acm->data->dev, "%s - write %d\n", __func__, count); |
| 718 | memcpy(wb->buf, buf, count); | 613 | memcpy(wb->buf, buf, count); |
| 719 | wb->len = count; | 614 | wb->len = count; |
| 720 | spin_unlock_irqrestore(&acm->write_lock, flags); | 615 | spin_unlock_irqrestore(&acm->write_lock, flags); |
| @@ -751,22 +646,31 @@ static int acm_tty_chars_in_buffer(struct tty_struct *tty) | |||
| 751 | static void acm_tty_throttle(struct tty_struct *tty) | 646 | static void acm_tty_throttle(struct tty_struct *tty) |
| 752 | { | 647 | { |
| 753 | struct acm *acm = tty->driver_data; | 648 | struct acm *acm = tty->driver_data; |
| 649 | |||
| 754 | if (!ACM_READY(acm)) | 650 | if (!ACM_READY(acm)) |
| 755 | return; | 651 | return; |
| 756 | spin_lock_bh(&acm->throttle_lock); | 652 | |
| 757 | acm->throttle = 1; | 653 | spin_lock_irq(&acm->read_lock); |
| 758 | spin_unlock_bh(&acm->throttle_lock); | 654 | acm->throttle_req = 1; |
| 655 | spin_unlock_irq(&acm->read_lock); | ||
| 759 | } | 656 | } |
| 760 | 657 | ||
| 761 | static void acm_tty_unthrottle(struct tty_struct *tty) | 658 | static void acm_tty_unthrottle(struct tty_struct *tty) |
| 762 | { | 659 | { |
| 763 | struct acm *acm = tty->driver_data; | 660 | struct acm *acm = tty->driver_data; |
| 661 | unsigned int was_throttled; | ||
| 662 | |||
| 764 | if (!ACM_READY(acm)) | 663 | if (!ACM_READY(acm)) |
| 765 | return; | 664 | return; |
| 766 | spin_lock_bh(&acm->throttle_lock); | 665 | |
| 767 | acm->throttle = 0; | 666 | spin_lock_irq(&acm->read_lock); |
| 768 | spin_unlock_bh(&acm->throttle_lock); | 667 | was_throttled = acm->throttled; |
| 769 | 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); | ||
| 770 | } | 674 | } |
| 771 | 675 | ||
| 772 | 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) |
| @@ -777,7 +681,8 @@ static int acm_tty_break_ctl(struct tty_struct *tty, int state) | |||
| 777 | return -EINVAL; | 681 | return -EINVAL; |
| 778 | retval = acm_send_break(acm, state ? 0xffff : 0); | 682 | retval = acm_send_break(acm, state ? 0xffff : 0); |
| 779 | if (retval < 0) | 683 | if (retval < 0) |
| 780 | dbg("send break failed"); | 684 | dev_dbg(&acm->control->dev, "%s - send break failed\n", |
| 685 | __func__); | ||
| 781 | return retval; | 686 | return retval; |
| 782 | } | 687 | } |
| 783 | 688 | ||
| @@ -872,7 +777,9 @@ static void acm_tty_set_termios(struct tty_struct *tty, | |||
| 872 | 777 | ||
| 873 | if (memcmp(&acm->line, &newline, sizeof newline)) { | 778 | if (memcmp(&acm->line, &newline, sizeof newline)) { |
| 874 | memcpy(&acm->line, &newline, sizeof newline); | 779 | memcpy(&acm->line, &newline, sizeof newline); |
| 875 | 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), | ||
| 876 | newline.bCharFormat, newline.bParityType, | 783 | newline.bCharFormat, newline.bParityType, |
| 877 | newline.bDataBits); | 784 | newline.bDataBits); |
| 878 | acm_set_line(acm, &acm->line); | 785 | acm_set_line(acm, &acm->line); |
| @@ -897,11 +804,11 @@ static void acm_write_buffers_free(struct acm *acm) | |||
| 897 | static void acm_read_buffers_free(struct acm *acm) | 804 | static void acm_read_buffers_free(struct acm *acm) |
| 898 | { | 805 | { |
| 899 | struct usb_device *usb_dev = interface_to_usbdev(acm->control); | 806 | struct usb_device *usb_dev = interface_to_usbdev(acm->control); |
| 900 | int i, n = acm->rx_buflimit; | 807 | int i; |
| 901 | 808 | ||
| 902 | for (i = 0; i < n; i++) | 809 | for (i = 0; i < acm->rx_buflimit; i++) |
| 903 | usb_free_coherent(usb_dev, acm->readsize, | 810 | usb_free_coherent(usb_dev, acm->readsize, |
| 904 | acm->rb[i].base, acm->rb[i].dma); | 811 | acm->read_buffers[i].base, acm->read_buffers[i].dma); |
| 905 | } | 812 | } |
| 906 | 813 | ||
| 907 | /* Little helper: write buffers allocate */ | 814 | /* Little helper: write buffers allocate */ |
| @@ -946,7 +853,7 @@ static int acm_probe(struct usb_interface *intf, | |||
| 946 | u8 ac_management_function = 0; | 853 | u8 ac_management_function = 0; |
| 947 | u8 call_management_function = 0; | 854 | u8 call_management_function = 0; |
| 948 | int call_interface_num = -1; | 855 | int call_interface_num = -1; |
| 949 | int data_interface_num; | 856 | int data_interface_num = -1; |
| 950 | unsigned long quirks; | 857 | unsigned long quirks; |
| 951 | int num_rx_buf; | 858 | int num_rx_buf; |
| 952 | int i; | 859 | int i; |
| @@ -1030,7 +937,11 @@ next_desc: | |||
| 1030 | if (!union_header) { | 937 | if (!union_header) { |
| 1031 | if (call_interface_num > 0) { | 938 | if (call_interface_num > 0) { |
| 1032 | 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"); |
| 1033 | 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)); | ||
| 1034 | control_interface = intf; | 945 | control_interface = intf; |
| 1035 | } else { | 946 | } else { |
| 1036 | if (intf->cur_altsetting->desc.bNumEndpoints != 3) { | 947 | if (intf->cur_altsetting->desc.bNumEndpoints != 3) { |
| @@ -1133,7 +1044,7 @@ skip_normal_probe: | |||
| 1133 | epwrite = t; | 1044 | epwrite = t; |
| 1134 | } | 1045 | } |
| 1135 | made_compressed_probe: | 1046 | made_compressed_probe: |
| 1136 | dbg("interfaces are valid"); | 1047 | dev_dbg(&intf->dev, "interfaces are valid\n"); |
| 1137 | for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); | 1048 | for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); |
| 1138 | 1049 | ||
| 1139 | if (minor == ACM_TTY_MINORS) { | 1050 | if (minor == ACM_TTY_MINORS) { |
| @@ -1143,7 +1054,7 @@ made_compressed_probe: | |||
| 1143 | 1054 | ||
| 1144 | acm = kzalloc(sizeof(struct acm), GFP_KERNEL); | 1055 | acm = kzalloc(sizeof(struct acm), GFP_KERNEL); |
| 1145 | if (acm == NULL) { | 1056 | if (acm == NULL) { |
| 1146 | dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n"); | 1057 | dev_err(&intf->dev, "out of memory (acm kzalloc)\n"); |
| 1147 | goto alloc_fail; | 1058 | goto alloc_fail; |
| 1148 | } | 1059 | } |
| 1149 | 1060 | ||
| @@ -1162,11 +1073,7 @@ made_compressed_probe: | |||
| 1162 | acm->ctrlsize = ctrlsize; | 1073 | acm->ctrlsize = ctrlsize; |
| 1163 | acm->readsize = readsize; | 1074 | acm->readsize = readsize; |
| 1164 | acm->rx_buflimit = num_rx_buf; | 1075 | acm->rx_buflimit = num_rx_buf; |
| 1165 | acm->urb_task.func = acm_rx_tasklet; | ||
| 1166 | acm->urb_task.data = (unsigned long) acm; | ||
| 1167 | INIT_WORK(&acm->work, acm_softint); | 1076 | INIT_WORK(&acm->work, acm_softint); |
| 1168 | init_waitqueue_head(&acm->drain_wait); | ||
| 1169 | spin_lock_init(&acm->throttle_lock); | ||
| 1170 | spin_lock_init(&acm->write_lock); | 1077 | spin_lock_init(&acm->write_lock); |
| 1171 | spin_lock_init(&acm->read_lock); | 1078 | spin_lock_init(&acm->read_lock); |
| 1172 | mutex_init(&acm->mutex); | 1079 | mutex_init(&acm->mutex); |
| @@ -1179,53 +1086,69 @@ made_compressed_probe: | |||
| 1179 | 1086 | ||
| 1180 | 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); |
| 1181 | if (!buf) { | 1088 | if (!buf) { |
| 1182 | dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n"); | 1089 | dev_err(&intf->dev, "out of memory (ctrl buffer alloc)\n"); |
| 1183 | goto alloc_fail2; | 1090 | goto alloc_fail2; |
| 1184 | } | 1091 | } |
| 1185 | acm->ctrl_buffer = buf; | 1092 | acm->ctrl_buffer = buf; |
| 1186 | 1093 | ||
| 1187 | if (acm_write_buffers_alloc(acm) < 0) { | 1094 | if (acm_write_buffers_alloc(acm) < 0) { |
| 1188 | dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); | 1095 | dev_err(&intf->dev, "out of memory (write buffer alloc)\n"); |
| 1189 | goto alloc_fail4; | 1096 | goto alloc_fail4; |
| 1190 | } | 1097 | } |
| 1191 | 1098 | ||
| 1192 | acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); | 1099 | acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); |
| 1193 | if (!acm->ctrlurb) { | 1100 | if (!acm->ctrlurb) { |
| 1194 | dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); | 1101 | dev_err(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); |
| 1195 | goto alloc_fail5; | 1102 | goto alloc_fail5; |
| 1196 | } | 1103 | } |
| 1197 | for (i = 0; i < num_rx_buf; i++) { | 1104 | for (i = 0; i < num_rx_buf; i++) { |
| 1198 | struct acm_ru *rcv = &(acm->ru[i]); | 1105 | struct acm_rb *rb = &(acm->read_buffers[i]); |
| 1106 | struct urb *urb; | ||
| 1199 | 1107 | ||
| 1200 | rcv->urb = usb_alloc_urb(0, GFP_KERNEL); | 1108 | rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, |
| 1201 | if (rcv->urb == NULL) { | 1109 | &rb->dma); |
| 1202 | dev_dbg(&intf->dev, | 1110 | if (!rb->base) { |
| 1203 | "out of memory (read urbs usb_alloc_urb)\n"); | 1111 | dev_err(&intf->dev, "out of memory " |
| 1112 | "(read bufs usb_alloc_coherent)\n"); | ||
| 1204 | goto alloc_fail6; | 1113 | goto alloc_fail6; |
| 1205 | } | 1114 | } |
| 1115 | rb->index = i; | ||
| 1116 | rb->instance = acm; | ||
| 1206 | 1117 | ||
| 1207 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1118 | urb = usb_alloc_urb(0, GFP_KERNEL); |
| 1208 | rcv->instance = acm; | 1119 | if (!urb) { |
| 1209 | } | 1120 | dev_err(&intf->dev, |
| 1210 | for (i = 0; i < num_rx_buf; i++) { | 1121 | "out of memory (read urbs usb_alloc_urb)\n"); |
| 1211 | struct acm_rb *rb = &(acm->rb[i]); | 1122 | goto alloc_fail6; |
| 1212 | 1123 | } | |
| 1213 | rb->base = usb_alloc_coherent(acm->dev, readsize, | 1124 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
| 1214 | GFP_KERNEL, &rb->dma); | 1125 | urb->transfer_dma = rb->dma; |
| 1215 | if (!rb->base) { | 1126 | if (acm->is_int_ep) { |
| 1216 | dev_dbg(&intf->dev, | 1127 | usb_fill_int_urb(urb, acm->dev, |
| 1217 | "out of memory (read bufs usb_alloc_coherent)\n"); | 1128 | acm->rx_endpoint, |
| 1218 | goto alloc_fail7; | 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); | ||
| 1219 | } | 1139 | } |
| 1140 | |||
| 1141 | acm->read_urbs[i] = urb; | ||
| 1142 | __set_bit(i, &acm->read_urbs_free); | ||
| 1220 | } | 1143 | } |
| 1221 | for (i = 0; i < ACM_NW; i++) { | 1144 | for (i = 0; i < ACM_NW; i++) { |
| 1222 | struct acm_wb *snd = &(acm->wb[i]); | 1145 | struct acm_wb *snd = &(acm->wb[i]); |
| 1223 | 1146 | ||
| 1224 | snd->urb = usb_alloc_urb(0, GFP_KERNEL); | 1147 | snd->urb = usb_alloc_urb(0, GFP_KERNEL); |
| 1225 | if (snd->urb == NULL) { | 1148 | if (snd->urb == NULL) { |
| 1226 | dev_dbg(&intf->dev, | 1149 | dev_err(&intf->dev, |
| 1227 | "out of memory (write urbs usb_alloc_urb)"); | 1150 | "out of memory (write urbs usb_alloc_urb)\n"); |
| 1228 | goto alloc_fail8; | 1151 | goto alloc_fail7; |
| 1229 | } | 1152 | } |
| 1230 | 1153 | ||
| 1231 | if (usb_endpoint_xfer_int(epwrite)) | 1154 | if (usb_endpoint_xfer_int(epwrite)) |
| @@ -1244,7 +1167,7 @@ made_compressed_probe: | |||
| 1244 | 1167 | ||
| 1245 | i = device_create_file(&intf->dev, &dev_attr_bmCapabilities); | 1168 | i = device_create_file(&intf->dev, &dev_attr_bmCapabilities); |
| 1246 | if (i < 0) | 1169 | if (i < 0) |
| 1247 | goto alloc_fail8; | 1170 | goto alloc_fail7; |
| 1248 | 1171 | ||
| 1249 | if (cfd) { /* export the country data */ | 1172 | if (cfd) { /* export the country data */ |
| 1250 | acm->country_codes = kmalloc(cfd->bLength - 4, GFP_KERNEL); | 1173 | acm->country_codes = kmalloc(cfd->bLength - 4, GFP_KERNEL); |
| @@ -1296,14 +1219,13 @@ skip_countries: | |||
| 1296 | acm_table[minor] = acm; | 1219 | acm_table[minor] = acm; |
| 1297 | 1220 | ||
| 1298 | return 0; | 1221 | return 0; |
| 1299 | alloc_fail8: | 1222 | alloc_fail7: |
| 1300 | for (i = 0; i < ACM_NW; i++) | 1223 | for (i = 0; i < ACM_NW; i++) |
| 1301 | usb_free_urb(acm->wb[i].urb); | 1224 | usb_free_urb(acm->wb[i].urb); |
| 1302 | alloc_fail7: | ||
| 1303 | acm_read_buffers_free(acm); | ||
| 1304 | alloc_fail6: | 1225 | alloc_fail6: |
| 1305 | for (i = 0; i < num_rx_buf; i++) | 1226 | for (i = 0; i < num_rx_buf; i++) |
| 1306 | usb_free_urb(acm->ru[i].urb); | 1227 | usb_free_urb(acm->read_urbs[i]); |
| 1228 | acm_read_buffers_free(acm); | ||
| 1307 | usb_free_urb(acm->ctrlurb); | 1229 | usb_free_urb(acm->ctrlurb); |
| 1308 | alloc_fail5: | 1230 | alloc_fail5: |
| 1309 | acm_write_buffers_free(acm); | 1231 | acm_write_buffers_free(acm); |
| @@ -1318,17 +1240,14 @@ alloc_fail: | |||
| 1318 | static void stop_data_traffic(struct acm *acm) | 1240 | static void stop_data_traffic(struct acm *acm) |
| 1319 | { | 1241 | { |
| 1320 | int i; | 1242 | int i; |
| 1321 | dbg("Entering stop_data_traffic"); | ||
| 1322 | 1243 | ||
| 1323 | tasklet_disable(&acm->urb_task); | 1244 | dev_dbg(&acm->control->dev, "%s\n", __func__); |
| 1324 | 1245 | ||
| 1325 | usb_kill_urb(acm->ctrlurb); | 1246 | usb_kill_urb(acm->ctrlurb); |
| 1326 | for (i = 0; i < ACM_NW; i++) | 1247 | for (i = 0; i < ACM_NW; i++) |
| 1327 | usb_kill_urb(acm->wb[i].urb); | 1248 | usb_kill_urb(acm->wb[i].urb); |
| 1328 | for (i = 0; i < acm->rx_buflimit; i++) | 1249 | for (i = 0; i < acm->rx_buflimit; i++) |
| 1329 | usb_kill_urb(acm->ru[i].urb); | 1250 | usb_kill_urb(acm->read_urbs[i]); |
| 1330 | |||
| 1331 | tasklet_enable(&acm->urb_task); | ||
| 1332 | 1251 | ||
| 1333 | cancel_work_sync(&acm->work); | 1252 | cancel_work_sync(&acm->work); |
| 1334 | } | 1253 | } |
| @@ -1389,11 +1308,9 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message) | |||
| 1389 | if (message.event & PM_EVENT_AUTO) { | 1308 | if (message.event & PM_EVENT_AUTO) { |
| 1390 | int b; | 1309 | int b; |
| 1391 | 1310 | ||
| 1392 | spin_lock_irq(&acm->read_lock); | 1311 | spin_lock_irq(&acm->write_lock); |
| 1393 | spin_lock(&acm->write_lock); | 1312 | b = acm->transmitting; |
| 1394 | b = acm->processing + acm->transmitting; | 1313 | spin_unlock_irq(&acm->write_lock); |
| 1395 | spin_unlock(&acm->write_lock); | ||
| 1396 | spin_unlock_irq(&acm->read_lock); | ||
| 1397 | if (b) | 1314 | if (b) |
| 1398 | return -EBUSY; | 1315 | return -EBUSY; |
| 1399 | } | 1316 | } |
| @@ -1455,7 +1372,7 @@ static int acm_resume(struct usb_interface *intf) | |||
| 1455 | if (rv < 0) | 1372 | if (rv < 0) |
| 1456 | goto err_out; | 1373 | goto err_out; |
| 1457 | 1374 | ||
| 1458 | tasklet_schedule(&acm->urb_task); | 1375 | rv = acm_submit_read_urbs(acm, GFP_NOIO); |
| 1459 | } | 1376 | } |
| 1460 | 1377 | ||
| 1461 | err_out: | 1378 | err_out: |
| @@ -1622,6 +1539,11 @@ static const struct usb_device_id acm_ids[] = { | |||
| 1622 | .driver_info = NOT_A_MODEM, | 1539 | .driver_info = NOT_A_MODEM, |
| 1623 | }, | 1540 | }, |
| 1624 | 1541 | ||
| 1542 | /* Support for Droids MuIn LCD */ | ||
| 1543 | { USB_DEVICE(0x04d8, 0x000b), | ||
| 1544 | .driver_info = NO_DATA_INTERFACE, | ||
| 1545 | }, | ||
| 1546 | |||
| 1625 | /* control interfaces without any protocol set */ | 1547 | /* control interfaces without any protocol set */ |
| 1626 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, | 1548 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, |
| 1627 | USB_CDC_PROTO_NONE) }, | 1549 | USB_CDC_PROTO_NONE) }, |
| @@ -1716,8 +1638,7 @@ static int __init acm_init(void) | |||
| 1716 | return retval; | 1638 | return retval; |
| 1717 | } | 1639 | } |
| 1718 | 1640 | ||
| 1719 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" | 1641 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); |
| 1720 | DRIVER_DESC "\n"); | ||
| 1721 | 1642 | ||
| 1722 | return 0; | 1643 | return 0; |
| 1723 | } | 1644 | } |
