1 /*
2 * acm.c Version 0.21
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 *
9 * USB Abstract Control Model driver for USB modems and ISDN adapters
10 *
11 * Sponsored by SuSE
12 *
13 * ChangeLog:
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 */
28
29 /*
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.
34 *
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.
39 *
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
43 */
44
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>
58 #undef DEBUG
59 #include <linux/usb.h>
60
61 /*
62 * Version Information
63 */
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"
67
68 /*
69 * CMSPAR, some architectures can't have space and mark parity.
70 */
71
72 #ifndef CMSPAR
73 #define CMSPAR 0
74 #endif
75
76 /*
77 * Major and minor numbers.
78 */
79
80 #define ACM_TTY_MAJOR 166
81 #define ACM_TTY_MINORS 32
82
83 /*
84 * Requests.
85 */
86
87 #define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
88
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
94
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
99
100 /*
101 * IRQs.
102 */
103
104 #define ACM_IRQ_NETWORK 0x00
105 #define ACM_IRQ_LINE_STATE 0x20
106
107 /*
108 * Output control lines.
109 */
110
111 #define ACM_CTRL_DTR 0x01
112 #define ACM_CTRL_RTS 0x02
113
114 /*
115 * Input control lines and line errors.
116 */
117
118 #define ACM_CTRL_DCD 0x01
119 #define ACM_CTRL_DSR 0x02
120 #define ACM_CTRL_BRK 0x04
121 #define ACM_CTRL_RI 0x08
122
123 #define ACM_CTRL_FRAMING 0x10
124 #define ACM_CTRL_PARITY 0x20
125 #define ACM_CTRL_OVERRUN 0x40
126
127 /*
128 * Line speed and caracter encoding.
129 */
130
131 struct acm_line {
132 __u32 speed;
133 __u8 stopbits;
134 __u8 parity;
135 __u8 databits;
136 } __attribute__ ((packed));
137
138 /*
139 * Internal driver structures.
140 */
141
142 struct acm {
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 */
156 };
157
158 static struct usb_driver acm_driver;
159 static struct tty_driver acm_tty_driver;
160 static struct acm *acm_table[ACM_TTY_MINORS];
161
162 #define ACM_READY(acm) (acm && acm->dev && acm->used)
163
164 /*
165 * Functions for ACM control messages.
166 */
167
acm_ctrl_msg(struct acm * acm,int request,int value,void * buf,int len)168 static int acm_ctrl_msg(struct acm *acm, int request, int value, void *buf, int len)
169 {
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;
174 }
175
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)
179
180 /*
181 * Interrupt handler for various ACM control events
182 */
183
acm_ctrl_irq(struct urb * urb)184 static void acm_ctrl_irq(struct urb *urb)
185 {
186 struct acm *acm = urb->context;
187 struct usb_ctrlrequest *dr = urb->transfer_buffer;
188 unsigned char *data = (unsigned char *)(dr + 1);
189 int newctrl;
190
191 if (!ACM_READY(acm)) return;
192
193 if (urb->status < 0) {
194 dbg("nonzero ctrl irq status received: %d", urb->status);
195 return;
196 }
197
198 switch (dr->bRequest) {
199
200 case ACM_IRQ_NETWORK:
201
202 dbg("%s network", data[0] ? "connected to" : "disconnected from");
203 return;
204
205 case ACM_IRQ_LINE_STATE:
206
207 newctrl = le16_to_cpup((__u16 *) data);
208
209 if (acm->tty && !acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
210 dbg("calling hangup");
211 tty_hangup(acm->tty);
212 }
213
214 acm->ctrlin = newctrl;
215
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 ? '+' : '-');
221
222 return;
223
224 default:
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]);
227 return;
228 }
229 }
230
acm_read_bulk(struct urb * urb)231 static void acm_read_bulk(struct urb *urb)
232 {
233 struct acm *acm = urb->context;
234 struct tty_struct *tty = acm->tty;
235 unsigned char *data = urb->transfer_buffer;
236 int i = 0;
237
238 if (!ACM_READY(acm)) return;
239
240 if (urb->status)
241 dbg("nonzero read bulk status received: %d", urb->status);
242
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,
246 * we drop them. */
247 if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
248 tty_flip_buffer_push(tty);
249 }
250 tty_insert_flip_char(tty, data[i], 0);
251 }
252 tty_flip_buffer_push(tty);
253 }
254
255 if (acm->throttle) {
256 memmove(data, data + i, urb->actual_length - i);
257 urb->actual_length -= i;
258 return;
259 }
260
261 urb->actual_length = 0;
262 urb->dev = acm->dev;
263
264 if (usb_submit_urb(urb))
265 dbg("failed resubmitting read urb");
266 }
267
acm_write_bulk(struct urb * urb)268 static void acm_write_bulk(struct urb *urb)
269 {
270 struct acm *acm = (struct acm *)urb->context;
271
272 if (!ACM_READY(acm)) return;
273
274 if (urb->status)
275 dbg("nonzero write bulk status received: %d", urb->status);
276
277 queue_task(&acm->tqueue, &tq_immediate);
278 mark_bh(IMMEDIATE_BH);
279 }
280
acm_softint(void * private)281 static void acm_softint(void *private)
282 {
283 struct acm *acm = private;
284 struct tty_struct *tty = acm->tty;
285
286 if (!ACM_READY(acm)) return;
287
288 tty_wakeup(tty);
289 }
290
291 /*
292 * TTY handlers
293 */
294
acm_tty_open(struct tty_struct * tty,struct file * filp)295 static int acm_tty_open(struct tty_struct *tty, struct file *filp)
296 {
297 struct acm *acm = acm_table[MINOR(tty->device)];
298
299 if (!acm || !acm->dev) return -EINVAL;
300
301 tty->driver_data = acm;
302 acm->tty = tty;
303
304 MOD_INC_USE_COUNT;
305
306 lock_kernel();
307
308 if (acm->used++) {
309 unlock_kernel();
310 return 0;
311 }
312
313 unlock_kernel();
314
315 acm->ctrlurb.dev = acm->dev;
316 if (usb_submit_urb(&acm->ctrlurb))
317 dbg("usb_submit_urb(ctrl irq) failed");
318
319 acm->readurb.dev = acm->dev;
320 if (usb_submit_urb(&acm->readurb))
321 dbg("usb_submit_urb(read bulk) failed");
322
323 acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS);
324
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;
328
329 return 0;
330 }
331
acm_tty_close(struct tty_struct * tty,struct file * filp)332 static void acm_tty_close(struct tty_struct *tty, struct file *filp)
333 {
334 struct acm *acm = tty->driver_data;
335
336 if (!acm || !acm->used) return;
337
338 if (!--acm->used) {
339 if (acm->dev) {
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);
344 } else {
345 tty_unregister_devfs(&acm_tty_driver, acm->minor);
346 acm_table[acm->minor] = NULL;
347 kfree(acm);
348 }
349 }
350 MOD_DEC_USE_COUNT;
351 }
352
acm_tty_write(struct tty_struct * tty,int from_user,const unsigned char * buf,int count)353 static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
354 {
355 struct acm *acm = tty->driver_data;
356
357 if (!ACM_READY(acm)) return -EINVAL;
358 if (acm->writeurb.status == -EINPROGRESS) return 0;
359 if (!count) return 0;
360
361 count = (count > acm->writesize) ? acm->writesize : count;
362
363 if (from_user) {
364 if (copy_from_user(acm->writeurb.transfer_buffer, buf, count))
365 return -EFAULT;
366 } else
367 memcpy(acm->writeurb.transfer_buffer, buf, count);
368
369 acm->writeurb.transfer_buffer_length = count;
370 acm->writeurb.dev = acm->dev;
371
372 if (usb_submit_urb(&acm->writeurb))
373 dbg("usb_submit_urb(write bulk) failed");
374
375 return count;
376 }
377
acm_tty_write_room(struct tty_struct * tty)378 static int acm_tty_write_room(struct tty_struct *tty)
379 {
380 struct acm *acm = tty->driver_data;
381 if (!ACM_READY(acm)) return -EINVAL;
382 return acm->writeurb.status == -EINPROGRESS ? 0 : acm->writesize;
383 }
384
acm_tty_chars_in_buffer(struct tty_struct * tty)385 static int acm_tty_chars_in_buffer(struct tty_struct *tty)
386 {
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;
390 }
391
acm_tty_throttle(struct tty_struct * tty)392 static void acm_tty_throttle(struct tty_struct *tty)
393 {
394 struct acm *acm = tty->driver_data;
395 if (!ACM_READY(acm)) return;
396 acm->throttle = 1;
397 }
398
acm_tty_unthrottle(struct tty_struct * tty)399 static void acm_tty_unthrottle(struct tty_struct *tty)
400 {
401 struct acm *acm = tty->driver_data;
402 if (!ACM_READY(acm)) return;
403 acm->throttle = 0;
404 if (acm->readurb.status != -EINPROGRESS)
405 acm_read_bulk(&acm->readurb);
406 }
407
acm_tty_break_ctl(struct tty_struct * tty,int state)408 static void acm_tty_break_ctl(struct tty_struct *tty, int state)
409 {
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");
414 }
415
acm_tty_ioctl(struct tty_struct * tty,struct file * file,unsigned int cmd,unsigned long arg)416 static int acm_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
417 {
418 struct acm *acm = tty->driver_data;
419 unsigned int mask, newctrl;
420
421 if (!ACM_READY(acm)) return -EINVAL;
422
423 switch (cmd) {
424
425 case TIOCMGET:
426
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);
433
434 case TIOCMSET:
435 case TIOCMBIS:
436 case TIOCMBIC:
437
438 if (get_user(mask, (unsigned long *) arg))
439 return -EFAULT;
440
441 newctrl = acm->ctrlout;
442 mask = (mask & TIOCM_DTR ? ACM_CTRL_DTR : 0) | (mask & TIOCM_RTS ? ACM_CTRL_RTS : 0);
443
444 switch (cmd) {
445 case TIOCMSET: newctrl = mask; break;
446 case TIOCMBIS: newctrl |= mask; break;
447 case TIOCMBIC: newctrl &= ~mask; break;
448 }
449
450 if (acm->ctrlout == newctrl) return 0;
451 return acm_set_control(acm, acm->ctrlout = newctrl);
452 }
453
454 return -ENOIOCTLCMD;
455 }
456
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
463 };
464
465 static __u8 acm_tty_size[] = {
466 5, 6, 7, 8
467 };
468
acm_tty_set_termios(struct tty_struct * tty,struct termios * termios_old)469 static void acm_tty_set_termios(struct tty_struct *tty, struct termios *termios_old)
470 {
471 struct acm *acm = tty->driver_data;
472 struct termios *termios = tty->termios;
473 struct acm_line newline;
474 int newctrl = acm->ctrlout;
475
476 if (!ACM_READY(acm)) return;
477
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];
484
485 acm->clocal = ((termios->c_cflag & CLOCAL) != 0);
486
487 if (!newline.speed) {
488 newline.speed = acm->line.speed;
489 newctrl &= ~ACM_CTRL_DTR;
490 } else newctrl |= ACM_CTRL_DTR;
491
492 if (newctrl != acm->ctrlout)
493 acm_set_control(acm, acm->ctrlout = newctrl);
494
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);
499 }
500 }
501
502 /*
503 * USB probe and disconnect routines.
504 */
505
acm_probe(struct usb_device * dev,unsigned int ifnum,const struct usb_device_id * id)506 static void *acm_probe(struct usb_device *dev, unsigned int ifnum,
507 const struct usb_device_id *id)
508 {
509 struct acm *acm;
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;
514 unsigned char *buf;
515
516 for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
517
518 cfacm = dev->config + i;
519
520 dbg("probing config %d", cfacm->bConfigurationValue);
521
522 for (j = 0; j < cfacm->bNumInterfaces - 1; j++) {
523
524 if (usb_interface_claimed(cfacm->interface + j) ||
525 usb_interface_claimed(cfacm->interface + j + 1))
526 continue;
527
528 ifcom = cfacm->interface[j].altsetting + 0;
529 ifdata = cfacm->interface[j + 1].altsetting + 0;
530
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)
535 continue;
536 }
537
538 if (ifcom->bInterfaceClass != 2 || ifcom->bInterfaceSubClass != 2 ||
539 ifcom->bInterfaceProtocol < 1 || ifcom->bInterfaceProtocol > 6 ||
540 ifcom->bNumEndpoints < 1)
541 continue;
542
543 epctrl = ifcom->endpoint + 0;
544 epread = ifdata->endpoint + 0;
545 epwrite = ifdata->endpoint + 1;
546
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)
550 continue;
551
552 dbg("using interface %d\n", j);
553
554 if ((epread->bEndpointAddress & 0x80) != 0x80) {
555 epread = ifdata->endpoint + 1;
556 epwrite = ifdata->endpoint + 0;
557 }
558
559 usb_set_configuration(dev, cfacm->bConfigurationValue);
560
561 for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
562 if (acm_table[minor]) {
563 err("no more free acm devices");
564 return NULL;
565 }
566
567 if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) {
568 err("out of memory");
569 return NULL;
570 }
571 memset(acm, 0, sizeof(struct acm));
572
573 ctrlsize = epctrl->wMaxPacketSize;
574 readsize = epread->wMaxPacketSize;
575 acm->writesize = epwrite->wMaxPacketSize;
576 acm->iface = cfacm->interface + j;
577 acm->minor = minor;
578 acm->dev = dev;
579
580 acm->tqueue.routine = acm_softint;
581 acm->tqueue.data = acm;
582
583 if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
584 err("out of memory");
585 kfree(acm);
586 return NULL;
587 }
588
589 FILL_INT_URB(&acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress),
590 buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
591
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;
595
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;
599
600 printk(KERN_INFO "ttyACM%d: USB ACM device\n", minor);
601
602 acm_set_control(acm, acm->ctrlout);
603
604 acm->line.speed = cpu_to_le32(9600);
605 acm->line.databits = 8;
606 acm_set_line(acm, &acm->line);
607
608 usb_driver_claim_interface(&acm_driver, acm->iface + 0, acm);
609 usb_driver_claim_interface(&acm_driver, acm->iface + 1, acm);
610
611 tty_register_devfs(&acm_tty_driver, 0, minor);
612 return acm_table[minor] = acm;
613 }
614 }
615
616 return NULL;
617 }
618
acm_disconnect(struct usb_device * dev,void * ptr)619 static void acm_disconnect(struct usb_device *dev, void *ptr)
620 {
621 struct acm *acm = ptr;
622
623 if (!acm || !acm->dev) {
624 dbg("disconnect on nonexisting interface");
625 return;
626 }
627
628 acm->dev = NULL;
629
630 usb_unlink_urb(&acm->ctrlurb);
631 usb_unlink_urb(&acm->readurb);
632 usb_unlink_urb(&acm->writeurb);
633
634 kfree(acm->ctrlurb.transfer_buffer);
635
636 usb_driver_release_interface(&acm_driver, acm->iface + 0);
637 usb_driver_release_interface(&acm_driver, acm->iface + 1);
638
639 if (!acm->used) {
640 tty_unregister_devfs(&acm_tty_driver, acm->minor);
641 acm_table[acm->minor] = NULL;
642 kfree(acm);
643 return;
644 }
645
646 if (acm->tty)
647 tty_hangup(acm->tty);
648 }
649
650 /*
651 * USB driver structure.
652 */
653
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) },
658 { }
659 };
660
661 MODULE_DEVICE_TABLE (usb, acm_ids);
662
663 static struct usb_driver acm_driver = {
664 name: "acm",
665 probe: acm_probe,
666 disconnect: acm_disconnect,
667 id_table: acm_ids,
668 };
669
670 /*
671 * TTY driver structures.
672 */
673
674 static int acm_tty_refcount;
675
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];
679
680 static struct tty_driver acm_tty_driver = {
681 magic: TTY_DRIVER_MAGIC,
682 driver_name: "acm",
683 name: "usb/acm/%d",
684 major: ACM_TTY_MAJOR,
685 minor_start: 0,
686 num: ACM_TTY_MINORS,
687 type: TTY_DRIVER_TYPE_SERIAL,
688 subtype: SERIAL_TYPE_NORMAL,
689 flags: TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
690
691 refcount: &acm_tty_refcount,
692
693 table: acm_tty_table,
694 termios: acm_tty_termios,
695 termios_locked: acm_tty_termios_locked,
696
697 open: acm_tty_open,
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
707 };
708
709 /*
710 * Init / exit.
711 */
712
acm_init(void)713 static int __init acm_init(void)
714 {
715 acm_tty_driver.init_termios = tty_std_termios;
716 acm_tty_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
717
718 if (tty_register_driver(&acm_tty_driver))
719 return -1;
720
721 if (usb_register(&acm_driver) < 0) {
722 tty_unregister_driver(&acm_tty_driver);
723 return -1;
724 }
725
726 info(DRIVER_VERSION ":" DRIVER_DESC);
727
728 return 0;
729 }
730
acm_exit(void)731 static void __exit acm_exit(void)
732 {
733 usb_deregister(&acm_driver);
734 tty_unregister_driver(&acm_tty_driver);
735 }
736
737 module_init(acm_init);
738 module_exit(acm_exit);
739
740 MODULE_AUTHOR( DRIVER_AUTHOR );
741 MODULE_DESCRIPTION( DRIVER_DESC );
742 MODULE_LICENSE("GPL");
743
744