Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] USB: fix acm trouble with terminals

This patch fixes lost LF when ACM device is used with getty/login/bash,
in case of a modem which takes calls.

Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
Signed-off-by: Oliver Neukum <oliver@neukum.name>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Oliver Neukum and committed by
Greg Kroah-Hartman
884b600f d5926ae7

+199 -39
+177 -36
drivers/usb/class/cdc-acm.c
··· 106 106 acm_ctrl_msg(acm, USB_CDC_REQ_SEND_BREAK, ms, NULL, 0) 107 107 108 108 /* 109 + * Write buffer management. 110 + * All of these assume proper locks taken by the caller. 111 + */ 112 + 113 + static int acm_wb_alloc(struct acm *acm) 114 + { 115 + int i, wbn; 116 + struct acm_wb *wb; 117 + 118 + wbn = acm->write_current; 119 + i = 0; 120 + for (;;) { 121 + wb = &acm->wb[wbn]; 122 + if (!wb->use) { 123 + wb->use = 1; 124 + return wbn; 125 + } 126 + wbn = (wbn + 1) % ACM_NWB; 127 + if (++i >= ACM_NWB) 128 + return -1; 129 + } 130 + } 131 + 132 + static void acm_wb_free(struct acm *acm, int wbn) 133 + { 134 + acm->wb[wbn].use = 0; 135 + } 136 + 137 + static int acm_wb_is_avail(struct acm *acm) 138 + { 139 + int i, n; 140 + 141 + n = 0; 142 + for (i = 0; i < ACM_NWB; i++) { 143 + if (!acm->wb[i].use) 144 + n++; 145 + } 146 + return n; 147 + } 148 + 149 + static inline int acm_wb_is_used(struct acm *acm, int wbn) 150 + { 151 + return acm->wb[wbn].use; 152 + } 153 + 154 + /* 155 + * Finish write. 156 + */ 157 + static void acm_write_done(struct acm *acm) 158 + { 159 + unsigned long flags; 160 + int wbn; 161 + 162 + spin_lock_irqsave(&acm->write_lock, flags); 163 + acm->write_ready = 1; 164 + wbn = acm->write_current; 165 + acm_wb_free(acm, wbn); 166 + acm->write_current = (wbn + 1) % ACM_NWB; 167 + spin_unlock_irqrestore(&acm->write_lock, flags); 168 + } 169 + 170 + /* 171 + * Poke write. 172 + */ 173 + static int acm_write_start(struct acm *acm) 174 + { 175 + unsigned long flags; 176 + int wbn; 177 + struct acm_wb *wb; 178 + int rc; 179 + 180 + spin_lock_irqsave(&acm->write_lock, flags); 181 + if (!acm->dev) { 182 + spin_unlock_irqrestore(&acm->write_lock, flags); 183 + return -ENODEV; 184 + } 185 + 186 + if (!acm->write_ready) { 187 + spin_unlock_irqrestore(&acm->write_lock, flags); 188 + return 0; /* A white lie */ 189 + } 190 + 191 + wbn = acm->write_current; 192 + if (!acm_wb_is_used(acm, wbn)) { 193 + spin_unlock_irqrestore(&acm->write_lock, flags); 194 + return 0; 195 + } 196 + wb = &acm->wb[wbn]; 197 + 198 + acm->write_ready = 0; 199 + spin_unlock_irqrestore(&acm->write_lock, flags); 200 + 201 + acm->writeurb->transfer_buffer = wb->buf; 202 + acm->writeurb->transfer_dma = wb->dmah; 203 + acm->writeurb->transfer_buffer_length = wb->len; 204 + acm->writeurb->dev = acm->dev; 205 + 206 + if ((rc = usb_submit_urb(acm->writeurb, GFP_ATOMIC)) < 0) { 207 + dbg("usb_submit_urb(write bulk) failed: %d", rc); 208 + acm_write_done(acm); 209 + } 210 + return rc; 211 + } 212 + 213 + /* 109 214 * Interrupt handlers for various ACM device responses 110 215 */ 111 216 ··· 342 237 static void acm_write_bulk(struct urb *urb, struct pt_regs *regs) 343 238 { 344 239 struct acm *acm = (struct acm *)urb->context; 240 + 345 241 dbg("Entering acm_write_bulk with status %d\n", urb->status); 346 242 347 - if (!ACM_READY(acm)) 348 - goto out; 349 - 350 - if (urb->status) 351 - dbg("nonzero write bulk status received: %d", urb->status); 352 - 353 - schedule_work(&acm->work); 354 - out: 355 - acm->ready_for_write = 1; 243 + acm_write_done(acm); 244 + acm_write_start(acm); 245 + if (ACM_READY(acm)) 246 + schedule_work(&acm->work); 356 247 } 357 248 358 249 static void acm_softint(void *private) ··· 452 351 { 453 352 struct acm *acm = tty->driver_data; 454 353 int stat; 354 + unsigned long flags; 355 + int wbn; 356 + struct acm_wb *wb; 357 + 455 358 dbg("Entering acm_tty_write to write %d bytes,\n", count); 456 359 457 360 if (!ACM_READY(acm)) 458 361 return -EINVAL; 459 - if (!acm->ready_for_write) 460 - return 0; 461 362 if (!count) 462 363 return 0; 463 364 464 - count = (count > acm->writesize) ? acm->writesize : count; 465 - 466 - dbg("Get %d bytes...", count); 467 - memcpy(acm->write_buffer, buf, count); 468 - dbg(" Successfully copied.\n"); 469 - 470 - acm->writeurb->transfer_buffer_length = count; 471 - acm->writeurb->dev = acm->dev; 472 - 473 - acm->ready_for_write = 0; 474 - stat = usb_submit_urb(acm->writeurb, GFP_ATOMIC); 475 - if (stat < 0) { 476 - dbg("usb_submit_urb(write bulk) failed"); 477 - acm->ready_for_write = 1; 478 - return stat; 365 + spin_lock_irqsave(&acm->write_lock, flags); 366 + if ((wbn = acm_wb_alloc(acm)) < 0) { 367 + spin_unlock_irqrestore(&acm->write_lock, flags); 368 + acm_write_start(acm); 369 + return 0; 479 370 } 371 + wb = &acm->wb[wbn]; 480 372 373 + count = (count > acm->writesize) ? acm->writesize : count; 374 + dbg("Get %d bytes...", count); 375 + memcpy(wb->buf, buf, count); 376 + wb->len = count; 377 + spin_unlock_irqrestore(&acm->write_lock, flags); 378 + 379 + if ((stat = acm_write_start(acm)) < 0) 380 + return stat; 481 381 return count; 482 382 } 483 383 ··· 487 385 struct acm *acm = tty->driver_data; 488 386 if (!ACM_READY(acm)) 489 387 return -EINVAL; 490 - return !acm->ready_for_write ? 0 : acm->writesize; 388 + /* 389 + * Do not let the line discipline to know that we have a reserve, 390 + * or it might get too enthusiastic. 391 + */ 392 + return (acm->write_ready && acm_wb_is_avail(acm)) ? acm->writesize : 0; 491 393 } 492 394 493 395 static int acm_tty_chars_in_buffer(struct tty_struct *tty) ··· 499 393 struct acm *acm = tty->driver_data; 500 394 if (!ACM_READY(acm)) 501 395 return -EINVAL; 502 - return !acm->ready_for_write ? acm->writeurb->transfer_buffer_length : 0; 396 + /* 397 + * This is inaccurate (overcounts), but it works. 398 + */ 399 + return (ACM_NWB - acm_wb_is_avail(acm)) * acm->writesize; 503 400 } 504 401 505 402 static void acm_tty_throttle(struct tty_struct *tty) ··· 634 525 /* 635 526 * USB probe and disconnect routines. 636 527 */ 528 + 529 + /* Little helper: write buffers free */ 530 + static void acm_write_buffers_free(struct acm *acm) 531 + { 532 + int i; 533 + struct acm_wb *wb; 534 + 535 + for (wb = &acm->wb[0], i = 0; i < ACM_NWB; i++, wb++) { 536 + usb_buffer_free(acm->dev, acm->writesize, wb->buf, wb->dmah); 537 + } 538 + } 539 + 540 + /* Little helper: write buffers allocate */ 541 + static int acm_write_buffers_alloc(struct acm *acm) 542 + { 543 + int i; 544 + struct acm_wb *wb; 545 + 546 + for (wb = &acm->wb[0], i = 0; i < ACM_NWB; i++, wb++) { 547 + wb->buf = usb_buffer_alloc(acm->dev, acm->writesize, GFP_KERNEL, 548 + &wb->dmah); 549 + if (!wb->buf) { 550 + while (i != 0) { 551 + --i; 552 + --wb; 553 + usb_buffer_free(acm->dev, acm->writesize, 554 + wb->buf, wb->dmah); 555 + } 556 + return -ENOMEM; 557 + } 558 + } 559 + return 0; 560 + } 637 561 638 562 static int acm_probe (struct usb_interface *intf, 639 563 const struct usb_device_id *id) ··· 842 700 acm->bh.data = (unsigned long) acm; 843 701 INIT_WORK(&acm->work, acm_softint, acm); 844 702 spin_lock_init(&acm->throttle_lock); 845 - acm->ready_for_write = 1; 703 + spin_lock_init(&acm->write_lock); 704 + acm->write_ready = 1; 846 705 847 706 buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); 848 707 if (!buf) { ··· 859 716 } 860 717 acm->read_buffer = buf; 861 718 862 - buf = usb_buffer_alloc(usb_dev, acm->writesize, GFP_KERNEL, &acm->write_dma); 863 - if (!buf) { 719 + if (acm_write_buffers_alloc(acm) < 0) { 864 720 dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); 865 721 goto alloc_fail4; 866 722 } 867 - acm->write_buffer = buf; 868 723 869 724 acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); 870 725 if (!acm->ctrlurb) { ··· 891 750 acm->readurb->transfer_dma = acm->read_dma; 892 751 893 752 usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), 894 - acm->write_buffer, acm->writesize, acm_write_bulk, acm); 753 + NULL, acm->writesize, acm_write_bulk, acm); 895 754 acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; 896 - acm->writeurb->transfer_dma = acm->write_dma; 755 + /* acm->writeurb->transfer_dma = 0; */ 897 756 898 757 dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); 899 758 ··· 916 775 alloc_fail6: 917 776 usb_free_urb(acm->ctrlurb); 918 777 alloc_fail5: 919 - usb_buffer_free(usb_dev, acm->writesize, acm->write_buffer, acm->write_dma); 778 + acm_write_buffers_free(acm); 920 779 alloc_fail4: 921 780 usb_buffer_free(usb_dev, readsize, acm->read_buffer, acm->read_dma); 922 781 alloc_fail3: ··· 947 806 948 807 flush_scheduled_work(); /* wait for acm_softint */ 949 808 950 - usb_buffer_free(usb_dev, acm->writesize, acm->write_buffer, acm->write_dma); 809 + acm_write_buffers_free(acm); 951 810 usb_buffer_free(usb_dev, acm->readsize, acm->read_buffer, acm->read_dma); 952 811 usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); 953 812
+22 -3
drivers/usb/class/cdc-acm.h
··· 51 51 * Internal driver structures. 52 52 */ 53 53 54 + /* 55 + * The only reason to have several buffers is to accomodate assumptions 56 + * in line disciplines. They ask for empty space amount, receive our URB size, 57 + * and proceed to issue several 1-character writes, assuming they will fit. 58 + * The very first write takes a complete URB. Fortunately, this only happens 59 + * when processing onlcr, so we only need 2 buffers. 60 + */ 61 + #define ACM_NWB 2 62 + struct acm_wb { 63 + unsigned char *buf; 64 + dma_addr_t dmah; 65 + int len; 66 + int use; 67 + }; 68 + 54 69 struct acm { 55 70 struct usb_device *dev; /* the corresponding usb device */ 56 71 struct usb_interface *control; /* control interface */ 57 72 struct usb_interface *data; /* data interface */ 58 73 struct tty_struct *tty; /* the corresponding tty */ 59 74 struct urb *ctrlurb, *readurb, *writeurb; /* urbs */ 60 - u8 *ctrl_buffer, *read_buffer, *write_buffer; /* buffers of urbs */ 61 - dma_addr_t ctrl_dma, read_dma, write_dma; /* dma handles of buffers */ 75 + u8 *ctrl_buffer, *read_buffer; /* buffers of urbs */ 76 + dma_addr_t ctrl_dma, read_dma; /* dma handles of buffers */ 77 + struct acm_wb wb[ACM_NWB]; 78 + int write_current; /* current write buffer */ 79 + int write_used; /* number of non-empty write buffers */ 80 + int write_ready; /* write urb is not running */ 81 + spinlock_t write_lock; 62 82 struct usb_cdc_line_coding line; /* bits, stop, parity */ 63 83 struct work_struct work; /* work queue entry for line discipline waking up */ 64 84 struct tasklet_struct bh; /* rx processing */ ··· 91 71 unsigned int minor; /* acm minor number */ 92 72 unsigned char throttle; /* throttled by tty layer */ 93 73 unsigned char clocal; /* termios CLOCAL */ 94 - unsigned char ready_for_write; /* write urb can be used */ 95 74 unsigned char resubmit_to_unthrottle; /* throtteling has disabled the read urb */ 96 75 unsigned int ctrl_caps; /* control capabilities from the class specific header */ 97 76 };