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
27 * v0.22 - probe only the control interface. if usbcore doesn't choose the
28 * config we want, sysadmin changes bConfigurationValue in sysfs.
29 * v0.23 - use softirq for rx processing, as needed by tty layer
33 * This program is free software; you can redistribute it and/or modify
34 * it under the terms of the GNU General Public License as published by
35 * the Free Software Foundation; either version 2 of the License, or
36 * (at your option) any later version.
38 * This program is distributed in the hope that it will be useful,
39 * but WITHOUT ANY WARRANTY; without even the implied warranty of
40 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41 * GNU General Public License for more details.
43 * You should have received a copy of the GNU General Public License
44 * along with this program; if not, write to the Free Software
45 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
50 #include <linux/kernel.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/tty.h>
55 #include <linux/tty_driver.h>
56 #include <linux/tty_flip.h>
57 #include <linux/module.h>
58 #include <linux/smp_lock.h>
59 #include <asm/uaccess.h>
60 #include <linux/usb.h>
61 #include <asm/byteorder.h>
66 #define DRIVER_VERSION "v0.23"
67 #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik"
68 #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
71 * CMSPAR, some architectures can't have space and mark parity.
79 * Major and minor numbers.
82 #define ACM_TTY_MAJOR 166
83 #define ACM_TTY_MINORS 32
89 #define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
91 #define ACM_REQ_COMMAND 0x00
92 #define ACM_REQ_RESPONSE 0x01
93 #define ACM_REQ_SET_FEATURE 0x02
94 #define ACM_REQ_GET_FEATURE 0x03
95 #define ACM_REQ_CLEAR_FEATURE 0x04
97 #define ACM_REQ_SET_LINE 0x20
98 #define ACM_REQ_GET_LINE 0x21
99 #define ACM_REQ_SET_CONTROL 0x22
100 #define ACM_REQ_SEND_BREAK 0x23
106 #define ACM_IRQ_NETWORK 0x00
107 #define ACM_IRQ_LINE_STATE 0x20
110 * Output control lines.
113 #define ACM_CTRL_DTR 0x01
114 #define ACM_CTRL_RTS 0x02
117 * Input control lines and line errors.
120 #define ACM_CTRL_DCD 0x01
121 #define ACM_CTRL_DSR 0x02
122 #define ACM_CTRL_BRK 0x04
123 #define ACM_CTRL_RI 0x08
125 #define ACM_CTRL_FRAMING 0x10
126 #define ACM_CTRL_PARITY 0x20
127 #define ACM_CTRL_OVERRUN 0x40
130 * Line speed and caracter encoding.
138 } __attribute__ ((packed));
141 * Internal driver structures.
145 struct usb_device *dev; /* the corresponding usb device */
146 struct usb_interface *control; /* control interface */
147 struct usb_interface *data; /* data interface */
148 struct tty_struct *tty; /* the corresponding tty */
149 struct urb *ctrlurb, *readurb, *writeurb; /* urbs */
150 struct acm_line line; /* line coding (bits, stop, parity) */
151 struct work_struct work; /* work queue entry for line discipline waking up */
152 struct tasklet_struct bh; /* rx processing */
153 unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */
154 unsigned int ctrlout; /* output control lines (DTR, RTS) */
155 unsigned int writesize; /* max packet size for the output bulk endpoint */
156 unsigned int used; /* someone has this acm's device open */
157 unsigned int minor; /* acm minor number */
158 unsigned char throttle; /* throttled by tty layer */
159 unsigned char clocal; /* termios CLOCAL */
162 static struct usb_driver acm_driver;
163 static struct tty_driver *acm_tty_driver;
164 static struct acm *acm_table[ACM_TTY_MINORS];
166 #define ACM_READY(acm) (acm && acm->dev && acm->used)
169 * Functions for ACM control messages.
172 static int acm_ctrl_msg(struct acm *acm, int request, int value, void *buf, int len)
174 int retval = usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0),
175 request, USB_RT_ACM, value,
176 acm->control->altsetting[0].desc.bInterfaceNumber,
178 dbg("acm_control_msg: rq: 0x%02x val: %#x len: %#x result: %d", request, value, len, retval);
179 return retval < 0 ? retval : 0;
182 /* devices aren't required to support these requests.
183 * the cdc acm descriptor tells whether they do...
185 #define acm_set_control(acm, control) acm_ctrl_msg(acm, ACM_REQ_SET_CONTROL, control, NULL, 0)
186 #define acm_set_line(acm, line) acm_ctrl_msg(acm, ACM_REQ_SET_LINE, 0, line, sizeof(struct acm_line))
187 #define acm_send_break(acm, ms) acm_ctrl_msg(acm, ACM_REQ_SEND_BREAK, ms, NULL, 0)
190 * Interrupt handlers for various ACM device responses
193 /* control interface reports status changes with "interrupt" transfers */
194 static void acm_ctrl_irq(struct urb *urb, struct pt_regs *regs)
196 struct acm *acm = urb->context;
197 struct usb_ctrlrequest *dr = urb->transfer_buffer;
198 unsigned char *data = (unsigned char *)(dr + 1);
202 switch (urb->status) {
209 /* this urb is terminated, clean up */
210 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
213 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
220 switch (dr->bRequest) {
222 case ACM_IRQ_NETWORK:
224 dbg("%s network", dr->wValue ? "connected to" : "disconnected from");
227 case ACM_IRQ_LINE_STATE:
229 newctrl = le16_to_cpup((__u16 *) data);
231 if (acm->tty && !acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
232 dbg("calling hangup");
233 tty_hangup(acm->tty);
236 acm->ctrlin = newctrl;
238 dbg("input control lines: dcd%c dsr%c break%c ring%c framing%c parity%c overrun%c",
239 acm->ctrlin & ACM_CTRL_DCD ? '+' : '-', acm->ctrlin & ACM_CTRL_DSR ? '+' : '-',
240 acm->ctrlin & ACM_CTRL_BRK ? '+' : '-', acm->ctrlin & ACM_CTRL_RI ? '+' : '-',
241 acm->ctrlin & ACM_CTRL_FRAMING ? '+' : '-', acm->ctrlin & ACM_CTRL_PARITY ? '+' : '-',
242 acm->ctrlin & ACM_CTRL_OVERRUN ? '+' : '-');
247 dbg("unknown control event received: request %d index %d len %d data0 %d data1 %d",
248 dr->bRequest, dr->wIndex, dr->wLength, data[0], data[1]);
252 status = usb_submit_urb (urb, GFP_ATOMIC);
254 err ("%s - usb_submit_urb failed with result %d",
255 __FUNCTION__, status);
258 /* data interface returns incoming bytes, or we got unthrottled */
259 static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
261 struct acm *acm = urb->context;
267 dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status);
269 /* calling tty_flip_buffer_push() in_irq() isn't allowed */
270 tasklet_schedule(&acm->bh);
273 static void acm_rx_tasklet(unsigned long _acm)
275 struct acm *acm = (void *)_acm;
276 struct urb *urb = acm->readurb;
277 struct tty_struct *tty = acm->tty;
278 unsigned char *data = urb->transfer_buffer;
281 if (urb->actual_length > 0 && !acm->throttle) {
282 for (i = 0; i < urb->actual_length && !acm->throttle; i++) {
283 /* if we insert more than TTY_FLIPBUF_SIZE characters,
285 if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
286 tty_flip_buffer_push(tty);
288 tty_insert_flip_char(tty, data[i], 0);
290 tty_flip_buffer_push(tty);
294 memmove(data, data + i, urb->actual_length - i);
295 urb->actual_length -= i;
299 urb->actual_length = 0;
302 i = usb_submit_urb(urb, GFP_ATOMIC);
304 dev_dbg(&acm->data->dev, "bulk rx resubmit %d\n", i);
307 /* data interface wrote those outgoing bytes */
308 static void acm_write_bulk(struct urb *urb, struct pt_regs *regs)
310 struct acm *acm = (struct acm *)urb->context;
316 dbg("nonzero write bulk status received: %d", urb->status);
318 schedule_work(&acm->work);
321 static void acm_softint(void *private)
323 struct acm *acm = private;
324 struct tty_struct *tty = acm->tty;
329 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
330 (tty->ldisc.write_wakeup)(tty);
332 wake_up_interruptible(&tty->write_wait);
339 static int acm_tty_open(struct tty_struct *tty, struct file *filp)
341 struct acm *acm = acm_table[tty->index];
343 if (!acm || !acm->dev)
346 tty->driver_data = acm;
358 acm->ctrlurb->dev = acm->dev;
359 if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL))
360 dbg("usb_submit_urb(ctrl irq) failed");
362 acm->readurb->dev = acm->dev;
363 if (usb_submit_urb(acm->readurb, GFP_KERNEL))
364 dbg("usb_submit_urb(read bulk) failed");
366 acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS);
368 /* force low_latency on so that our tty_push actually forces the data through,
369 otherwise it is scheduled, and with high data rates data can get lost. */
370 tty->low_latency = 1;
375 static void acm_tty_close(struct tty_struct *tty, struct file *filp)
377 struct acm *acm = tty->driver_data;
379 if (!acm || !acm->used)
384 acm_set_control(acm, acm->ctrlout = 0);
385 usb_unlink_urb(acm->ctrlurb);
386 usb_unlink_urb(acm->writeurb);
387 usb_unlink_urb(acm->readurb);
389 tty_unregister_device(acm_tty_driver, acm->minor);
390 acm_table[acm->minor] = NULL;
391 usb_free_urb(acm->ctrlurb);
392 usb_free_urb(acm->readurb);
393 usb_free_urb(acm->writeurb);
399 static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
401 struct acm *acm = tty->driver_data;
406 if (acm->writeurb->status == -EINPROGRESS)
411 count = (count > acm->writesize) ? acm->writesize : count;
414 if (copy_from_user(acm->writeurb->transfer_buffer, (void __user *)buf, count))
417 memcpy(acm->writeurb->transfer_buffer, buf, count);
419 acm->writeurb->transfer_buffer_length = count;
420 acm->writeurb->dev = acm->dev;
422 /* GFP_KERNEL probably works if from_user */
423 stat = usb_submit_urb(acm->writeurb, GFP_ATOMIC);
425 dbg("usb_submit_urb(write bulk) failed");
432 static int acm_tty_write_room(struct tty_struct *tty)
434 struct acm *acm = tty->driver_data;
437 return acm->writeurb->status == -EINPROGRESS ? 0 : acm->writesize;
440 static int acm_tty_chars_in_buffer(struct tty_struct *tty)
442 struct acm *acm = tty->driver_data;
445 return acm->writeurb->status == -EINPROGRESS ? acm->writeurb->transfer_buffer_length : 0;
448 static void acm_tty_throttle(struct tty_struct *tty)
450 struct acm *acm = tty->driver_data;
456 static void acm_tty_unthrottle(struct tty_struct *tty)
458 struct acm *acm = tty->driver_data;
462 if (acm->readurb->status != -EINPROGRESS)
463 acm_read_bulk(acm->readurb, NULL);
466 static void acm_tty_break_ctl(struct tty_struct *tty, int state)
468 struct acm *acm = tty->driver_data;
471 if (acm_send_break(acm, state ? 0xffff : 0))
472 dbg("send break failed");
475 static int acm_tty_tiocmget(struct tty_struct *tty, struct file *file)
477 struct acm *acm = tty->driver_data;
482 return (acm->ctrlout & ACM_CTRL_DTR ? TIOCM_DTR : 0) |
483 (acm->ctrlout & ACM_CTRL_RTS ? TIOCM_RTS : 0) |
484 (acm->ctrlin & ACM_CTRL_DSR ? TIOCM_DSR : 0) |
485 (acm->ctrlin & ACM_CTRL_RI ? TIOCM_RI : 0) |
486 (acm->ctrlin & ACM_CTRL_DCD ? TIOCM_CD : 0) |
490 static int acm_tty_tiocmset(struct tty_struct *tty, struct file *file,
491 unsigned int set, unsigned int clear)
493 struct acm *acm = tty->driver_data;
494 unsigned int newctrl;
499 newctrl = acm->ctrlout;
500 set = (set & TIOCM_DTR ? ACM_CTRL_DTR : 0) | (set & TIOCM_RTS ? ACM_CTRL_RTS : 0);
501 clear = (clear & TIOCM_DTR ? ACM_CTRL_DTR : 0) | (clear & TIOCM_RTS ? ACM_CTRL_RTS : 0);
503 newctrl = (newctrl & ~clear) | set;
505 if (acm->ctrlout == newctrl)
507 return acm_set_control(acm, acm->ctrlout = newctrl);
510 static int acm_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
512 struct acm *acm = tty->driver_data;
520 static __u32 acm_tty_speed[] = {
521 0, 50, 75, 110, 134, 150, 200, 300, 600,
522 1200, 1800, 2400, 4800, 9600, 19200, 38400,
523 57600, 115200, 230400, 460800, 500000, 576000,
524 921600, 1000000, 1152000, 1500000, 2000000,
525 2500000, 3000000, 3500000, 4000000
528 static __u8 acm_tty_size[] = {
532 static void acm_tty_set_termios(struct tty_struct *tty, struct termios *termios_old)
534 struct acm *acm = tty->driver_data;
535 struct termios *termios = tty->termios;
536 struct acm_line newline;
537 int newctrl = acm->ctrlout;
542 newline.speed = cpu_to_le32p(acm_tty_speed +
543 (termios->c_cflag & CBAUD & ~CBAUDEX) + (termios->c_cflag & CBAUDEX ? 15 : 0));
544 newline.stopbits = termios->c_cflag & CSTOPB ? 2 : 0;
545 newline.parity = termios->c_cflag & PARENB ?
546 (termios->c_cflag & PARODD ? 1 : 2) + (termios->c_cflag & CMSPAR ? 2 : 0) : 0;
547 newline.databits = acm_tty_size[(termios->c_cflag & CSIZE) >> 4];
549 acm->clocal = ((termios->c_cflag & CLOCAL) != 0);
551 if (!newline.speed) {
552 newline.speed = acm->line.speed;
553 newctrl &= ~ACM_CTRL_DTR;
554 } else newctrl |= ACM_CTRL_DTR;
556 if (newctrl != acm->ctrlout)
557 acm_set_control(acm, acm->ctrlout = newctrl);
559 if (memcmp(&acm->line, &newline, sizeof(struct acm_line))) {
560 memcpy(&acm->line, &newline, sizeof(struct acm_line));
561 dbg("set line: %d %d %d %d", newline.speed, newline.stopbits, newline.parity, newline.databits);
562 acm_set_line(acm, &acm->line);
567 * USB probe and disconnect routines.
570 static int acm_probe (struct usb_interface *intf,
571 const struct usb_device_id *id)
573 struct usb_device *dev;
575 struct usb_host_config *cfacm;
576 struct usb_interface *data = NULL;
577 struct usb_host_interface *ifcom, *ifdata = NULL;
578 struct usb_endpoint_descriptor *epctrl = NULL;
579 struct usb_endpoint_descriptor *epread = NULL;
580 struct usb_endpoint_descriptor *epwrite = NULL;
581 int readsize, ctrlsize, minor, j;
584 dev = interface_to_usbdev (intf);
586 cfacm = dev->actconfig;
588 /* We know we're probe()d with the control interface. */
589 ifcom = intf->cur_altsetting;
591 /* ACM doesn't guarantee the data interface is
592 * adjacent to the control interface, or that if one
593 * is there it's not for call management ... so find
596 for (j = 0; j < cfacm->desc.bNumInterfaces; j++) {
597 ifdata = cfacm->interface[j]->cur_altsetting;
598 data = cfacm->interface[j];
600 if (ifdata->desc.bInterfaceClass == 10 &&
601 ifdata->desc.bNumEndpoints == 2) {
602 epctrl = &ifcom->endpoint[0].desc;
603 epread = &ifdata->endpoint[0].desc;
604 epwrite = &ifdata->endpoint[1].desc;
606 if ((epctrl->bEndpointAddress & 0x80) != 0x80 ||
607 (epctrl->bmAttributes & 3) != 3 ||
608 (epread->bmAttributes & 3) != 2 ||
609 (epwrite->bmAttributes & 3) != 2 ||
610 ((epread->bEndpointAddress & 0x80) ^ (epwrite->bEndpointAddress & 0x80)) != 0x80)
613 if ((epread->bEndpointAddress & 0x80) != 0x80) {
614 epread = &ifdata->endpoint[1].desc;
615 epwrite = &ifdata->endpoint[0].desc;
617 dbg("found data interface at %d\n", j);
626 /* there's been a problem */
628 dbg("interface not found (%p)\n", ifdata);
633 for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
634 if (acm_table[minor]) {
635 err("no more free acm devices");
639 if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) {
640 err("out of memory");
643 memset(acm, 0, sizeof(struct acm));
645 ctrlsize = epctrl->wMaxPacketSize;
646 readsize = epread->wMaxPacketSize;
647 acm->writesize = epwrite->wMaxPacketSize;
653 acm->bh.func = acm_rx_tasklet;
654 acm->bh.data = (unsigned long) acm;
655 INIT_WORK(&acm->work, acm_softint, acm);
657 if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
658 err("out of memory");
663 acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
665 err("out of memory");
670 acm->readurb = usb_alloc_urb(0, GFP_KERNEL);
672 err("out of memory");
673 usb_free_urb(acm->ctrlurb);
678 acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
679 if (!acm->writeurb) {
680 err("out of memory");
681 usb_free_urb(acm->readurb);
682 usb_free_urb(acm->ctrlurb);
688 usb_fill_int_urb(acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress),
689 buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
691 usb_fill_bulk_urb(acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
692 buf += ctrlsize, readsize, acm_read_bulk, acm);
693 acm->readurb->transfer_flags |= URB_NO_FSBR;
695 usb_fill_bulk_urb(acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
696 buf += readsize, acm->writesize, acm_write_bulk, acm);
697 acm->writeurb->transfer_flags |= URB_NO_FSBR;
699 dev_info(&intf->dev, "ttyACM%d: USB ACM device", minor);
701 acm_set_control(acm, acm->ctrlout);
703 acm->line.speed = cpu_to_le32(9600);
704 acm->line.databits = 8;
705 acm_set_line(acm, &acm->line);
707 if ( (j = usb_driver_claim_interface(&acm_driver, data, acm)) != 0) {
709 usb_free_urb(acm->ctrlurb);
710 usb_free_urb(acm->readurb);
711 usb_free_urb(acm->writeurb);
717 tty_register_device(acm_tty_driver, minor, &intf->dev);
719 acm_table[minor] = acm;
720 usb_set_intfdata (intf, acm);
724 static void acm_disconnect(struct usb_interface *intf)
726 struct acm *acm = usb_get_intfdata (intf);
728 if (!acm || !acm->dev) {
729 dbg("disconnect on nonexisting interface");
734 usb_set_intfdata (intf, NULL);
736 usb_unlink_urb(acm->ctrlurb);
737 usb_unlink_urb(acm->readurb);
738 usb_unlink_urb(acm->writeurb);
740 kfree(acm->ctrlurb->transfer_buffer);
742 usb_driver_release_interface(&acm_driver, acm->data);
745 tty_unregister_device(acm_tty_driver, acm->minor);
746 acm_table[acm->minor] = NULL;
747 usb_free_urb(acm->ctrlurb);
748 usb_free_urb(acm->readurb);
749 usb_free_urb(acm->writeurb);
755 tty_hangup(acm->tty);
759 * USB driver structure.
762 static struct usb_device_id acm_ids[] = {
763 /* control interfaces with various AT-command sets */
764 { USB_INTERFACE_INFO(USB_CLASS_COMM, 2, 1) },
765 { USB_INTERFACE_INFO(USB_CLASS_COMM, 2, 2) },
766 { USB_INTERFACE_INFO(USB_CLASS_COMM, 2, 3) },
767 { USB_INTERFACE_INFO(USB_CLASS_COMM, 2, 4) },
768 { USB_INTERFACE_INFO(USB_CLASS_COMM, 2, 5) },
769 { USB_INTERFACE_INFO(USB_CLASS_COMM, 2, 6) },
771 /* NOTE: COMM/2/0xff is likely MSFT RNDIS ... NOT a modem!! */
775 MODULE_DEVICE_TABLE (usb, acm_ids);
777 static struct usb_driver acm_driver = {
778 .owner = THIS_MODULE,
781 .disconnect = acm_disconnect,
786 * TTY driver structures.
789 static struct tty_operations acm_ops = {
790 .open = acm_tty_open,
791 .close = acm_tty_close,
792 .write = acm_tty_write,
793 .write_room = acm_tty_write_room,
794 .ioctl = acm_tty_ioctl,
795 .throttle = acm_tty_throttle,
796 .unthrottle = acm_tty_unthrottle,
797 .chars_in_buffer = acm_tty_chars_in_buffer,
798 .break_ctl = acm_tty_break_ctl,
799 .set_termios = acm_tty_set_termios,
800 .tiocmget = acm_tty_tiocmget,
801 .tiocmset = acm_tty_tiocmset,
808 static int __init acm_init(void)
811 acm_tty_driver = alloc_tty_driver(ACM_TTY_MINORS);
814 acm_tty_driver->owner = THIS_MODULE,
815 acm_tty_driver->driver_name = "acm",
816 acm_tty_driver->name = "ttyACM",
817 acm_tty_driver->devfs_name = "usb/acm/",
818 acm_tty_driver->major = ACM_TTY_MAJOR,
819 acm_tty_driver->minor_start = 0,
820 acm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL,
821 acm_tty_driver->subtype = SERIAL_TYPE_NORMAL,
822 acm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
823 acm_tty_driver->init_termios = tty_std_termios;
824 acm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
825 tty_set_operations(acm_tty_driver, &acm_ops);
827 retval = tty_register_driver(acm_tty_driver);
829 put_tty_driver(acm_tty_driver);
833 retval = usb_register(&acm_driver);
835 tty_unregister_driver(acm_tty_driver);
836 put_tty_driver(acm_tty_driver);
840 info(DRIVER_VERSION ":" DRIVER_DESC);
845 static void __exit acm_exit(void)
847 usb_deregister(&acm_driver);
848 tty_unregister_driver(acm_tty_driver);
849 put_tty_driver(acm_tty_driver);
852 module_init(acm_init);
853 module_exit(acm_exit);
855 MODULE_AUTHOR( DRIVER_AUTHOR );
856 MODULE_DESCRIPTION( DRIVER_DESC );
857 MODULE_LICENSE("GPL");