1/* 2 * cdc-acm.c 3 * 4 * Copyright (c) 1999 Armin Fuerst <fuerst@in.tum.de> 5 * Copyright (c) 1999 Pavel Machek <pavel@suse.cz> 6 * Copyright (c) 1999 Johannes Erdfelt <johannes@erdfelt.com> 7 * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> 8 * Copyright (c) 2004 Oliver Neukum <oliver@neukum.name> 9 * Copyright (c) 2005 David Kubicek <dave@awk.cz> 10 * 11 * USB Abstract Control Model driver for USB modems and ISDN adapters 12 * 13 * Sponsored by SuSE 14 * 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 kmalloced 20 * v0.13 - added termios, added hangup 21 * v0.14 - sized down struct acm 22 * v0.15 - fixed flow control again - characters could be lost 23 * v0.16 - added code for modems with swapped data and control interfaces 24 * v0.17 - added new style probing 25 * v0.18 - fixed new style probing for devices with more configurations 26 * v0.19 - fixed CLOCAL handling (thanks to Richard Shih-Ping Chan) 27 * v0.20 - switched to probing on interface (rather than device) class 28 * v0.21 - revert to probing on device for devices with multiple configs 29 * v0.22 - probe only the control interface. if usbcore doesn't choose the 30 * config we want, sysadmin changes bConfigurationValue in sysfs. 31 * v0.23 - use softirq for rx processing, as needed by tty layer 32 * v0.24 - change probe method to evaluate CDC union descriptor 33 * v0.25 - downstream tasks paralelized to maximize throughput 34 */ 35 36/* 37 * This program is free software; you can redistribute it and/or modify 38 * it under the terms of the GNU General Public License as published by 39 * the Free Software Foundation; either version 2 of the License, or 40 * (at your option) any later version. 41 * 42 * This program is distributed in the hope that it will be useful, 43 * but WITHOUT ANY WARRANTY; without even the implied warranty of 44 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 45 * GNU General Public License for more details. 46 * 47 * You should have received a copy of the GNU General Public License 48 * along with this program; if not, write to the Free Software 49 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 50 */ 51 52#undef DEBUG 53 54#include <linux/kernel.h> 55#include <linux/errno.h> 56#include <linux/init.h> 57#include <linux/slab.h> 58#include <linux/tty.h> 59#include <linux/tty_driver.h> 60#include <linux/tty_flip.h> 61#include <linux/module.h> 62#include <linux/mutex.h> 63#include <asm/uaccess.h> 64#include <linux/usb.h> 65#include <linux/usb/cdc.h> 66#include <asm/byteorder.h> 67#include <asm/unaligned.h> 68#include <linux/list.h> 69 70#include "cdc-acm.h" 71 72/* 73 * Version Information 74 */ 75#define DRIVER_VERSION "v0.25" 76#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek" 77#define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" 78 79static struct usb_driver acm_driver; 80static struct tty_driver *acm_tty_driver; 81static struct acm *acm_table[ACM_TTY_MINORS]; 82 83static DEFINE_MUTEX(open_mutex); 84 85#define ACM_READY(acm) (acm && acm->dev && acm->used) 86 87/* 88 * Functions for ACM control messages. 89 */ 90 91static int acm_ctrl_msg(struct acm *acm, int request, int value, void *buf, int len) 92{ 93 int retval = usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0), 94 request, USB_RT_ACM, value, 95 acm->control->altsetting[0].desc.bInterfaceNumber, 96 buf, len, 5000); 97 dbg("acm_control_msg: rq: 0x%02x val: %#x len: %#x result: %d", request, value, len, retval); 98 return retval < 0 ? retval : 0; 99} 100 101/* devices aren't required to support these requests. 102 * the cdc acm descriptor tells whether they do... 103 */ 104#define acm_set_control(acm, control) \ 105 acm_ctrl_msg(acm, USB_CDC_REQ_SET_CONTROL_LINE_STATE, control, NULL, 0) 106#define acm_set_line(acm, line) \ 107 acm_ctrl_msg(acm, USB_CDC_REQ_SET_LINE_CODING, 0, line, sizeof *(line)) 108#define acm_send_break(acm, ms) \ 109 acm_ctrl_msg(acm, USB_CDC_REQ_SEND_BREAK, ms, NULL, 0) 110 111/* 112 * Write buffer management. 113 * All of these assume proper locks taken by the caller. 114 */ 115 116static int acm_wb_alloc(struct acm *acm) 117{ 118 int i, wbn; 119 struct acm_wb *wb; 120 121 wbn = acm->write_current; 122 i = 0; 123 for (;;) { 124 wb = &acm->wb[wbn]; 125 if (!wb->use) { 126 wb->use = 1; 127 return wbn; 128 } 129 wbn = (wbn + 1) % ACM_NW; 130 if (++i >= ACM_NW) 131 return -1; 132 } 133} 134 135static void acm_wb_free(struct acm *acm, int wbn) 136{ 137 acm->wb[wbn].use = 0; 138} 139 140static int acm_wb_is_avail(struct acm *acm) 141{ 142 int i, n; 143 144 n = ACM_NW; 145 for (i = 0; i < ACM_NW; i++) { 146 n -= acm->wb[i].use; 147 } 148 return n; 149} 150 151static inline int acm_wb_is_used(struct acm *acm, int wbn) 152{ 153 return acm->wb[wbn].use; 154} 155 156/* 157 * Finish write. 158 */ 159static void acm_write_done(struct acm *acm) 160{ 161 unsigned long flags; 162 int wbn; 163 164 spin_lock_irqsave(&acm->write_lock, flags); 165 acm->write_ready = 1; 166 wbn = acm->write_current; 167 acm_wb_free(acm, wbn); 168 acm->write_current = (wbn + 1) % ACM_NW; 169 spin_unlock_irqrestore(&acm->write_lock, flags); 170} 171 172/* 173 * Poke write. 174 */ 175static int acm_write_start(struct acm *acm) 176{ 177 unsigned long flags; 178 int wbn; 179 struct acm_wb *wb; 180 int rc; 181 182 spin_lock_irqsave(&acm->write_lock, flags); 183 if (!acm->dev) { 184 spin_unlock_irqrestore(&acm->write_lock, flags); 185 return -ENODEV; 186 } 187 188 if (!acm->write_ready) { 189 spin_unlock_irqrestore(&acm->write_lock, flags); 190 return 0; /* A white lie */ 191 } 192 193 wbn = acm->write_current; 194 if (!acm_wb_is_used(acm, wbn)) { 195 spin_unlock_irqrestore(&acm->write_lock, flags); 196 return 0; 197 } 198 wb = &acm->wb[wbn]; 199 200 acm->write_ready = 0; 201 spin_unlock_irqrestore(&acm->write_lock, flags); 202 203 acm->writeurb->transfer_buffer = wb->buf; 204 acm->writeurb->transfer_dma = wb->dmah; 205 acm->writeurb->transfer_buffer_length = wb->len; 206 acm->writeurb->dev = acm->dev; 207 208 if ((rc = usb_submit_urb(acm->writeurb, GFP_ATOMIC)) < 0) { 209 dbg("usb_submit_urb(write bulk) failed: %d", rc); 210 acm_write_done(acm); 211 } 212 return rc; 213} 214/* 215 * attributes exported through sysfs 216 */ 217static ssize_t show_caps 218(struct device *dev, struct device_attribute *attr, char *buf) 219{ 220 struct usb_interface *intf = to_usb_interface(dev); 221 struct acm *acm = usb_get_intfdata(intf); 222 223 return sprintf(buf, "%d", acm->ctrl_caps); 224} 225static DEVICE_ATTR(bmCapabilities, S_IRUGO, show_caps, NULL); 226 227static ssize_t show_country_codes 228(struct device *dev, struct device_attribute *attr, char *buf) 229{ 230 struct usb_interface *intf = to_usb_interface(dev); 231 struct acm *acm = usb_get_intfdata(intf); 232 233 memcpy(buf, acm->country_codes, acm->country_code_size); 234 return acm->country_code_size; 235} 236 237static DEVICE_ATTR(wCountryCodes, S_IRUGO, show_country_codes, NULL); 238 239static ssize_t show_country_rel_date 240(struct device *dev, struct device_attribute *attr, char *buf) 241{ 242 struct usb_interface *intf = to_usb_interface(dev); 243 struct acm *acm = usb_get_intfdata(intf); 244 245 return sprintf(buf, "%d", acm->country_rel_date); 246} 247 248static DEVICE_ATTR(iCountryCodeRelDate, S_IRUGO, show_country_rel_date, NULL); 249/* 250 * Interrupt handlers for various ACM device responses 251 */ 252 253/* control interface reports status changes with "interrupt" transfers */ 254static void acm_ctrl_irq(struct urb *urb) 255{ 256 struct acm *acm = urb->context; 257 struct usb_cdc_notification *dr = urb->transfer_buffer; 258 unsigned char *data; 259 int newctrl; 260 int status; 261 262 switch (urb->status) { 263 case 0: 264 /* success */ 265 break; 266 case -ECONNRESET: 267 case -ENOENT: 268 case -ESHUTDOWN: 269 /* this urb is terminated, clean up */ 270 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 271 return; 272 default: 273 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); 274 goto exit; 275 } 276 277 if (!ACM_READY(acm)) 278 goto exit; 279 280 data = (unsigned char *)(dr + 1); 281 switch (dr->bNotificationType) { 282 283 case USB_CDC_NOTIFY_NETWORK_CONNECTION: 284 285 dbg("%s network", dr->wValue ? "connected to" : "disconnected from"); 286 break; 287 288 case USB_CDC_NOTIFY_SERIAL_STATE: 289 290 newctrl = le16_to_cpu(get_unaligned((__le16 *) data)); 291 292 if (acm->tty && !acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { 293 dbg("calling hangup"); 294 tty_hangup(acm->tty); 295 } 296 297 acm->ctrlin = newctrl; 298 299 dbg("input control lines: dcd%c dsr%c break%c ring%c framing%c parity%c overrun%c", 300 acm->ctrlin & ACM_CTRL_DCD ? '+' : '-', acm->ctrlin & ACM_CTRL_DSR ? '+' : '-', 301 acm->ctrlin & ACM_CTRL_BRK ? '+' : '-', acm->ctrlin & ACM_CTRL_RI ? '+' : '-', 302 acm->ctrlin & ACM_CTRL_FRAMING ? '+' : '-', acm->ctrlin & ACM_CTRL_PARITY ? '+' : '-', 303 acm->ctrlin & ACM_CTRL_OVERRUN ? '+' : '-'); 304 305 break; 306 307 default: 308 dbg("unknown notification %d received: index %d len %d data0 %d data1 %d", 309 dr->bNotificationType, dr->wIndex, 310 dr->wLength, data[0], data[1]); 311 break; 312 } 313exit: 314 status = usb_submit_urb (urb, GFP_ATOMIC); 315 if (status) 316 err ("%s - usb_submit_urb failed with result %d", 317 __FUNCTION__, status); 318} 319 320/* data interface returns incoming bytes, or we got unthrottled */ 321static void acm_read_bulk(struct urb *urb) 322{ 323 struct acm_rb *buf; 324 struct acm_ru *rcv = urb->context; 325 struct acm *acm = rcv->instance; 326 int status = urb->status; 327 dbg("Entering acm_read_bulk with status %d", urb->status); 328 329 if (!ACM_READY(acm)) 330 return; 331 332 if (status) 333 dev_dbg(&acm->data->dev, "bulk rx status %d", status); 334 335 buf = rcv->buffer; 336 buf->size = urb->actual_length; 337 338 if (likely(status == 0)) { 339 spin_lock(&acm->read_lock); 340 list_add_tail(&rcv->list, &acm->spare_read_urbs); 341 list_add_tail(&buf->list, &acm->filled_read_bufs); 342 spin_unlock(&acm->read_lock); 343 } else { 344 /* we drop the buffer due to an error */ 345 spin_lock(&acm->read_lock); 346 list_add_tail(&rcv->list, &acm->spare_read_urbs); 347 list_add(&buf->list, &acm->spare_read_bufs); 348 spin_unlock(&acm->read_lock); 349 /* nevertheless the tasklet must be kicked unconditionally 350 so the queue cannot dry up */ 351 } 352 tasklet_schedule(&acm->urb_task); 353} 354 355static void acm_rx_tasklet(unsigned long _acm) 356{ 357 struct acm *acm = (void *)_acm; 358 struct acm_rb *buf; 359 struct tty_struct *tty = acm->tty; 360 struct acm_ru *rcv; 361 unsigned long flags; 362 unsigned char throttled; 363 dbg("Entering acm_rx_tasklet"); 364 365 if (!ACM_READY(acm)) 366 return; 367 368 spin_lock_irqsave(&acm->throttle_lock, flags); 369 throttled = acm->throttle; 370 spin_unlock_irqrestore(&acm->throttle_lock, flags); 371 if (throttled) 372 return; 373 374next_buffer: 375 spin_lock_irqsave(&acm->read_lock, flags); 376 if (list_empty(&acm->filled_read_bufs)) { 377 spin_unlock_irqrestore(&acm->read_lock, flags); 378 goto urbs; 379 } 380 buf = list_entry(acm->filled_read_bufs.next, 381 struct acm_rb, list); 382 list_del(&buf->list); 383 spin_unlock_irqrestore(&acm->read_lock, flags); 384 385 dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size); 386 387 tty_buffer_request_room(tty, buf->size); 388 spin_lock_irqsave(&acm->throttle_lock, flags); 389 throttled = acm->throttle; 390 spin_unlock_irqrestore(&acm->throttle_lock, flags); 391 if (!throttled) 392 tty_insert_flip_string(tty, buf->base, buf->size); 393 tty_flip_buffer_push(tty); 394 395 if (throttled) { 396 dbg("Throttling noticed"); 397 spin_lock_irqsave(&acm->read_lock, flags); 398 list_add(&buf->list, &acm->filled_read_bufs); 399 spin_unlock_irqrestore(&acm->read_lock, flags); 400 return; 401 } 402 403 spin_lock_irqsave(&acm->read_lock, flags); 404 list_add(&buf->list, &acm->spare_read_bufs); 405 spin_unlock_irqrestore(&acm->read_lock, flags); 406 goto next_buffer; 407 408urbs: 409 while (!list_empty(&acm->spare_read_bufs)) { 410 spin_lock_irqsave(&acm->read_lock, flags); 411 if (list_empty(&acm->spare_read_urbs)) { 412 spin_unlock_irqrestore(&acm->read_lock, flags); 413 return; 414 } 415 rcv = list_entry(acm->spare_read_urbs.next, 416 struct acm_ru, list); 417 list_del(&rcv->list); 418 spin_unlock_irqrestore(&acm->read_lock, flags); 419 420 buf = list_entry(acm->spare_read_bufs.next, 421 struct acm_rb, list); 422 list_del(&buf->list); 423 424 rcv->buffer = buf; 425 426 usb_fill_bulk_urb(rcv->urb, acm->dev, 427 acm->rx_endpoint, 428 buf->base, 429 acm->readsize, 430 acm_read_bulk, rcv); 431 rcv->urb->transfer_dma = buf->dma; 432 rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 433 434 dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p", rcv->urb, rcv, buf); 435 436 /* This shouldn't kill the driver as unsuccessful URBs are returned to the 437 free-urbs-pool and resubmited ASAP */ 438 if (usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) { 439 list_add(&buf->list, &acm->spare_read_bufs); 440 spin_lock_irqsave(&acm->read_lock, flags); 441 list_add(&rcv->list, &acm->spare_read_urbs); 442 spin_unlock_irqrestore(&acm->read_lock, flags); 443 return; 444 } 445 } 446} 447 448/* data interface wrote those outgoing bytes */ 449static void acm_write_bulk(struct urb *urb) 450{ 451 struct acm *acm = (struct acm *)urb->context; 452 453 dbg("Entering acm_write_bulk with status %d", urb->status); 454 455 acm_write_done(acm); 456 acm_write_start(acm); 457 if (ACM_READY(acm)) 458 schedule_work(&acm->work); 459} 460 461static void acm_softint(struct work_struct *work) 462{ 463 struct acm *acm = container_of(work, struct acm, work); 464 dbg("Entering acm_softint."); 465 466 if (!ACM_READY(acm)) 467 return; 468 tty_wakeup(acm->tty); 469} 470 471/* 472 * TTY handlers 473 */ 474 475static int acm_tty_open(struct tty_struct *tty, struct file *filp) 476{ 477 struct acm *acm; 478 int rv = -EINVAL; 479 int i; 480 dbg("Entering acm_tty_open."); 481 482 mutex_lock(&open_mutex); 483 484 acm = acm_table[tty->index]; 485 if (!acm || !acm->dev) 486 goto err_out; 487 else 488 rv = 0; 489 490 tty->driver_data = acm; 491 acm->tty = tty; 492 493 /* force low_latency on so that our tty_push actually forces the data through, 494 otherwise it is scheduled, and with high data rates data can get lost. */ 495 tty->low_latency = 1; 496 497 if (acm->used++) { 498 goto done; 499 } 500 501 acm->ctrlurb->dev = acm->dev; 502 if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { 503 dbg("usb_submit_urb(ctrl irq) failed"); 504 goto bail_out; 505 } 506 507 if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) && 508 (acm->ctrl_caps & USB_CDC_CAP_LINE)) 509 goto full_bailout; 510 511 INIT_LIST_HEAD(&acm->spare_read_urbs); 512 INIT_LIST_HEAD(&acm->spare_read_bufs); 513 INIT_LIST_HEAD(&acm->filled_read_bufs); 514 for (i = 0; i < acm->rx_buflimit; i++) { 515 list_add(&(acm->ru[i].list), &acm->spare_read_urbs); 516 } 517 for (i = 0; i < acm->rx_buflimit; i++) { 518 list_add(&(acm->rb[i].list), &acm->spare_read_bufs); 519 } 520 521 acm->throttle = 0; 522 523 tasklet_schedule(&acm->urb_task); 524 525done: 526err_out: 527 mutex_unlock(&open_mutex); 528 return rv; 529 530full_bailout: 531 usb_kill_urb(acm->ctrlurb); 532bail_out: 533 acm->used--; 534 mutex_unlock(&open_mutex); 535 return -EIO; 536} 537 538static void acm_tty_unregister(struct acm *acm) 539{ 540 int i,nr; 541 542 nr = acm->rx_buflimit; 543 tty_unregister_device(acm_tty_driver, acm->minor); 544 usb_put_intf(acm->control); 545 acm_table[acm->minor] = NULL; 546 usb_free_urb(acm->ctrlurb); 547 usb_free_urb(acm->writeurb); 548 for (i = 0; i < nr; i++) 549 usb_free_urb(acm->ru[i].urb); 550 kfree(acm->country_codes); 551 kfree(acm); 552} 553 554static void acm_tty_close(struct tty_struct *tty, struct file *filp) 555{ 556 struct acm *acm = tty->driver_data; 557 int i,nr; 558 559 if (!acm || !acm->used) 560 return; 561 562 nr = acm->rx_buflimit; 563 mutex_lock(&open_mutex); 564 if (!--acm->used) { 565 if (acm->dev) { 566 acm_set_control(acm, acm->ctrlout = 0); 567 usb_kill_urb(acm->ctrlurb); 568 usb_kill_urb(acm->writeurb); 569 for (i = 0; i < nr; i++) 570 usb_kill_urb(acm->ru[i].urb); 571 } else 572 acm_tty_unregister(acm); 573 } 574 mutex_unlock(&open_mutex); 575} 576 577static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) 578{ 579 struct acm *acm = tty->driver_data; 580 int stat; 581 unsigned long flags; 582 int wbn; 583 struct acm_wb *wb; 584 585 dbg("Entering acm_tty_write to write %d bytes,", count); 586 587 if (!ACM_READY(acm)) 588 return -EINVAL; 589 if (!count) 590 return 0; 591 592 spin_lock_irqsave(&acm->write_lock, flags); 593 if ((wbn = acm_wb_alloc(acm)) < 0) { 594 spin_unlock_irqrestore(&acm->write_lock, flags); 595 acm_write_start(acm); 596 return 0; 597 } 598 wb = &acm->wb[wbn]; 599 600 count = (count > acm->writesize) ? acm->writesize : count; 601 dbg("Get %d bytes...", count); 602 memcpy(wb->buf, buf, count); 603 wb->len = count; 604 spin_unlock_irqrestore(&acm->write_lock, flags); 605 606 if ((stat = acm_write_start(acm)) < 0) 607 return stat; 608 return count; 609} 610 611static int acm_tty_write_room(struct tty_struct *tty) 612{ 613 struct acm *acm = tty->driver_data; 614 if (!ACM_READY(acm)) 615 return -EINVAL; 616 /* 617 * Do not let the line discipline to know that we have a reserve, 618 * or it might get too enthusiastic. 619 */ 620 return (acm->write_ready && acm_wb_is_avail(acm)) ? acm->writesize : 0; 621} 622 623static int acm_tty_chars_in_buffer(struct tty_struct *tty) 624{ 625 struct acm *acm = tty->driver_data; 626 if (!ACM_READY(acm)) 627 return -EINVAL; 628 /* 629 * This is inaccurate (overcounts), but it works. 630 */ 631 return (ACM_NW - acm_wb_is_avail(acm)) * acm->writesize; 632} 633 634static void acm_tty_throttle(struct tty_struct *tty) 635{ 636 struct acm *acm = tty->driver_data; 637 if (!ACM_READY(acm)) 638 return; 639 spin_lock_bh(&acm->throttle_lock); 640 acm->throttle = 1; 641 spin_unlock_bh(&acm->throttle_lock); 642} 643 644static void acm_tty_unthrottle(struct tty_struct *tty) 645{ 646 struct acm *acm = tty->driver_data; 647 if (!ACM_READY(acm)) 648 return; 649 spin_lock_bh(&acm->throttle_lock); 650 acm->throttle = 0; 651 spin_unlock_bh(&acm->throttle_lock); 652 tasklet_schedule(&acm->urb_task); 653} 654 655static void acm_tty_break_ctl(struct tty_struct *tty, int state) 656{ 657 struct acm *acm = tty->driver_data; 658 if (!ACM_READY(acm)) 659 return; 660 if (acm_send_break(acm, state ? 0xffff : 0)) 661 dbg("send break failed"); 662} 663 664static int acm_tty_tiocmget(struct tty_struct *tty, struct file *file) 665{ 666 struct acm *acm = tty->driver_data; 667 668 if (!ACM_READY(acm)) 669 return -EINVAL; 670 671 return (acm->ctrlout & ACM_CTRL_DTR ? TIOCM_DTR : 0) | 672 (acm->ctrlout & ACM_CTRL_RTS ? TIOCM_RTS : 0) | 673 (acm->ctrlin & ACM_CTRL_DSR ? TIOCM_DSR : 0) | 674 (acm->ctrlin & ACM_CTRL_RI ? TIOCM_RI : 0) | 675 (acm->ctrlin & ACM_CTRL_DCD ? TIOCM_CD : 0) | 676 TIOCM_CTS; 677} 678 679static int acm_tty_tiocmset(struct tty_struct *tty, struct file *file, 680 unsigned int set, unsigned int clear) 681{ 682 struct acm *acm = tty->driver_data; 683 unsigned int newctrl; 684 685 if (!ACM_READY(acm)) 686 return -EINVAL; 687 688 newctrl = acm->ctrlout; 689 set = (set & TIOCM_DTR ? ACM_CTRL_DTR : 0) | (set & TIOCM_RTS ? ACM_CTRL_RTS : 0); 690 clear = (clear & TIOCM_DTR ? ACM_CTRL_DTR : 0) | (clear & TIOCM_RTS ? ACM_CTRL_RTS : 0); 691 692 newctrl = (newctrl & ~clear) | set; 693 694 if (acm->ctrlout == newctrl) 695 return 0; 696 return acm_set_control(acm, acm->ctrlout = newctrl); 697} 698 699static int acm_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) 700{ 701 struct acm *acm = tty->driver_data; 702 703 if (!ACM_READY(acm)) 704 return -EINVAL; 705 706 return -ENOIOCTLCMD; 707} 708 709static const __u32 acm_tty_speed[] = { 710 0, 50, 75, 110, 134, 150, 200, 300, 600, 711 1200, 1800, 2400, 4800, 9600, 19200, 38400, 712 57600, 115200, 230400, 460800, 500000, 576000, 713 921600, 1000000, 1152000, 1500000, 2000000, 714 2500000, 3000000, 3500000, 4000000 715}; 716 717static const __u8 acm_tty_size[] = { 718 5, 6, 7, 8 719}; 720 721static void acm_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old) 722{ 723 struct acm *acm = tty->driver_data; 724 struct ktermios *termios = tty->termios; 725 struct usb_cdc_line_coding newline; 726 int newctrl = acm->ctrlout; 727 728 if (!ACM_READY(acm)) 729 return; 730 731 newline.dwDTERate = cpu_to_le32p(acm_tty_speed + 732 (termios->c_cflag & CBAUD & ~CBAUDEX) + (termios->c_cflag & CBAUDEX ? 15 : 0)); 733 newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0; 734 newline.bParityType = termios->c_cflag & PARENB ? 735 (termios->c_cflag & PARODD ? 1 : 2) + (termios->c_cflag & CMSPAR ? 2 : 0) : 0; 736 newline.bDataBits = acm_tty_size[(termios->c_cflag & CSIZE) >> 4]; 737 738 acm->clocal = ((termios->c_cflag & CLOCAL) != 0); 739 740 if (!newline.dwDTERate) { 741 newline.dwDTERate = acm->line.dwDTERate; 742 newctrl &= ~ACM_CTRL_DTR; 743 } else newctrl |= ACM_CTRL_DTR; 744 745 if (newctrl != acm->ctrlout) 746 acm_set_control(acm, acm->ctrlout = newctrl); 747 748 if (memcmp(&acm->line, &newline, sizeof newline)) { 749 memcpy(&acm->line, &newline, sizeof newline); 750 dbg("set line: %d %d %d %d", le32_to_cpu(newline.dwDTERate), 751 newline.bCharFormat, newline.bParityType, 752 newline.bDataBits); 753 acm_set_line(acm, &acm->line); 754 } 755} 756 757/* 758 * USB probe and disconnect routines. 759 */ 760 761/* Little helper: write buffers free */ 762static void acm_write_buffers_free(struct acm *acm) 763{ 764 int i; 765 struct acm_wb *wb; 766 767 for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) { 768 usb_buffer_free(acm->dev, acm->writesize, wb->buf, wb->dmah); 769 } 770} 771 772/* Little helper: write buffers allocate */ 773static int acm_write_buffers_alloc(struct acm *acm) 774{ 775 int i; 776 struct acm_wb *wb; 777 778 for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) { 779 wb->buf = usb_buffer_alloc(acm->dev, acm->writesize, GFP_KERNEL, 780 &wb->dmah); 781 if (!wb->buf) { 782 while (i != 0) { 783 --i; 784 --wb; 785 usb_buffer_free(acm->dev, acm->writesize, 786 wb->buf, wb->dmah); 787 } 788 return -ENOMEM; 789 } 790 } 791 return 0; 792} 793 794static int acm_probe (struct usb_interface *intf, 795 const struct usb_device_id *id) 796{ 797 struct usb_cdc_union_desc *union_header = NULL; 798 struct usb_cdc_country_functional_desc *cfd = NULL; 799 char *buffer = intf->altsetting->extra; 800 int buflen = intf->altsetting->extralen; 801 struct usb_interface *control_interface; 802 struct usb_interface *data_interface; 803 struct usb_endpoint_descriptor *epctrl; 804 struct usb_endpoint_descriptor *epread; 805 struct usb_endpoint_descriptor *epwrite; 806 struct usb_device *usb_dev = interface_to_usbdev(intf); 807 struct acm *acm; 808 int minor; 809 int ctrlsize,readsize; 810 u8 *buf; 811 u8 ac_management_function = 0; 812 u8 call_management_function = 0; 813 int call_interface_num = -1; 814 int data_interface_num; 815 unsigned long quirks; 816 int num_rx_buf; 817 int i; 818 819 /* normal quirks */ 820 quirks = (unsigned long)id->driver_info; 821 num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR; 822 823 /* handle quirks deadly to normal probing*/ 824 if (quirks == NO_UNION_NORMAL) { 825 data_interface = usb_ifnum_to_if(usb_dev, 1); 826 control_interface = usb_ifnum_to_if(usb_dev, 0); 827 goto skip_normal_probe; 828 } 829 830 /* normal probing*/ 831 if (!buffer) { 832 err("Wierd descriptor references\n"); 833 return -EINVAL; 834 } 835 836 if (!buflen) { 837 if (intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) { 838 dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint"); 839 buflen = intf->cur_altsetting->endpoint->extralen; 840 buffer = intf->cur_altsetting->endpoint->extra; 841 } else { 842 err("Zero length descriptor references\n"); 843 return -EINVAL; 844 } 845 } 846 847 while (buflen > 0) { 848 if (buffer [1] != USB_DT_CS_INTERFACE) { 849 err("skipping garbage\n"); 850 goto next_desc; 851 } 852 853 switch (buffer [2]) { 854 case USB_CDC_UNION_TYPE: /* we've found it */ 855 if (union_header) { 856 err("More than one union descriptor, skipping ..."); 857 goto next_desc; 858 } 859 union_header = (struct usb_cdc_union_desc *) 860 buffer; 861 break; 862 case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/ 863 cfd = (struct usb_cdc_country_functional_desc *)buffer; 864 break; 865 case USB_CDC_HEADER_TYPE: /* maybe check version */ 866 break; /* for now we ignore it */ 867 case USB_CDC_ACM_TYPE: 868 ac_management_function = buffer[3]; 869 break; 870 case USB_CDC_CALL_MANAGEMENT_TYPE: 871 call_management_function = buffer[3]; 872 call_interface_num = buffer[4]; 873 if ((call_management_function & 3) != 3) 874 err("This device cannot do calls on its own. It is no modem."); 875 break; 876 877 default: 878 err("Ignoring extra header, type %d, length %d", buffer[2], buffer[0]); 879 break; 880 } 881next_desc: 882 buflen -= buffer[0]; 883 buffer += buffer[0]; 884 } 885 886 if (!union_header) { 887 if (call_interface_num > 0) { 888 dev_dbg(&intf->dev,"No union descriptor, using call management descriptor"); 889 data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); 890 control_interface = intf; 891 } else { 892 dev_dbg(&intf->dev,"No union descriptor, giving up"); 893 return -ENODEV; 894 } 895 } else { 896 control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0); 897 data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0)); 898 if (!control_interface || !data_interface) { 899 dev_dbg(&intf->dev,"no interfaces"); 900 return -ENODEV; 901 } 902 } 903 904 if (data_interface_num != call_interface_num) 905 dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported."); 906 907skip_normal_probe: 908 909 if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) { 910 if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) { 911 struct usb_interface *t; 912 dev_dbg(&intf->dev,"Your device has switched interfaces."); 913 914 t = control_interface; 915 control_interface = data_interface; 916 data_interface = t; 917 } else { 918 return -EINVAL; 919 } 920 } 921 922 if (usb_interface_claimed(data_interface)) { /* valid in this context */ 923 dev_dbg(&intf->dev,"The data interface isn't available"); 924 return -EBUSY; 925 } 926 927 928 if (data_interface->cur_altsetting->desc.bNumEndpoints < 2) 929 return -EINVAL; 930 931 epctrl = &control_interface->cur_altsetting->endpoint[0].desc; 932 epread = &data_interface->cur_altsetting->endpoint[0].desc; 933 epwrite = &data_interface->cur_altsetting->endpoint[1].desc; 934 935 936 if (!usb_endpoint_dir_in(epread)) { 937 /* descriptors are swapped */ 938 struct usb_endpoint_descriptor *t; 939 dev_dbg(&intf->dev,"The data interface has switched endpoints"); 940 941 t = epread; 942 epread = epwrite; 943 epwrite = t; 944 } 945 dbg("interfaces are valid"); 946 for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); 947 948 if (minor == ACM_TTY_MINORS) { 949 err("no more free acm devices"); 950 return -ENODEV; 951 } 952 953 if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) { 954 dev_dbg(&intf->dev, "out of memory (acm kzalloc)"); 955 goto alloc_fail; 956 } 957 958 ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); 959 readsize = le16_to_cpu(epread->wMaxPacketSize)* ( quirks == SINGLE_RX_URB ? 1 : 2); 960 acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize); 961 acm->control = control_interface; 962 acm->data = data_interface; 963 acm->minor = minor; 964 acm->dev = usb_dev; 965 acm->ctrl_caps = ac_management_function; 966 acm->ctrlsize = ctrlsize; 967 acm->readsize = readsize; 968 acm->rx_buflimit = num_rx_buf; 969 acm->urb_task.func = acm_rx_tasklet; 970 acm->urb_task.data = (unsigned long) acm; 971 INIT_WORK(&acm->work, acm_softint); 972 spin_lock_init(&acm->throttle_lock); 973 spin_lock_init(&acm->write_lock); 974 spin_lock_init(&acm->read_lock); 975 acm->write_ready = 1; 976 acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); 977 978 buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); 979 if (!buf) { 980 dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)"); 981 goto alloc_fail2; 982 } 983 acm->ctrl_buffer = buf; 984 985 if (acm_write_buffers_alloc(acm) < 0) { 986 dev_dbg(&intf->dev, "out of memory (write buffer alloc)"); 987 goto alloc_fail4; 988 } 989 990 acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); 991 if (!acm->ctrlurb) { 992 dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)"); 993 goto alloc_fail5; 994 } 995 for (i = 0; i < num_rx_buf; i++) { 996 struct acm_ru *rcv = &(acm->ru[i]); 997 998 if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) { 999 dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)"); 1000 goto alloc_fail7; 1001 } 1002 1003 rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 1004 rcv->instance = acm; 1005 } 1006 for (i = 0; i < num_rx_buf; i++) { 1007 struct acm_rb *buf = &(acm->rb[i]); 1008 1009 if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) { 1010 dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)"); 1011 goto alloc_fail7; 1012 } 1013 } 1014 acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); 1015 if (!acm->writeurb) { 1016 dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)"); 1017 goto alloc_fail7; 1018 } 1019 1020 usb_set_intfdata (intf, acm); 1021 1022 i = device_create_file(&intf->dev, &dev_attr_bmCapabilities); 1023 if (i < 0) 1024 goto alloc_fail8; 1025 1026 if (cfd) { /* export the country data */ 1027 acm->country_codes = kmalloc(cfd->bLength - 4, GFP_KERNEL); 1028 if (!acm->country_codes) 1029 goto skip_countries; 1030 acm->country_code_size = cfd->bLength - 4; 1031 memcpy(acm->country_codes, (u8 *)&cfd->wCountyCode0, cfd->bLength - 4); 1032 acm->country_rel_date = cfd->iCountryCodeRelDate; 1033 1034 i = device_create_file(&intf->dev, &dev_attr_wCountryCodes); 1035 if (i < 0) { 1036 kfree(acm->country_codes); 1037 goto skip_countries; 1038 } 1039 1040 i = device_create_file(&intf->dev, &dev_attr_iCountryCodeRelDate); 1041 if (i < 0) { 1042 kfree(acm->country_codes); 1043 goto skip_countries; 1044 } 1045 } 1046 1047skip_countries: 1048 usb_fill_int_urb(acm->ctrlurb, usb_dev, usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress), 1049 acm->ctrl_buffer, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval); 1050 acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 1051 acm->ctrlurb->transfer_dma = acm->ctrl_dma; 1052 1053 usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), 1054 NULL, acm->writesize, acm_write_bulk, acm); 1055 acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; 1056 1057 dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); 1058 1059 acm_set_control(acm, acm->ctrlout); 1060 1061 acm->line.dwDTERate = cpu_to_le32(9600); 1062 acm->line.bDataBits = 8; 1063 acm_set_line(acm, &acm->line); 1064 1065 usb_driver_claim_interface(&acm_driver, data_interface, acm); 1066 1067 usb_get_intf(control_interface); 1068 tty_register_device(acm_tty_driver, minor, &control_interface->dev); 1069 1070 acm_table[minor] = acm; 1071 1072 return 0; 1073alloc_fail8: 1074 usb_free_urb(acm->writeurb); 1075alloc_fail7: 1076 for (i = 0; i < num_rx_buf; i++) 1077 usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); 1078 for (i = 0; i < num_rx_buf; i++) 1079 usb_free_urb(acm->ru[i].urb); 1080 usb_free_urb(acm->ctrlurb); 1081alloc_fail5: 1082 acm_write_buffers_free(acm); 1083alloc_fail4: 1084 usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); 1085alloc_fail2: 1086 kfree(acm); 1087alloc_fail: 1088 return -ENOMEM; 1089} 1090 1091static void acm_disconnect(struct usb_interface *intf) 1092{ 1093 struct acm *acm = usb_get_intfdata(intf); 1094 struct usb_device *usb_dev = interface_to_usbdev(intf); 1095 int i; 1096 1097 if (!acm || !acm->dev) { 1098 dbg("disconnect on nonexisting interface"); 1099 return; 1100 } 1101 1102 mutex_lock(&open_mutex); 1103 if (!usb_get_intfdata(intf)) { 1104 mutex_unlock(&open_mutex); 1105 return; 1106 } 1107 if (acm->country_codes){ 1108 device_remove_file(&intf->dev, &dev_attr_wCountryCodes); 1109 device_remove_file(&intf->dev, &dev_attr_iCountryCodeRelDate); 1110 } 1111 device_remove_file(&intf->dev, &dev_attr_bmCapabilities); 1112 acm->dev = NULL; 1113 usb_set_intfdata(acm->control, NULL); 1114 usb_set_intfdata(acm->data, NULL); 1115 1116 tasklet_disable(&acm->urb_task); 1117 1118 usb_kill_urb(acm->ctrlurb); 1119 usb_kill_urb(acm->writeurb); 1120 for (i = 0; i < acm->rx_buflimit; i++) 1121 usb_kill_urb(acm->ru[i].urb); 1122 1123 INIT_LIST_HEAD(&acm->filled_read_bufs); 1124 INIT_LIST_HEAD(&acm->spare_read_bufs); 1125 1126 tasklet_enable(&acm->urb_task); 1127 1128 flush_scheduled_work(); /* wait for acm_softint */ 1129 1130 acm_write_buffers_free(acm); 1131 usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); 1132 for (i = 0; i < acm->rx_buflimit; i++) 1133 usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); 1134 1135 usb_driver_release_interface(&acm_driver, intf == acm->control ? acm->data : intf); 1136 1137 if (!acm->used) { 1138 acm_tty_unregister(acm); 1139 mutex_unlock(&open_mutex); 1140 return; 1141 } 1142 1143 mutex_unlock(&open_mutex); 1144 1145 if (acm->tty) 1146 tty_hangup(acm->tty); 1147} 1148 1149/* 1150 * USB driver structure. 1151 */ 1152 1153static struct usb_device_id acm_ids[] = { 1154 /* quirky and broken devices */ 1155 { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ 1156 .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ 1157 }, 1158 { USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */ 1159 .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ 1160 }, 1161 { USB_DEVICE(0x079b, 0x000f), /* BT On-Air USB MODEM */ 1162 .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ 1163 }, 1164 { USB_DEVICE(0x0ace, 0x1608), /* ZyDAS 56K USB MODEM */ 1165 .driver_info = SINGLE_RX_URB, /* firmware bug */ 1166 }, 1167 { USB_DEVICE(0x0ace, 0x1611), /* ZyDAS 56K USB MODEM - new version */ 1168 .driver_info = SINGLE_RX_URB, /* firmware bug */ 1169 }, 1170 { USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */ 1171 .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ 1172 }, 1173 1174 /* control interfaces with various AT-command sets */ 1175 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, 1176 USB_CDC_ACM_PROTO_AT_V25TER) }, 1177 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, 1178 USB_CDC_ACM_PROTO_AT_PCCA101) }, 1179 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, 1180 USB_CDC_ACM_PROTO_AT_PCCA101_WAKE) }, 1181 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, 1182 USB_CDC_ACM_PROTO_AT_GSM) }, 1183 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, 1184 USB_CDC_ACM_PROTO_AT_3G ) }, 1185 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, 1186 USB_CDC_ACM_PROTO_AT_CDMA) }, 1187 1188 /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */ 1189 { } 1190}; 1191 1192MODULE_DEVICE_TABLE (usb, acm_ids); 1193 1194static struct usb_driver acm_driver = { 1195 .name = "cdc_acm", 1196 .probe = acm_probe, 1197 .disconnect = acm_disconnect, 1198 .id_table = acm_ids, 1199}; 1200 1201/* 1202 * TTY driver structures. 1203 */ 1204 1205static const struct tty_operations acm_ops = { 1206 .open = acm_tty_open, 1207 .close = acm_tty_close, 1208 .write = acm_tty_write, 1209 .write_room = acm_tty_write_room, 1210 .ioctl = acm_tty_ioctl, 1211 .throttle = acm_tty_throttle, 1212 .unthrottle = acm_tty_unthrottle, 1213 .chars_in_buffer = acm_tty_chars_in_buffer, 1214 .break_ctl = acm_tty_break_ctl, 1215 .set_termios = acm_tty_set_termios, 1216 .tiocmget = acm_tty_tiocmget, 1217 .tiocmset = acm_tty_tiocmset, 1218}; 1219 1220/* 1221 * Init / exit. 1222 */ 1223 1224static int __init acm_init(void) 1225{ 1226 int retval; 1227 acm_tty_driver = alloc_tty_driver(ACM_TTY_MINORS); 1228 if (!acm_tty_driver) 1229 return -ENOMEM; 1230 acm_tty_driver->owner = THIS_MODULE, 1231 acm_tty_driver->driver_name = "acm", 1232 acm_tty_driver->name = "ttyACM", 1233 acm_tty_driver->major = ACM_TTY_MAJOR, 1234 acm_tty_driver->minor_start = 0, 1235 acm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL, 1236 acm_tty_driver->subtype = SERIAL_TYPE_NORMAL, 1237 acm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; 1238 acm_tty_driver->init_termios = tty_std_termios; 1239 acm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; 1240 tty_set_operations(acm_tty_driver, &acm_ops); 1241 1242 retval = tty_register_driver(acm_tty_driver); 1243 if (retval) { 1244 put_tty_driver(acm_tty_driver); 1245 return retval; 1246 } 1247 1248 retval = usb_register(&acm_driver); 1249 if (retval) { 1250 tty_unregister_driver(acm_tty_driver); 1251 put_tty_driver(acm_tty_driver); 1252 return retval; 1253 } 1254 1255 info(DRIVER_VERSION ":" DRIVER_DESC); 1256 1257 return 0; 1258} 1259 1260static void __exit acm_exit(void) 1261{ 1262 usb_deregister(&acm_driver); 1263 tty_unregister_driver(acm_tty_driver); 1264 put_tty_driver(acm_tty_driver); 1265} 1266 1267module_init(acm_init); 1268module_exit(acm_exit); 1269 1270MODULE_AUTHOR( DRIVER_AUTHOR ); 1271MODULE_DESCRIPTION( DRIVER_DESC ); 1272MODULE_LICENSE("GPL"); 1273