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/sched.h>
47 #include <linux/signal.h>
48 #include <linux/errno.h>
49 #include <linux/poll.h>
50 #include <linux/init.h>
51 #include <linux/slab.h>
52 #include <linux/fcntl.h>
53 #include <linux/tty.h>
54 #include <linux/tty_driver.h>
55 #include <linux/tty_flip.h>
56 #include <linux/module.h>
57 #include <linux/smp_lock.h>
59 #include <linux/usb.h>
64 #define DRIVER_VERSION "v0.21"
65 #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik"
66 #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
69 * CMSPAR, some architectures can't have space and mark parity.
77 * Major and minor numbers.
80 #define ACM_TTY_MAJOR 166
81 #define ACM_TTY_MINORS 32
87 #define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
89 #define ACM_REQ_COMMAND 0x00
90 #define ACM_REQ_RESPONSE 0x01
91 #define ACM_REQ_SET_FEATURE 0x02
92 #define ACM_REQ_GET_FEATURE 0x03
93 #define ACM_REQ_CLEAR_FEATURE 0x04
95 #define ACM_REQ_SET_LINE 0x20
96 #define ACM_REQ_GET_LINE 0x21
97 #define ACM_REQ_SET_CONTROL 0x22
98 #define ACM_REQ_SEND_BREAK 0x23
104 #define ACM_IRQ_NETWORK 0x00
105 #define ACM_IRQ_LINE_STATE 0x20
108 * Output control lines.
111 #define ACM_CTRL_DTR 0x01
112 #define ACM_CTRL_RTS 0x02
115 * Input control lines and line errors.
118 #define ACM_CTRL_DCD 0x01
119 #define ACM_CTRL_DSR 0x02
120 #define ACM_CTRL_BRK 0x04
121 #define ACM_CTRL_RI 0x08
123 #define ACM_CTRL_FRAMING 0x10
124 #define ACM_CTRL_PARITY 0x20
125 #define ACM_CTRL_OVERRUN 0x40
128 * Line speed and caracter encoding.
136 } __attribute__ ((packed));
139 * Internal driver structures.
143 struct usb_device *dev; /* the coresponding usb device */
144 struct usb_interface *iface; /* the interfaces - +0 control +1 data */
145 struct tty_struct *tty; /* the coresponding tty */
146 struct urb ctrlurb, readurb, writeurb; /* urbs */
147 struct acm_line line; /* line coding (bits, stop, parity) */
148 struct tq_struct tqueue; /* task queue for line discipline waking up */
149 unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */
150 unsigned int ctrlout; /* output control lines (DTR, RTS) */
151 unsigned int writesize; /* max packet size for the output bulk endpoint */
152 unsigned int used; /* someone has this acm's device open */
153 unsigned int minor; /* acm minor number */
154 unsigned char throttle; /* throttled by tty layer */
155 unsigned char clocal; /* termios CLOCAL */
158 static struct usb_driver acm_driver;
159 static struct tty_driver acm_tty_driver;
160 static struct acm *acm_table[ACM_TTY_MINORS];
162 #define ACM_READY(acm) (acm && acm->dev && acm->used)
165 * Functions for ACM control messages.
168 static int acm_ctrl_msg(struct acm *acm, int request, int value, void *buf, int len)
170 int retval = usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0),
171 request, USB_RT_ACM, value, acm->iface[0].altsetting[0].bInterfaceNumber, buf, len, HZ * 5);
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)
186 struct acm *acm = urb->context;
187 struct usb_ctrlrequest *dr = urb->transfer_buffer;
188 unsigned char *data = (unsigned char *)(dr + 1);
191 if (!ACM_READY(acm)) return;
193 if (urb->status < 0) {
194 dbg("nonzero ctrl irq status received: %d", urb->status);
198 switch (dr->bRequest) {
200 case ACM_IRQ_NETWORK:
202 dbg("%s network", data[0] ? "connected to" : "disconnected from");
205 case ACM_IRQ_LINE_STATE:
207 newctrl = le16_to_cpup((__u16 *) data);
209 if (acm->tty && !acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
210 dbg("calling hangup");
211 tty_hangup(acm->tty);
214 acm->ctrlin = newctrl;
216 dbg("input control lines: dcd%c dsr%c break%c ring%c framing%c parity%c overrun%c",
217 acm->ctrlin & ACM_CTRL_DCD ? '+' : '-', acm->ctrlin & ACM_CTRL_DSR ? '+' : '-',
218 acm->ctrlin & ACM_CTRL_BRK ? '+' : '-', acm->ctrlin & ACM_CTRL_RI ? '+' : '-',
219 acm->ctrlin & ACM_CTRL_FRAMING ? '+' : '-', acm->ctrlin & ACM_CTRL_PARITY ? '+' : '-',
220 acm->ctrlin & ACM_CTRL_OVERRUN ? '+' : '-');
225 dbg("unknown control event received: request %d index %d len %d data0 %d data1 %d",
226 dr->bRequest, dr->wIndex, dr->wLength, data[0], data[1]);
231 static void acm_read_bulk(struct urb *urb)
233 struct acm *acm = urb->context;
234 struct tty_struct *tty = acm->tty;
235 unsigned char *data = urb->transfer_buffer;
238 if (!ACM_READY(acm)) return;
241 dbg("nonzero read bulk status received: %d", urb->status);
243 if (!urb->status && !acm->throttle) {
244 for (i = 0; i < urb->actual_length && !acm->throttle; i++) {
245 /* if we insert more than TTY_FLIPBUF_SIZE characters,
247 if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
248 tty_flip_buffer_push(tty);
250 tty_insert_flip_char(tty, data[i], 0);
252 tty_flip_buffer_push(tty);
256 memmove(data, data + i, urb->actual_length - i);
257 urb->actual_length -= i;
261 urb->actual_length = 0;
264 if (usb_submit_urb(urb))
265 dbg("failed resubmitting read urb");
268 static void acm_write_bulk(struct urb *urb)
270 struct acm *acm = (struct acm *)urb->context;
272 if (!ACM_READY(acm)) return;
275 dbg("nonzero write bulk status received: %d", urb->status);
277 queue_task(&acm->tqueue, &tq_immediate);
278 mark_bh(IMMEDIATE_BH);
281 static void acm_softint(void *private)
283 struct acm *acm = private;
284 struct tty_struct *tty = acm->tty;
286 if (!ACM_READY(acm)) return;
295 static int acm_tty_open(struct tty_struct *tty, struct file *filp)
297 struct acm *acm = acm_table[MINOR(tty->device)];
299 if (!acm || !acm->dev) return -EINVAL;
301 tty->driver_data = acm;
315 acm->ctrlurb.dev = acm->dev;
316 if (usb_submit_urb(&acm->ctrlurb))
317 dbg("usb_submit_urb(ctrl irq) failed");
319 acm->readurb.dev = acm->dev;
320 if (usb_submit_urb(&acm->readurb))
321 dbg("usb_submit_urb(read bulk) failed");
323 acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS);
325 /* force low_latency on so that our tty_push actually forces the data through,
326 otherwise it is scheduled, and with high data rates data can get lost. */
327 tty->low_latency = 1;
332 static void acm_tty_close(struct tty_struct *tty, struct file *filp)
334 struct acm *acm = tty->driver_data;
336 if (!acm || !acm->used) return;
340 acm_set_control(acm, acm->ctrlout = 0);
341 usb_unlink_urb(&acm->ctrlurb);
342 usb_unlink_urb(&acm->writeurb);
343 usb_unlink_urb(&acm->readurb);
345 tty_unregister_devfs(&acm_tty_driver, acm->minor);
346 acm_table[acm->minor] = NULL;
353 static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
355 struct acm *acm = tty->driver_data;
357 if (!ACM_READY(acm)) return -EINVAL;
358 if (acm->writeurb.status == -EINPROGRESS) return 0;
359 if (!count) return 0;
361 count = (count > acm->writesize) ? acm->writesize : count;
364 if (copy_from_user(acm->writeurb.transfer_buffer, buf, count))
367 memcpy(acm->writeurb.transfer_buffer, buf, count);
369 acm->writeurb.transfer_buffer_length = count;
370 acm->writeurb.dev = acm->dev;
372 if (usb_submit_urb(&acm->writeurb))
373 dbg("usb_submit_urb(write bulk) failed");
378 static int acm_tty_write_room(struct tty_struct *tty)
380 struct acm *acm = tty->driver_data;
381 if (!ACM_READY(acm)) return -EINVAL;
382 return acm->writeurb.status == -EINPROGRESS ? 0 : acm->writesize;
385 static int acm_tty_chars_in_buffer(struct tty_struct *tty)
387 struct acm *acm = tty->driver_data;
388 if (!ACM_READY(acm)) return -EINVAL;
389 return acm->writeurb.status == -EINPROGRESS ? acm->writeurb.transfer_buffer_length : 0;
392 static void acm_tty_throttle(struct tty_struct *tty)
394 struct acm *acm = tty->driver_data;
395 if (!ACM_READY(acm)) return;
399 static void acm_tty_unthrottle(struct tty_struct *tty)
401 struct acm *acm = tty->driver_data;
402 if (!ACM_READY(acm)) return;
404 if (acm->readurb.status != -EINPROGRESS)
405 acm_read_bulk(&acm->readurb);
408 static void acm_tty_break_ctl(struct tty_struct *tty, int state)
410 struct acm *acm = tty->driver_data;
411 if (!ACM_READY(acm)) return;
412 if (acm_send_break(acm, state ? 0xffff : 0))
413 dbg("send break failed");
416 static int acm_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
418 struct acm *acm = tty->driver_data;
419 unsigned int mask, newctrl;
421 if (!ACM_READY(acm)) return -EINVAL;
427 return put_user((acm->ctrlout & ACM_CTRL_DTR ? TIOCM_DTR : 0) |
428 (acm->ctrlout & ACM_CTRL_RTS ? TIOCM_RTS : 0) |
429 (acm->ctrlin & ACM_CTRL_DSR ? TIOCM_DSR : 0) |
430 (acm->ctrlin & ACM_CTRL_RI ? TIOCM_RI : 0) |
431 (acm->ctrlin & ACM_CTRL_DCD ? TIOCM_CD : 0) |
432 TIOCM_CTS, (unsigned long *) arg);
438 if (get_user(mask, (unsigned long *) arg))
441 newctrl = acm->ctrlout;
442 mask = (mask & TIOCM_DTR ? ACM_CTRL_DTR : 0) | (mask & TIOCM_RTS ? ACM_CTRL_RTS : 0);
445 case TIOCMSET: newctrl = mask; break;
446 case TIOCMBIS: newctrl |= mask; break;
447 case TIOCMBIC: newctrl &= ~mask; break;
450 if (acm->ctrlout == newctrl) return 0;
451 return acm_set_control(acm, acm->ctrlout = newctrl);
457 static __u32 acm_tty_speed[] = {
458 0, 50, 75, 110, 134, 150, 200, 300, 600,
459 1200, 1800, 2400, 4800, 9600, 19200, 38400,
460 57600, 115200, 230400, 460800, 500000, 576000,
461 921600, 1000000, 1152000, 1500000, 2000000,
462 2500000, 3000000, 3500000, 4000000
465 static __u8 acm_tty_size[] = {
469 static void acm_tty_set_termios(struct tty_struct *tty, struct termios *termios_old)
471 struct acm *acm = tty->driver_data;
472 struct termios *termios = tty->termios;
473 struct acm_line newline;
474 int newctrl = acm->ctrlout;
476 if (!ACM_READY(acm)) return;
478 newline.speed = cpu_to_le32p(acm_tty_speed +
479 (termios->c_cflag & CBAUD & ~CBAUDEX) + (termios->c_cflag & CBAUDEX ? 15 : 0));
480 newline.stopbits = termios->c_cflag & CSTOPB ? 2 : 0;
481 newline.parity = termios->c_cflag & PARENB ?
482 (termios->c_cflag & PARODD ? 1 : 2) + (termios->c_cflag & CMSPAR ? 2 : 0) : 0;
483 newline.databits = acm_tty_size[(termios->c_cflag & CSIZE) >> 4];
485 acm->clocal = ((termios->c_cflag & CLOCAL) != 0);
487 if (!newline.speed) {
488 newline.speed = acm->line.speed;
489 newctrl &= ~ACM_CTRL_DTR;
490 } else newctrl |= ACM_CTRL_DTR;
492 if (newctrl != acm->ctrlout)
493 acm_set_control(acm, acm->ctrlout = newctrl);
495 if (memcmp(&acm->line, &newline, sizeof(struct acm_line))) {
496 memcpy(&acm->line, &newline, sizeof(struct acm_line));
497 dbg("set line: %d %d %d %d", newline.speed, newline.stopbits, newline.parity, newline.databits);
498 acm_set_line(acm, &acm->line);
503 * USB probe and disconnect routines.
506 static void *acm_probe(struct usb_device *dev, unsigned int ifnum,
507 const struct usb_device_id *id)
510 struct usb_config_descriptor *cfacm;
511 struct usb_interface_descriptor *ifcom, *ifdata;
512 struct usb_endpoint_descriptor *epctrl, *epread, *epwrite;
513 int readsize, ctrlsize, minor, i, j;
516 for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
518 cfacm = dev->config + i;
520 dbg("probing config %d", cfacm->bConfigurationValue);
522 for (j = 0; j < cfacm->bNumInterfaces - 1; j++) {
524 if (usb_interface_claimed(cfacm->interface + j) ||
525 usb_interface_claimed(cfacm->interface + j + 1))
528 ifcom = cfacm->interface[j].altsetting + 0;
529 ifdata = cfacm->interface[j + 1].altsetting + 0;
531 if (ifdata->bInterfaceClass != 10 || ifdata->bNumEndpoints < 2) {
532 ifcom = cfacm->interface[j + 1].altsetting + 0;
533 ifdata = cfacm->interface[j].altsetting + 0;
534 if (ifdata->bInterfaceClass != 10 || ifdata->bNumEndpoints < 2)
538 if (ifcom->bInterfaceClass != 2 || ifcom->bInterfaceSubClass != 2 ||
539 ifcom->bInterfaceProtocol < 1 || ifcom->bInterfaceProtocol > 6 ||
540 ifcom->bNumEndpoints < 1)
543 epctrl = ifcom->endpoint + 0;
544 epread = ifdata->endpoint + 0;
545 epwrite = ifdata->endpoint + 1;
547 if ((epctrl->bEndpointAddress & 0x80) != 0x80 || (epctrl->bmAttributes & 3) != 3 ||
548 (epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes & 3) != 2 ||
549 ((epread->bEndpointAddress & 0x80) ^ (epwrite->bEndpointAddress & 0x80)) != 0x80)
552 dbg("using interface %d\n", j);
554 if ((epread->bEndpointAddress & 0x80) != 0x80) {
555 epread = ifdata->endpoint + 1;
556 epwrite = ifdata->endpoint + 0;
559 usb_set_configuration(dev, cfacm->bConfigurationValue);
561 for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
562 if (acm_table[minor]) {
563 err("no more free acm devices");
567 if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) {
568 err("out of memory");
571 memset(acm, 0, sizeof(struct acm));
573 ctrlsize = epctrl->wMaxPacketSize;
574 readsize = epread->wMaxPacketSize;
575 acm->writesize = epwrite->wMaxPacketSize;
576 acm->iface = cfacm->interface + j;
580 acm->tqueue.routine = acm_softint;
581 acm->tqueue.data = acm;
583 if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
584 err("out of memory");
589 FILL_INT_URB(&acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress),
590 buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
592 FILL_BULK_URB(&acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
593 buf += ctrlsize, readsize, acm_read_bulk, acm);
594 acm->readurb.transfer_flags |= USB_NO_FSBR;
596 FILL_BULK_URB(&acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
597 buf += readsize, acm->writesize, acm_write_bulk, acm);
598 acm->writeurb.transfer_flags |= USB_NO_FSBR;
600 printk(KERN_INFO "ttyACM%d: USB ACM device\n", minor);
602 acm_set_control(acm, acm->ctrlout);
604 acm->line.speed = cpu_to_le32(9600);
605 acm->line.databits = 8;
606 acm_set_line(acm, &acm->line);
608 usb_driver_claim_interface(&acm_driver, acm->iface + 0, acm);
609 usb_driver_claim_interface(&acm_driver, acm->iface + 1, acm);
611 tty_register_devfs(&acm_tty_driver, 0, minor);
612 return acm_table[minor] = acm;
619 static void acm_disconnect(struct usb_device *dev, void *ptr)
621 struct acm *acm = ptr;
623 if (!acm || !acm->dev) {
624 dbg("disconnect on nonexisting interface");
630 usb_unlink_urb(&acm->ctrlurb);
631 usb_unlink_urb(&acm->readurb);
632 usb_unlink_urb(&acm->writeurb);
634 kfree(acm->ctrlurb.transfer_buffer);
636 usb_driver_release_interface(&acm_driver, acm->iface + 0);
637 usb_driver_release_interface(&acm_driver, acm->iface + 1);
640 tty_unregister_devfs(&acm_tty_driver, acm->minor);
641 acm_table[acm->minor] = NULL;
647 tty_hangup(acm->tty);
651 * USB driver structure.
654 static struct usb_device_id acm_ids[] = {
655 { USB_DEVICE(0x22B8, 0x1005) }, /* Motorola TimePort 280 */
656 { USB_DEVICE_INFO(USB_CLASS_COMM, 0, 0) },
657 { USB_DEVICE_INFO(USB_CLASS_COMM, 2, 0) },
661 MODULE_DEVICE_TABLE (usb, acm_ids);
663 static struct usb_driver acm_driver = {
666 disconnect: acm_disconnect,
671 * TTY driver structures.
674 static int acm_tty_refcount;
676 static struct tty_struct *acm_tty_table[ACM_TTY_MINORS];
677 static struct termios *acm_tty_termios[ACM_TTY_MINORS];
678 static struct termios *acm_tty_termios_locked[ACM_TTY_MINORS];
680 static struct tty_driver acm_tty_driver = {
681 magic: TTY_DRIVER_MAGIC,
684 major: ACM_TTY_MAJOR,
687 type: TTY_DRIVER_TYPE_SERIAL,
688 subtype: SERIAL_TYPE_NORMAL,
689 flags: TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
691 refcount: &acm_tty_refcount,
693 table: acm_tty_table,
694 termios: acm_tty_termios,
695 termios_locked: acm_tty_termios_locked,
698 close: acm_tty_close,
699 write: acm_tty_write,
700 write_room: acm_tty_write_room,
701 ioctl: acm_tty_ioctl,
702 throttle: acm_tty_throttle,
703 unthrottle: acm_tty_unthrottle,
704 chars_in_buffer: acm_tty_chars_in_buffer,
705 break_ctl: acm_tty_break_ctl,
706 set_termios: acm_tty_set_termios
713 static int __init acm_init(void)
715 acm_tty_driver.init_termios = tty_std_termios;
716 acm_tty_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
718 if (tty_register_driver(&acm_tty_driver))
721 if (usb_register(&acm_driver) < 0) {
722 tty_unregister_driver(&acm_tty_driver);
726 info(DRIVER_VERSION ":" DRIVER_DESC);
731 static void __exit acm_exit(void)
733 usb_deregister(&acm_driver);
734 tty_unregister_driver(&acm_tty_driver);
737 module_init(acm_init);
738 module_exit(acm_exit);
740 MODULE_AUTHOR( DRIVER_AUTHOR );
741 MODULE_DESCRIPTION( DRIVER_DESC );
742 MODULE_LICENSE("GPL");