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>
9 * USB Abstract Control Model driver for USB modems and ISDN adapters
14 * v0.9 - thorough cleaning, URBification, almost a rewrite
15 * v0.10 - some more cleanups
16 * v0.11 - fixed flow control, read error doesn't stop reads
17 * v0.12 - added TIOCM ioctls, added break handling, made struct acm kmalloced
18 * v0.13 - added termios, added hangup
19 * v0.14 - sized down struct acm
20 * v0.15 - fixed flow control again - characters could be lost
21 * v0.16 - added code for modems with swapped data and control interfaces
22 * v0.17 - added new style probing
23 * v0.18 - fixed new style probing for devices with more configurations
24 * v0.19 - fixed CLOCAL handling (thanks to Richard Shih-Ping Chan)
25 * v0.20 - switched to probing on interface (rather than device) class
26 * v0.21 - revert to probing on device for devices with multiple configs
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
40 * You should have received a copy of the GNU General Public License
41 * along with this program; if not, write to the Free Software
42 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
45 #include <linux/kernel.h>
46 #include <linux/errno.h>
47 #include <linux/init.h>
48 #include <linux/slab.h>
49 #include <linux/tty.h>
50 #include <linux/tty_driver.h>
51 #include <linux/tty_flip.h>
52 #include <linux/module.h>
53 #include <linux/smp_lock.h>
54 #include <asm/uaccess.h>
56 #include <linux/usb.h>
57 #include <asm/byteorder.h>
62 #define DRIVER_VERSION "v0.21"
63 #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik"
64 #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
67 * CMSPAR, some architectures can't have space and mark parity.
75 * Major and minor numbers.
78 #define ACM_TTY_MAJOR 166
79 #define ACM_TTY_MINORS 32
85 #define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
87 #define ACM_REQ_COMMAND 0x00
88 #define ACM_REQ_RESPONSE 0x01
89 #define ACM_REQ_SET_FEATURE 0x02
90 #define ACM_REQ_GET_FEATURE 0x03
91 #define ACM_REQ_CLEAR_FEATURE 0x04
93 #define ACM_REQ_SET_LINE 0x20
94 #define ACM_REQ_GET_LINE 0x21
95 #define ACM_REQ_SET_CONTROL 0x22
96 #define ACM_REQ_SEND_BREAK 0x23
102 #define ACM_IRQ_NETWORK 0x00
103 #define ACM_IRQ_LINE_STATE 0x20
106 * Output control lines.
109 #define ACM_CTRL_DTR 0x01
110 #define ACM_CTRL_RTS 0x02
113 * Input control lines and line errors.
116 #define ACM_CTRL_DCD 0x01
117 #define ACM_CTRL_DSR 0x02
118 #define ACM_CTRL_BRK 0x04
119 #define ACM_CTRL_RI 0x08
121 #define ACM_CTRL_FRAMING 0x10
122 #define ACM_CTRL_PARITY 0x20
123 #define ACM_CTRL_OVERRUN 0x40
126 * Line speed and caracter encoding.
134 } __attribute__ ((packed));
137 * Internal driver structures.
141 struct usb_device *dev; /* the corresponding usb device */
142 struct usb_interface *iface; /* the interfaces - +0 control +1 data */
143 struct tty_struct *tty; /* the corresponding tty */
144 struct urb *ctrlurb, *readurb, *writeurb; /* urbs */
145 struct acm_line line; /* line coding (bits, stop, parity) */
146 struct work_struct work; /* work queue entry for line discipline waking up */
147 unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */
148 unsigned int ctrlout; /* output control lines (DTR, RTS) */
149 unsigned int writesize; /* max packet size for the output bulk endpoint */
150 unsigned int used; /* someone has this acm's device open */
151 unsigned int minor; /* acm minor number */
152 unsigned char throttle; /* throttled by tty layer */
153 unsigned char clocal; /* termios CLOCAL */
156 static struct usb_driver acm_driver;
157 static struct tty_driver *acm_tty_driver;
158 static struct acm *acm_table[ACM_TTY_MINORS];
160 #define ACM_READY(acm) (acm && acm->dev && acm->used)
163 * Functions for ACM control messages.
166 static int acm_ctrl_msg(struct acm *acm, int request, int value, void *buf, int len)
168 int retval = usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0),
169 request, USB_RT_ACM, value,
170 acm->iface[0].altsetting[0].desc.bInterfaceNumber,
172 dbg("acm_control_msg: rq: 0x%02x val: %#x len: %#x result: %d", request, value, len, retval);
173 return retval < 0 ? retval : 0;
176 #define acm_set_control(acm, control) acm_ctrl_msg(acm, ACM_REQ_SET_CONTROL, control, NULL, 0)
177 #define acm_set_line(acm, line) acm_ctrl_msg(acm, ACM_REQ_SET_LINE, 0, line, sizeof(struct acm_line))
178 #define acm_send_break(acm, ms) acm_ctrl_msg(acm, ACM_REQ_SEND_BREAK, ms, NULL, 0)
181 * Interrupt handler for various ACM control events
184 static void acm_ctrl_irq(struct urb *urb, struct pt_regs *regs)
186 struct acm *acm = urb->context;
187 struct usb_ctrlrequest *dr = urb->transfer_buffer;
188 unsigned char *data = (unsigned char *)(dr + 1);
192 switch (urb->status) {
199 /* this urb is terminated, clean up */
200 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
203 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
210 switch (dr->bRequest) {
212 case ACM_IRQ_NETWORK:
214 dbg("%s network", data[0] ? "connected to" : "disconnected from");
217 case ACM_IRQ_LINE_STATE:
219 newctrl = le16_to_cpup((__u16 *) data);
221 if (acm->tty && !acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
222 dbg("calling hangup");
223 tty_hangup(acm->tty);
226 acm->ctrlin = newctrl;
228 dbg("input control lines: dcd%c dsr%c break%c ring%c framing%c parity%c overrun%c",
229 acm->ctrlin & ACM_CTRL_DCD ? '+' : '-', acm->ctrlin & ACM_CTRL_DSR ? '+' : '-',
230 acm->ctrlin & ACM_CTRL_BRK ? '+' : '-', acm->ctrlin & ACM_CTRL_RI ? '+' : '-',
231 acm->ctrlin & ACM_CTRL_FRAMING ? '+' : '-', acm->ctrlin & ACM_CTRL_PARITY ? '+' : '-',
232 acm->ctrlin & ACM_CTRL_OVERRUN ? '+' : '-');
237 dbg("unknown control event received: request %d index %d len %d data0 %d data1 %d",
238 dr->bRequest, dr->wIndex, dr->wLength, data[0], data[1]);
242 status = usb_submit_urb (urb, GFP_ATOMIC);
244 err ("%s - usb_submit_urb failed with result %d",
245 __FUNCTION__, status);
248 static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
250 struct acm *acm = urb->context;
251 struct tty_struct *tty = acm->tty;
252 unsigned char *data = urb->transfer_buffer;
259 dbg("nonzero read bulk status received: %d", urb->status);
261 if (!urb->status && !acm->throttle) {
262 for (i = 0; i < urb->actual_length && !acm->throttle; i++) {
263 /* if we insert more than TTY_FLIPBUF_SIZE characters,
265 if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
266 tty_flip_buffer_push(tty);
268 tty_insert_flip_char(tty, data[i], 0);
270 tty_flip_buffer_push(tty);
274 memmove(data, data + i, urb->actual_length - i);
275 urb->actual_length -= i;
279 urb->actual_length = 0;
282 if (usb_submit_urb(urb, GFP_ATOMIC))
283 dbg("failed resubmitting read urb");
286 static void acm_write_bulk(struct urb *urb, struct pt_regs *regs)
288 struct acm *acm = (struct acm *)urb->context;
294 dbg("nonzero write bulk status received: %d", urb->status);
296 schedule_work(&acm->work);
299 static void acm_softint(void *private)
301 struct acm *acm = private;
302 struct tty_struct *tty = acm->tty;
307 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
308 (tty->ldisc.write_wakeup)(tty);
310 wake_up_interruptible(&tty->write_wait);
317 static int acm_tty_open(struct tty_struct *tty, struct file *filp)
319 struct acm *acm = acm_table[tty->index];
321 if (!acm || !acm->dev)
324 tty->driver_data = acm;
336 acm->ctrlurb->dev = acm->dev;
337 if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL))
338 dbg("usb_submit_urb(ctrl irq) failed");
340 acm->readurb->dev = acm->dev;
341 if (usb_submit_urb(acm->readurb, GFP_KERNEL))
342 dbg("usb_submit_urb(read bulk) failed");
344 acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS);
346 /* force low_latency on so that our tty_push actually forces the data through,
347 otherwise it is scheduled, and with high data rates data can get lost. */
348 tty->low_latency = 1;
353 static void acm_tty_close(struct tty_struct *tty, struct file *filp)
355 struct acm *acm = tty->driver_data;
357 if (!acm || !acm->used)
362 acm_set_control(acm, acm->ctrlout = 0);
363 usb_unlink_urb(acm->ctrlurb);
364 usb_unlink_urb(acm->writeurb);
365 usb_unlink_urb(acm->readurb);
367 tty_unregister_device(acm_tty_driver, acm->minor);
368 acm_table[acm->minor] = NULL;
369 usb_free_urb(acm->ctrlurb);
370 usb_free_urb(acm->readurb);
371 usb_free_urb(acm->writeurb);
377 static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
379 struct acm *acm = tty->driver_data;
383 if (acm->writeurb->status == -EINPROGRESS)
388 count = (count > acm->writesize) ? acm->writesize : count;
391 if (copy_from_user(acm->writeurb->transfer_buffer, (void __user *)buf, count))
394 memcpy(acm->writeurb->transfer_buffer, buf, count);
396 acm->writeurb->transfer_buffer_length = count;
397 acm->writeurb->dev = acm->dev;
399 if (usb_submit_urb(acm->writeurb, GFP_KERNEL))
400 dbg("usb_submit_urb(write bulk) failed");
405 static int acm_tty_write_room(struct tty_struct *tty)
407 struct acm *acm = tty->driver_data;
410 return acm->writeurb->status == -EINPROGRESS ? 0 : acm->writesize;
413 static int acm_tty_chars_in_buffer(struct tty_struct *tty)
415 struct acm *acm = tty->driver_data;
418 return acm->writeurb->status == -EINPROGRESS ? acm->writeurb->transfer_buffer_length : 0;
421 static void acm_tty_throttle(struct tty_struct *tty)
423 struct acm *acm = tty->driver_data;
429 static void acm_tty_unthrottle(struct tty_struct *tty)
431 struct acm *acm = tty->driver_data;
435 if (acm->readurb->status != -EINPROGRESS)
436 acm_read_bulk(acm->readurb, NULL);
439 static void acm_tty_break_ctl(struct tty_struct *tty, int state)
441 struct acm *acm = tty->driver_data;
444 if (acm_send_break(acm, state ? 0xffff : 0))
445 dbg("send break failed");
448 static int acm_tty_tiocmget(struct tty_struct *tty, struct file *file)
450 struct acm *acm = tty->driver_data;
455 return (acm->ctrlout & ACM_CTRL_DTR ? TIOCM_DTR : 0) |
456 (acm->ctrlout & ACM_CTRL_RTS ? TIOCM_RTS : 0) |
457 (acm->ctrlin & ACM_CTRL_DSR ? TIOCM_DSR : 0) |
458 (acm->ctrlin & ACM_CTRL_RI ? TIOCM_RI : 0) |
459 (acm->ctrlin & ACM_CTRL_DCD ? TIOCM_CD : 0) |
463 static int acm_tty_tiocmset(struct tty_struct *tty, struct file *file,
464 unsigned int set, unsigned int clear)
466 struct acm *acm = tty->driver_data;
467 unsigned int newctrl;
472 newctrl = acm->ctrlout;
473 set = (set & TIOCM_DTR ? ACM_CTRL_DTR : 0) | (set & TIOCM_RTS ? ACM_CTRL_RTS : 0);
474 clear = (clear & TIOCM_DTR ? ACM_CTRL_DTR : 0) | (clear & TIOCM_RTS ? ACM_CTRL_RTS : 0);
476 newctrl = (newctrl & ~clear) | set;
478 if (acm->ctrlout == newctrl)
480 return acm_set_control(acm, acm->ctrlout = newctrl);
483 static int acm_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
485 struct acm *acm = tty->driver_data;
493 static __u32 acm_tty_speed[] = {
494 0, 50, 75, 110, 134, 150, 200, 300, 600,
495 1200, 1800, 2400, 4800, 9600, 19200, 38400,
496 57600, 115200, 230400, 460800, 500000, 576000,
497 921600, 1000000, 1152000, 1500000, 2000000,
498 2500000, 3000000, 3500000, 4000000
501 static __u8 acm_tty_size[] = {
505 static void acm_tty_set_termios(struct tty_struct *tty, struct termios *termios_old)
507 struct acm *acm = tty->driver_data;
508 struct termios *termios = tty->termios;
509 struct acm_line newline;
510 int newctrl = acm->ctrlout;
515 newline.speed = cpu_to_le32p(acm_tty_speed +
516 (termios->c_cflag & CBAUD & ~CBAUDEX) + (termios->c_cflag & CBAUDEX ? 15 : 0));
517 newline.stopbits = termios->c_cflag & CSTOPB ? 2 : 0;
518 newline.parity = termios->c_cflag & PARENB ?
519 (termios->c_cflag & PARODD ? 1 : 2) + (termios->c_cflag & CMSPAR ? 2 : 0) : 0;
520 newline.databits = acm_tty_size[(termios->c_cflag & CSIZE) >> 4];
522 acm->clocal = ((termios->c_cflag & CLOCAL) != 0);
524 if (!newline.speed) {
525 newline.speed = acm->line.speed;
526 newctrl &= ~ACM_CTRL_DTR;
527 } else newctrl |= ACM_CTRL_DTR;
529 if (newctrl != acm->ctrlout)
530 acm_set_control(acm, acm->ctrlout = newctrl);
532 if (memcmp(&acm->line, &newline, sizeof(struct acm_line))) {
533 memcpy(&acm->line, &newline, sizeof(struct acm_line));
534 dbg("set line: %d %d %d %d", newline.speed, newline.stopbits, newline.parity, newline.databits);
535 acm_set_line(acm, &acm->line);
540 * USB probe and disconnect routines.
543 static int acm_probe (struct usb_interface *intf,
544 const struct usb_device_id *id)
546 struct usb_device *dev;
548 struct usb_host_config *cfacm;
549 struct usb_host_interface *ifcom, *ifdata;
550 struct usb_endpoint_descriptor *epctrl, *epread, *epwrite;
551 int readsize, ctrlsize, minor, i, j;
554 dev = interface_to_usbdev (intf);
555 for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
557 cfacm = dev->config + i;
559 dbg("probing config %d", cfacm->desc.bConfigurationValue);
561 for (j = 0; j < cfacm->desc.bNumInterfaces - 1; j++) {
563 if (usb_interface_claimed(cfacm->interface + j) ||
564 usb_interface_claimed(cfacm->interface + j + 1))
567 ifcom = cfacm->interface[j].altsetting + 0;
568 ifdata = cfacm->interface[j + 1].altsetting + 0;
570 if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2) {
571 ifcom = cfacm->interface[j + 1].altsetting + 0;
572 ifdata = cfacm->interface[j].altsetting + 0;
573 if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2)
577 if (ifcom->desc.bInterfaceClass != 2 || ifcom->desc.bInterfaceSubClass != 2 ||
578 ifcom->desc.bInterfaceProtocol < 1 || ifcom->desc.bInterfaceProtocol > 6 ||
579 ifcom->desc.bNumEndpoints < 1)
582 epctrl = &ifcom->endpoint[0].desc;
583 epread = &ifdata->endpoint[0].desc;
584 epwrite = &ifdata->endpoint[1].desc;
586 if ((epctrl->bEndpointAddress & 0x80) != 0x80 || (epctrl->bmAttributes & 3) != 3 ||
587 (epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes & 3) != 2 ||
588 ((epread->bEndpointAddress & 0x80) ^ (epwrite->bEndpointAddress & 0x80)) != 0x80)
591 if ((epread->bEndpointAddress & 0x80) != 0x80) {
592 epread = &ifdata->endpoint[1].desc;
593 epwrite = &ifdata->endpoint[0].desc;
596 usb_set_configuration(dev, cfacm->desc.bConfigurationValue);
598 for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
599 if (acm_table[minor]) {
600 err("no more free acm devices");
604 if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) {
605 err("out of memory");
608 memset(acm, 0, sizeof(struct acm));
610 ctrlsize = epctrl->wMaxPacketSize;
611 readsize = epread->wMaxPacketSize;
612 acm->writesize = epwrite->wMaxPacketSize;
613 acm->iface = cfacm->interface + j;
617 INIT_WORK(&acm->work, acm_softint, acm);
619 if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
620 err("out of memory");
625 acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
627 err("out of memory");
632 acm->readurb = usb_alloc_urb(0, GFP_KERNEL);
634 err("out of memory");
635 usb_free_urb(acm->ctrlurb);
640 acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
641 if (!acm->writeurb) {
642 err("out of memory");
643 usb_free_urb(acm->readurb);
644 usb_free_urb(acm->ctrlurb);
650 usb_fill_int_urb(acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress),
651 buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
653 usb_fill_bulk_urb(acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
654 buf += ctrlsize, readsize, acm_read_bulk, acm);
655 acm->readurb->transfer_flags |= URB_NO_FSBR;
657 usb_fill_bulk_urb(acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
658 buf += readsize, acm->writesize, acm_write_bulk, acm);
659 acm->writeurb->transfer_flags |= URB_NO_FSBR;
661 info("ttyACM%d: USB ACM device", minor);
663 acm_set_control(acm, acm->ctrlout);
665 acm->line.speed = cpu_to_le32(9600);
666 acm->line.databits = 8;
667 acm_set_line(acm, &acm->line);
669 usb_driver_claim_interface(&acm_driver, acm->iface + 0, acm);
670 usb_driver_claim_interface(&acm_driver, acm->iface + 1, acm);
672 tty_register_device(acm_tty_driver, minor, &intf->dev);
674 acm_table[minor] = acm;
675 usb_set_intfdata (intf, acm);
683 static void acm_disconnect(struct usb_interface *intf)
685 struct acm *acm = usb_get_intfdata (intf);
687 if (!acm || !acm->dev) {
688 dbg("disconnect on nonexisting interface");
693 usb_set_intfdata (intf, NULL);
695 usb_unlink_urb(acm->ctrlurb);
696 usb_unlink_urb(acm->readurb);
697 usb_unlink_urb(acm->writeurb);
699 kfree(acm->ctrlurb->transfer_buffer);
701 usb_driver_release_interface(&acm_driver, acm->iface + 0);
702 usb_driver_release_interface(&acm_driver, acm->iface + 1);
705 tty_unregister_device(acm_tty_driver, acm->minor);
706 acm_table[acm->minor] = NULL;
707 usb_free_urb(acm->ctrlurb);
708 usb_free_urb(acm->readurb);
709 usb_free_urb(acm->writeurb);
715 tty_hangup(acm->tty);
719 * USB driver structure.
722 static struct usb_device_id acm_ids[] = {
723 { USB_DEVICE_INFO(USB_CLASS_COMM, 0, 0) },
724 { USB_DEVICE_INFO(USB_CLASS_COMM, 2, 0) },
728 MODULE_DEVICE_TABLE (usb, acm_ids);
730 static struct usb_driver acm_driver = {
731 .owner = THIS_MODULE,
734 .disconnect = acm_disconnect,
739 * TTY driver structures.
742 static struct tty_operations acm_ops = {
743 .open = acm_tty_open,
744 .close = acm_tty_close,
745 .write = acm_tty_write,
746 .write_room = acm_tty_write_room,
747 .ioctl = acm_tty_ioctl,
748 .throttle = acm_tty_throttle,
749 .unthrottle = acm_tty_unthrottle,
750 .chars_in_buffer = acm_tty_chars_in_buffer,
751 .break_ctl = acm_tty_break_ctl,
752 .set_termios = acm_tty_set_termios,
753 .tiocmget = acm_tty_tiocmget,
754 .tiocmset = acm_tty_tiocmset,
761 static int __init acm_init(void)
763 acm_tty_driver = alloc_tty_driver(ACM_TTY_MINORS);
766 acm_tty_driver->owner = THIS_MODULE,
767 acm_tty_driver->driver_name = "acm",
768 acm_tty_driver->name = "ttyACM",
769 acm_tty_driver->devfs_name = "usb/acm/",
770 acm_tty_driver->major = ACM_TTY_MAJOR,
771 acm_tty_driver->minor_start = 0,
772 acm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL,
773 acm_tty_driver->subtype = SERIAL_TYPE_NORMAL,
774 acm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
775 acm_tty_driver->init_termios = tty_std_termios;
776 acm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
777 tty_set_operations(acm_tty_driver, &acm_ops);
779 if (tty_register_driver(acm_tty_driver)) {
780 put_tty_driver(acm_tty_driver);
784 if (usb_register(&acm_driver) < 0) {
785 tty_unregister_driver(acm_tty_driver);
786 put_tty_driver(acm_tty_driver);
790 info(DRIVER_VERSION ":" DRIVER_DESC);
795 static void __exit acm_exit(void)
797 usb_deregister(&acm_driver);
798 tty_unregister_driver(acm_tty_driver);
799 put_tty_driver(acm_tty_driver);
802 module_init(acm_init);
803 module_exit(acm_exit);
805 MODULE_AUTHOR( DRIVER_AUTHOR );
806 MODULE_DESCRIPTION( DRIVER_DESC );
807 MODULE_LICENSE("GPL");