blob: 0c4881d18cd59b0c30f63b4a3401da3eb3813623 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * USB Serial Converter driver
3 *
Greg Kroah-Hartman502b95c2005-06-20 21:15:16 -07004 * Copyright (C) 1999 - 2005 Greg Kroah-Hartman (greg@kroah.com)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 * Copyright (C) 2000 Peter Berger (pberger@brimson.com)
6 * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version
10 * 2 as published by the Free Software Foundation.
11 *
Greg Kroah-Hartman502b95c2005-06-20 21:15:16 -070012 * This driver was originally based on the ACM driver by Armin Fuerst (which was
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 * based on a driver by Brad Keryan)
14 *
15 * See Documentation/usb/usb-serial.txt for more information on using this driver
16 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070017 */
18
19#include <linux/config.h>
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/tty.h>
25#include <linux/tty_driver.h>
26#include <linux/tty_flip.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/spinlock.h>
30#include <linux/list.h>
31#include <linux/smp_lock.h>
32#include <asm/uaccess.h>
33#include <linux/usb.h>
34#include "usb-serial.h"
35#include "pl2303.h"
36
37/*
38 * Version Information
39 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/"
41#define DRIVER_DESC "USB Serial Driver core"
42
43/* Driver structure we register with the USB core */
44static struct usb_driver usb_serial_driver = {
45 .owner = THIS_MODULE,
46 .name = "usbserial",
47 .probe = usb_serial_probe,
48 .disconnect = usb_serial_disconnect,
49};
50
51/* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead
52 the MODULE_DEVICE_TABLE declarations in each serial driver
53 cause the "hotplug" program to pull in whatever module is necessary
54 via modprobe, and modprobe will load usbserial because the serial
55 drivers depend on it.
56*/
57
58static int debug;
59static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */
60static LIST_HEAD(usb_serial_driver_list);
61
62struct usb_serial *usb_serial_get_by_index(unsigned index)
63{
64 struct usb_serial *serial = serial_table[index];
65
66 if (serial)
67 kref_get(&serial->kref);
68 return serial;
69}
70
71static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_ports, unsigned int *minor)
72{
73 unsigned int i, j;
74 int good_spot;
75
76 dbg("%s %d", __FUNCTION__, num_ports);
77
78 *minor = 0;
79 for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
80 if (serial_table[i])
81 continue;
82
83 good_spot = 1;
84 for (j = 1; j <= num_ports-1; ++j)
85 if ((i+j >= SERIAL_TTY_MINORS) || (serial_table[i+j])) {
86 good_spot = 0;
87 i += j;
88 break;
89 }
90 if (good_spot == 0)
91 continue;
92
93 *minor = i;
94 dbg("%s - minor base = %d", __FUNCTION__, *minor);
95 for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i)
96 serial_table[i] = serial;
97 return serial;
98 }
99 return NULL;
100}
101
102static void return_serial(struct usb_serial *serial)
103{
104 int i;
105
106 dbg("%s", __FUNCTION__);
107
108 if (serial == NULL)
109 return;
110
111 for (i = 0; i < serial->num_ports; ++i) {
112 serial_table[serial->minor + i] = NULL;
113 }
114}
115
116static void destroy_serial(struct kref *kref)
117{
118 struct usb_serial *serial;
119 struct usb_serial_port *port;
120 int i;
121
122 serial = to_usb_serial(kref);
123
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700124 dbg("%s - %s", __FUNCTION__, serial->type->description);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
126 serial->type->shutdown(serial);
127
128 /* return the minor range that this device had */
129 return_serial(serial);
130
131 for (i = 0; i < serial->num_ports; ++i)
132 serial->port[i]->open_count = 0;
133
134 /* the ports are cleaned up and released in port_release() */
135 for (i = 0; i < serial->num_ports; ++i)
136 if (serial->port[i]->dev.parent != NULL) {
137 device_unregister(&serial->port[i]->dev);
138 serial->port[i] = NULL;
139 }
140
141 /* If this is a "fake" port, we have to clean it up here, as it will
142 * not get cleaned up in port_release() as it was never registered with
143 * the driver core */
144 if (serial->num_ports < serial->num_port_pointers) {
145 for (i = serial->num_ports; i < serial->num_port_pointers; ++i) {
146 port = serial->port[i];
147 if (!port)
148 continue;
149 usb_kill_urb(port->read_urb);
150 usb_free_urb(port->read_urb);
151 usb_kill_urb(port->write_urb);
152 usb_free_urb(port->write_urb);
153 usb_kill_urb(port->interrupt_in_urb);
154 usb_free_urb(port->interrupt_in_urb);
155 usb_kill_urb(port->interrupt_out_urb);
156 usb_free_urb(port->interrupt_out_urb);
157 kfree(port->bulk_in_buffer);
158 kfree(port->bulk_out_buffer);
159 kfree(port->interrupt_in_buffer);
160 kfree(port->interrupt_out_buffer);
161 }
162 }
163
164 usb_put_dev(serial->dev);
165
166 /* free up any memory that we allocated */
167 kfree (serial);
168}
169
170/*****************************************************************************
171 * Driver tty interface functions
172 *****************************************************************************/
173static int serial_open (struct tty_struct *tty, struct file * filp)
174{
175 struct usb_serial *serial;
176 struct usb_serial_port *port;
177 unsigned int portNumber;
178 int retval;
179
180 dbg("%s", __FUNCTION__);
181
182 /* get the serial object associated with this tty pointer */
183 serial = usb_serial_get_by_index(tty->index);
184 if (!serial) {
185 tty->driver_data = NULL;
186 return -ENODEV;
187 }
188
189 portNumber = tty->index - serial->minor;
190 port = serial->port[portNumber];
191
192 ++port->open_count;
193
194 if (port->open_count == 1) {
195
196 /* set up our port structure making the tty driver
197 * remember our port object, and us it */
198 tty->driver_data = port;
199 port->tty = tty;
200
201 /* lock this module before we call it
202 * this may fail, which means we must bail out,
203 * safe because we are called with BKL held */
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700204 if (!try_module_get(serial->type->driver.owner)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 retval = -ENODEV;
206 goto bailout_kref_put;
207 }
208
209 /* only call the device specific open if this
210 * is the first time the port is opened */
211 retval = serial->type->open(port, filp);
212 if (retval)
213 goto bailout_module_put;
214 }
215
216 return 0;
217
218bailout_module_put:
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700219 module_put(serial->type->driver.owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220bailout_kref_put:
221 kref_put(&serial->kref, destroy_serial);
222 port->open_count = 0;
223 return retval;
224}
225
226static void serial_close(struct tty_struct *tty, struct file * filp)
227{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200228 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229
230 if (!port)
231 return;
232
233 dbg("%s - port %d", __FUNCTION__, port->number);
234
235 if (port->open_count == 0)
236 return;
237
238 --port->open_count;
239 if (port->open_count == 0) {
240 /* only call the device specific close if this
241 * port is being closed by the last owner */
242 port->serial->type->close(port, filp);
243
244 if (port->tty) {
245 if (port->tty->driver_data)
246 port->tty->driver_data = NULL;
247 port->tty = NULL;
248 }
249
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700250 module_put(port->serial->type->driver.owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 }
252
253 kref_put(&port->serial->kref, destroy_serial);
254}
255
256static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
257{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200258 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 int retval = -EINVAL;
260
261 dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count);
262
263 if (!port->open_count) {
264 dbg("%s - port not opened", __FUNCTION__);
265 goto exit;
266 }
267
268 /* pass on to the driver specific version of this function */
269 retval = port->serial->type->write(port, buf, count);
270
271exit:
272 return retval;
273}
274
275static int serial_write_room (struct tty_struct *tty)
276{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200277 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278 int retval = -EINVAL;
279
280 dbg("%s - port %d", __FUNCTION__, port->number);
281
282 if (!port->open_count) {
283 dbg("%s - port not open", __FUNCTION__);
284 goto exit;
285 }
286
287 /* pass on to the driver specific version of this function */
288 retval = port->serial->type->write_room(port);
289
290exit:
291 return retval;
292}
293
294static int serial_chars_in_buffer (struct tty_struct *tty)
295{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200296 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297 int retval = -EINVAL;
298
299 dbg("%s = port %d", __FUNCTION__, port->number);
300
301 if (!port->open_count) {
302 dbg("%s - port not open", __FUNCTION__);
303 goto exit;
304 }
305
306 /* pass on to the driver specific version of this function */
307 retval = port->serial->type->chars_in_buffer(port);
308
309exit:
310 return retval;
311}
312
313static void serial_throttle (struct tty_struct * tty)
314{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200315 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316
317 dbg("%s - port %d", __FUNCTION__, port->number);
318
319 if (!port->open_count) {
320 dbg ("%s - port not open", __FUNCTION__);
321 return;
322 }
323
324 /* pass on to the driver specific version of this function */
325 if (port->serial->type->throttle)
326 port->serial->type->throttle(port);
327}
328
329static void serial_unthrottle (struct tty_struct * tty)
330{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200331 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332
333 dbg("%s - port %d", __FUNCTION__, port->number);
334
335 if (!port->open_count) {
336 dbg("%s - port not open", __FUNCTION__);
337 return;
338 }
339
340 /* pass on to the driver specific version of this function */
341 if (port->serial->type->unthrottle)
342 port->serial->type->unthrottle(port);
343}
344
345static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
346{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200347 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 int retval = -ENODEV;
349
350 dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
351
352 if (!port->open_count) {
353 dbg ("%s - port not open", __FUNCTION__);
354 goto exit;
355 }
356
357 /* pass on to the driver specific version of this function if it is available */
358 if (port->serial->type->ioctl)
359 retval = port->serial->type->ioctl(port, file, cmd, arg);
360 else
361 retval = -ENOIOCTLCMD;
362
363exit:
364 return retval;
365}
366
367static void serial_set_termios (struct tty_struct *tty, struct termios * old)
368{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200369 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370
371 dbg("%s - port %d", __FUNCTION__, port->number);
372
373 if (!port->open_count) {
374 dbg("%s - port not open", __FUNCTION__);
375 return;
376 }
377
378 /* pass on to the driver specific version of this function if it is available */
379 if (port->serial->type->set_termios)
380 port->serial->type->set_termios(port, old);
381}
382
383static void serial_break (struct tty_struct *tty, int break_state)
384{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200385 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
387 dbg("%s - port %d", __FUNCTION__, port->number);
388
389 if (!port->open_count) {
390 dbg("%s - port not open", __FUNCTION__);
391 return;
392 }
393
394 /* pass on to the driver specific version of this function if it is available */
395 if (port->serial->type->break_ctl)
396 port->serial->type->break_ctl(port, break_state);
397}
398
399static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data)
400{
401 struct usb_serial *serial;
402 int length = 0;
403 int i;
404 off_t begin = 0;
405 char tmp[40];
406
407 dbg("%s", __FUNCTION__);
Greg Kroah-Hartman17a882f2005-06-20 21:15:16 -0700408 length += sprintf (page, "usbserinfo:1.0 driver:2.0\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) {
410 serial = usb_serial_get_by_index(i);
411 if (serial == NULL)
412 continue;
413
414 length += sprintf (page+length, "%d:", i);
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700415 if (serial->type->driver.owner)
416 length += sprintf (page+length, " module:%s", module_name(serial->type->driver.owner));
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700417 length += sprintf (page+length, " name:\"%s\"", serial->type->description);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 length += sprintf (page+length, " vendor:%04x product:%04x",
419 le16_to_cpu(serial->dev->descriptor.idVendor),
420 le16_to_cpu(serial->dev->descriptor.idProduct));
421 length += sprintf (page+length, " num_ports:%d", serial->num_ports);
422 length += sprintf (page+length, " port:%d", i - serial->minor + 1);
423
424 usb_make_path(serial->dev, tmp, sizeof(tmp));
425 length += sprintf (page+length, " path:%s", tmp);
426
427 length += sprintf (page+length, "\n");
428 if ((length + begin) > (off + count))
429 goto done;
430 if ((length + begin) < off) {
431 begin += length;
432 length = 0;
433 }
434 kref_put(&serial->kref, destroy_serial);
435 }
436 *eof = 1;
437done:
438 if (off >= (length + begin))
439 return 0;
440 *start = page + (off-begin);
441 return ((count < begin+length-off) ? count : begin+length-off);
442}
443
444static int serial_tiocmget (struct tty_struct *tty, struct file *file)
445{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200446 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447
448 dbg("%s - port %d", __FUNCTION__, port->number);
449
450 if (!port->open_count) {
451 dbg("%s - port not open", __FUNCTION__);
452 goto exit;
453 }
454
455 if (port->serial->type->tiocmget)
456 return port->serial->type->tiocmget(port, file);
457
458exit:
459 return -EINVAL;
460}
461
462static int serial_tiocmset (struct tty_struct *tty, struct file *file,
463 unsigned int set, unsigned int clear)
464{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200465 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466
467 dbg("%s - port %d", __FUNCTION__, port->number);
468
469 if (!port->open_count) {
470 dbg("%s - port not open", __FUNCTION__);
471 goto exit;
472 }
473
474 if (port->serial->type->tiocmset)
475 return port->serial->type->tiocmset(port, file, set, clear);
476
477exit:
478 return -EINVAL;
479}
480
481void usb_serial_port_softint(void *private)
482{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200483 struct usb_serial_port *port = private;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 struct tty_struct *tty;
485
486 dbg("%s - port %d", __FUNCTION__, port->number);
487
488 if (!port)
489 return;
490
491 tty = port->tty;
492 if (!tty)
493 return;
494
495 tty_wakeup(tty);
496}
497
498static void port_release(struct device *dev)
499{
500 struct usb_serial_port *port = to_usb_serial_port(dev);
501
502 dbg ("%s - %s", __FUNCTION__, dev->bus_id);
503 usb_kill_urb(port->read_urb);
504 usb_free_urb(port->read_urb);
505 usb_kill_urb(port->write_urb);
506 usb_free_urb(port->write_urb);
507 usb_kill_urb(port->interrupt_in_urb);
508 usb_free_urb(port->interrupt_in_urb);
509 usb_kill_urb(port->interrupt_out_urb);
510 usb_free_urb(port->interrupt_out_urb);
511 kfree(port->bulk_in_buffer);
512 kfree(port->bulk_out_buffer);
513 kfree(port->interrupt_in_buffer);
514 kfree(port->interrupt_out_buffer);
515 kfree(port);
516}
517
518static struct usb_serial * create_serial (struct usb_device *dev,
519 struct usb_interface *interface,
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700520 struct usb_serial_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521{
522 struct usb_serial *serial;
523
524 serial = kmalloc (sizeof (*serial), GFP_KERNEL);
525 if (!serial) {
526 dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__);
527 return NULL;
528 }
529 memset (serial, 0, sizeof(*serial));
530 serial->dev = usb_get_dev(dev);
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700531 serial->type = driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 serial->interface = interface;
533 kref_init(&serial->kref);
534
535 return serial;
536}
537
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700538static struct usb_serial_driver *search_serial_device(struct usb_interface *iface)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539{
540 struct list_head *p;
541 const struct usb_device_id *id;
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700542 struct usb_serial_driver *t;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543
544 /* List trough know devices and see if the usb id matches */
545 list_for_each(p, &usb_serial_driver_list) {
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700546 t = list_entry(p, struct usb_serial_driver, driver_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 id = usb_match_id(iface, t->id_table);
548 if (id != NULL) {
549 dbg("descriptor matches");
550 return t;
551 }
552 }
553
554 return NULL;
555}
556
557int usb_serial_probe(struct usb_interface *interface,
558 const struct usb_device_id *id)
559{
560 struct usb_device *dev = interface_to_usbdev (interface);
561 struct usb_serial *serial = NULL;
562 struct usb_serial_port *port;
563 struct usb_host_interface *iface_desc;
564 struct usb_endpoint_descriptor *endpoint;
565 struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
566 struct usb_endpoint_descriptor *interrupt_out_endpoint[MAX_NUM_PORTS];
567 struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];
568 struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700569 struct usb_serial_driver *type = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 int retval;
571 int minor;
572 int buffer_size;
573 int i;
574 int num_interrupt_in = 0;
575 int num_interrupt_out = 0;
576 int num_bulk_in = 0;
577 int num_bulk_out = 0;
578 int num_ports = 0;
579 int max_endpoints;
580
581 type = search_serial_device(interface);
582 if (!type) {
583 dbg("none matched");
584 return -ENODEV;
585 }
586
587 serial = create_serial (dev, interface, type);
588 if (!serial) {
589 dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__);
590 return -ENOMEM;
591 }
592
593 /* if this device type has a probe function, call it */
594 if (type->probe) {
595 const struct usb_device_id *id;
596
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700597 if (!try_module_get(type->driver.owner)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 dev_err(&interface->dev, "module get failed, exiting\n");
599 kfree (serial);
600 return -EIO;
601 }
602
603 id = usb_match_id(interface, type->id_table);
604 retval = type->probe(serial, id);
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700605 module_put(type->driver.owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606
607 if (retval) {
608 dbg ("sub driver rejected device");
609 kfree (serial);
610 return retval;
611 }
612 }
613
614 /* descriptor matches, let's find the endpoints needed */
615 /* check out the endpoints */
616 iface_desc = interface->cur_altsetting;
617 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
618 endpoint = &iface_desc->endpoint[i].desc;
619
620 if ((endpoint->bEndpointAddress & 0x80) &&
621 ((endpoint->bmAttributes & 3) == 0x02)) {
622 /* we found a bulk in endpoint */
623 dbg("found bulk in on endpoint %d", i);
624 bulk_in_endpoint[num_bulk_in] = endpoint;
625 ++num_bulk_in;
626 }
627
628 if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
629 ((endpoint->bmAttributes & 3) == 0x02)) {
630 /* we found a bulk out endpoint */
631 dbg("found bulk out on endpoint %d", i);
632 bulk_out_endpoint[num_bulk_out] = endpoint;
633 ++num_bulk_out;
634 }
635
636 if ((endpoint->bEndpointAddress & 0x80) &&
637 ((endpoint->bmAttributes & 3) == 0x03)) {
638 /* we found a interrupt in endpoint */
639 dbg("found interrupt in on endpoint %d", i);
640 interrupt_in_endpoint[num_interrupt_in] = endpoint;
641 ++num_interrupt_in;
642 }
643
644 if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
645 ((endpoint->bmAttributes & 3) == 0x03)) {
646 /* we found an interrupt out endpoint */
647 dbg("found interrupt out on endpoint %d", i);
648 interrupt_out_endpoint[num_interrupt_out] = endpoint;
649 ++num_interrupt_out;
650 }
651 }
652
653#if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)
654 /* BEGIN HORRIBLE HACK FOR PL2303 */
655 /* this is needed due to the looney way its endpoints are set up */
656 if (((le16_to_cpu(dev->descriptor.idVendor) == PL2303_VENDOR_ID) &&
657 (le16_to_cpu(dev->descriptor.idProduct) == PL2303_PRODUCT_ID)) ||
658 ((le16_to_cpu(dev->descriptor.idVendor) == ATEN_VENDOR_ID) &&
659 (le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID))) {
660 if (interface != dev->actconfig->interface[0]) {
661 /* check out the endpoints of the other interface*/
662 iface_desc = dev->actconfig->interface[0]->cur_altsetting;
663 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
664 endpoint = &iface_desc->endpoint[i].desc;
665 if ((endpoint->bEndpointAddress & 0x80) &&
666 ((endpoint->bmAttributes & 3) == 0x03)) {
667 /* we found a interrupt in endpoint */
668 dbg("found interrupt in for Prolific device on separate interface");
669 interrupt_in_endpoint[num_interrupt_in] = endpoint;
670 ++num_interrupt_in;
671 }
672 }
673 }
674
675 /* Now make sure the PL-2303 is configured correctly.
676 * If not, give up now and hope this hack will work
677 * properly during a later invocation of usb_serial_probe
678 */
679 if (num_bulk_in == 0 || num_bulk_out == 0) {
680 dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n");
681 kfree (serial);
682 return -ENODEV;
683 }
684 }
685 /* END HORRIBLE HACK FOR PL2303 */
686#endif
687
688 /* found all that we need */
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -0700689 dev_info(&interface->dev, "%s converter detected\n", type->description);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690
691#ifdef CONFIG_USB_SERIAL_GENERIC
692 if (type == &usb_serial_generic_device) {
693 num_ports = num_bulk_out;
694 if (num_ports == 0) {
695 dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n");
696 kfree (serial);
697 return -EIO;
698 }
699 }
700#endif
701 if (!num_ports) {
702 /* if this device type has a calc_num_ports function, call it */
703 if (type->calc_num_ports) {
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700704 if (!try_module_get(type->driver.owner)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705 dev_err(&interface->dev, "module get failed, exiting\n");
706 kfree (serial);
707 return -EIO;
708 }
709 num_ports = type->calc_num_ports (serial);
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700710 module_put(type->driver.owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 }
712 if (!num_ports)
713 num_ports = type->num_ports;
714 }
715
716 if (get_free_serial (serial, num_ports, &minor) == NULL) {
717 dev_err(&interface->dev, "No more free serial devices\n");
718 kfree (serial);
719 return -ENOMEM;
720 }
721
722 serial->minor = minor;
723 serial->num_ports = num_ports;
724 serial->num_bulk_in = num_bulk_in;
725 serial->num_bulk_out = num_bulk_out;
726 serial->num_interrupt_in = num_interrupt_in;
727 serial->num_interrupt_out = num_interrupt_out;
728
729 /* create our ports, we need as many as the max endpoints */
730 /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */
731 max_endpoints = max(num_bulk_in, num_bulk_out);
732 max_endpoints = max(max_endpoints, num_interrupt_in);
733 max_endpoints = max(max_endpoints, num_interrupt_out);
734 max_endpoints = max(max_endpoints, (int)serial->num_ports);
735 serial->num_port_pointers = max_endpoints;
736 dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints);
737 for (i = 0; i < max_endpoints; ++i) {
738 port = kmalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
739 if (!port)
740 goto probe_error;
741 memset(port, 0x00, sizeof(struct usb_serial_port));
742 port->number = i + serial->minor;
743 port->serial = serial;
Greg Kroah-Hartman507ca9b2005-04-23 12:49:16 -0700744 spin_lock_init(&port->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 INIT_WORK(&port->work, usb_serial_port_softint, port);
746 serial->port[i] = port;
747 }
748
749 /* set up the endpoint information */
750 for (i = 0; i < num_bulk_in; ++i) {
751 endpoint = bulk_in_endpoint[i];
752 port = serial->port[i];
753 port->read_urb = usb_alloc_urb (0, GFP_KERNEL);
754 if (!port->read_urb) {
755 dev_err(&interface->dev, "No free urbs available\n");
756 goto probe_error;
757 }
758 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
759 port->bulk_in_size = buffer_size;
760 port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
761 port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
762 if (!port->bulk_in_buffer) {
763 dev_err(&interface->dev, "Couldn't allocate bulk_in_buffer\n");
764 goto probe_error;
765 }
766 usb_fill_bulk_urb (port->read_urb, dev,
767 usb_rcvbulkpipe (dev,
768 endpoint->bEndpointAddress),
769 port->bulk_in_buffer, buffer_size,
770 serial->type->read_bulk_callback,
771 port);
772 }
773
774 for (i = 0; i < num_bulk_out; ++i) {
775 endpoint = bulk_out_endpoint[i];
776 port = serial->port[i];
777 port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
778 if (!port->write_urb) {
779 dev_err(&interface->dev, "No free urbs available\n");
780 goto probe_error;
781 }
782 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
783 port->bulk_out_size = buffer_size;
784 port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
785 port->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
786 if (!port->bulk_out_buffer) {
787 dev_err(&interface->dev, "Couldn't allocate bulk_out_buffer\n");
788 goto probe_error;
789 }
790 usb_fill_bulk_urb (port->write_urb, dev,
791 usb_sndbulkpipe (dev,
792 endpoint->bEndpointAddress),
793 port->bulk_out_buffer, buffer_size,
794 serial->type->write_bulk_callback,
795 port);
796 }
797
798 if (serial->type->read_int_callback) {
799 for (i = 0; i < num_interrupt_in; ++i) {
800 endpoint = interrupt_in_endpoint[i];
801 port = serial->port[i];
802 port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
803 if (!port->interrupt_in_urb) {
804 dev_err(&interface->dev, "No free urbs available\n");
805 goto probe_error;
806 }
807 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
808 port->interrupt_in_endpointAddress = endpoint->bEndpointAddress;
809 port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
810 if (!port->interrupt_in_buffer) {
811 dev_err(&interface->dev, "Couldn't allocate interrupt_in_buffer\n");
812 goto probe_error;
813 }
814 usb_fill_int_urb (port->interrupt_in_urb, dev,
815 usb_rcvintpipe (dev,
816 endpoint->bEndpointAddress),
817 port->interrupt_in_buffer, buffer_size,
818 serial->type->read_int_callback, port,
819 endpoint->bInterval);
820 }
821 } else if (num_interrupt_in) {
822 dbg("the device claims to support interrupt in transfers, but read_int_callback is not defined");
823 }
824
825 if (serial->type->write_int_callback) {
826 for (i = 0; i < num_interrupt_out; ++i) {
827 endpoint = interrupt_out_endpoint[i];
828 port = serial->port[i];
829 port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
830 if (!port->interrupt_out_urb) {
831 dev_err(&interface->dev, "No free urbs available\n");
832 goto probe_error;
833 }
834 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
835 port->interrupt_out_size = buffer_size;
836 port->interrupt_out_endpointAddress = endpoint->bEndpointAddress;
837 port->interrupt_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
838 if (!port->interrupt_out_buffer) {
839 dev_err(&interface->dev, "Couldn't allocate interrupt_out_buffer\n");
840 goto probe_error;
841 }
842 usb_fill_int_urb (port->interrupt_out_urb, dev,
843 usb_sndintpipe (dev,
844 endpoint->bEndpointAddress),
845 port->interrupt_out_buffer, buffer_size,
846 serial->type->write_int_callback, port,
847 endpoint->bInterval);
848 }
849 } else if (num_interrupt_out) {
850 dbg("the device claims to support interrupt out transfers, but write_int_callback is not defined");
851 }
852
853 /* if this device type has an attach function, call it */
854 if (type->attach) {
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700855 if (!try_module_get(type->driver.owner)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 dev_err(&interface->dev, "module get failed, exiting\n");
857 goto probe_error;
858 }
859 retval = type->attach (serial);
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700860 module_put(type->driver.owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861 if (retval < 0)
862 goto probe_error;
863 if (retval > 0) {
864 /* quietly accept this device, but don't bind to a serial port
865 * as it's about to disappear */
866 goto exit;
867 }
868 }
869
870 /* register all of the individual ports with the driver core */
871 for (i = 0; i < num_ports; ++i) {
872 port = serial->port[i];
873 port->dev.parent = &interface->dev;
874 port->dev.driver = NULL;
875 port->dev.bus = &usb_serial_bus_type;
876 port->dev.release = &port_release;
877
878 snprintf (&port->dev.bus_id[0], sizeof(port->dev.bus_id), "ttyUSB%d", port->number);
879 dbg ("%s - registering %s", __FUNCTION__, port->dev.bus_id);
880 device_register (&port->dev);
881 }
882
883 usb_serial_console_init (debug, minor);
884
885exit:
886 /* success */
887 usb_set_intfdata (interface, serial);
888 return 0;
889
890probe_error:
891 for (i = 0; i < num_bulk_in; ++i) {
892 port = serial->port[i];
893 if (!port)
894 continue;
895 if (port->read_urb)
896 usb_free_urb (port->read_urb);
897 kfree(port->bulk_in_buffer);
898 }
899 for (i = 0; i < num_bulk_out; ++i) {
900 port = serial->port[i];
901 if (!port)
902 continue;
903 if (port->write_urb)
904 usb_free_urb (port->write_urb);
905 kfree(port->bulk_out_buffer);
906 }
907 for (i = 0; i < num_interrupt_in; ++i) {
908 port = serial->port[i];
909 if (!port)
910 continue;
911 if (port->interrupt_in_urb)
912 usb_free_urb (port->interrupt_in_urb);
913 kfree(port->interrupt_in_buffer);
914 }
915 for (i = 0; i < num_interrupt_out; ++i) {
916 port = serial->port[i];
917 if (!port)
918 continue;
919 if (port->interrupt_out_urb)
920 usb_free_urb (port->interrupt_out_urb);
921 kfree(port->interrupt_out_buffer);
922 }
923
924 /* return the minor range that this device had */
925 return_serial (serial);
926
927 /* free up any memory that we allocated */
928 for (i = 0; i < serial->num_port_pointers; ++i)
929 kfree(serial->port[i]);
930 kfree (serial);
931 return -EIO;
932}
933
934void usb_serial_disconnect(struct usb_interface *interface)
935{
936 int i;
937 struct usb_serial *serial = usb_get_intfdata (interface);
938 struct device *dev = &interface->dev;
939 struct usb_serial_port *port;
940
941 dbg ("%s", __FUNCTION__);
942
943 usb_set_intfdata (interface, NULL);
944 if (serial) {
945 for (i = 0; i < serial->num_ports; ++i) {
946 port = serial->port[i];
947 if (port && port->tty)
948 tty_hangup(port->tty);
949 }
950 /* let the last holder of this object
951 * cause it to be cleaned up */
952 kref_put(&serial->kref, destroy_serial);
953 }
954 dev_info(dev, "device disconnected\n");
955}
956
957static struct tty_operations serial_ops = {
958 .open = serial_open,
959 .close = serial_close,
960 .write = serial_write,
961 .write_room = serial_write_room,
962 .ioctl = serial_ioctl,
963 .set_termios = serial_set_termios,
964 .throttle = serial_throttle,
965 .unthrottle = serial_unthrottle,
966 .break_ctl = serial_break,
967 .chars_in_buffer = serial_chars_in_buffer,
968 .read_proc = serial_read_proc,
969 .tiocmget = serial_tiocmget,
970 .tiocmset = serial_tiocmset,
971};
972
973struct tty_driver *usb_serial_tty_driver;
974
975static int __init usb_serial_init(void)
976{
977 int i;
978 int result;
979
980 usb_serial_tty_driver = alloc_tty_driver(SERIAL_TTY_MINORS);
981 if (!usb_serial_tty_driver)
982 return -ENOMEM;
983
984 /* Initialize our global data */
985 for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
986 serial_table[i] = NULL;
987 }
988
989 result = bus_register(&usb_serial_bus_type);
990 if (result) {
991 err("%s - registering bus driver failed", __FUNCTION__);
992 goto exit_bus;
993 }
994
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 usb_serial_tty_driver->owner = THIS_MODULE;
996 usb_serial_tty_driver->driver_name = "usbserial";
997 usb_serial_tty_driver->devfs_name = "usb/tts/";
998 usb_serial_tty_driver->name = "ttyUSB";
999 usb_serial_tty_driver->major = SERIAL_TTY_MAJOR;
1000 usb_serial_tty_driver->minor_start = 0;
1001 usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
1002 usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL;
1003 usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
1004 usb_serial_tty_driver->init_termios = tty_std_termios;
1005 usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1006 tty_set_operations(usb_serial_tty_driver, &serial_ops);
1007 result = tty_register_driver(usb_serial_tty_driver);
1008 if (result) {
1009 err("%s - tty_register_driver failed", __FUNCTION__);
1010 goto exit_reg_driver;
1011 }
1012
1013 /* register the USB driver */
1014 result = usb_register(&usb_serial_driver);
1015 if (result < 0) {
1016 err("%s - usb_register failed", __FUNCTION__);
1017 goto exit_tty;
1018 }
1019
Greg Kroah-Hartman06299db2005-05-26 05:55:55 -07001020 /* register the generic driver, if we should */
1021 result = usb_serial_generic_register(debug);
1022 if (result < 0) {
1023 err("%s - registering generic driver failed", __FUNCTION__);
1024 goto exit_generic;
1025 }
1026
Greg Kroah-Hartman17a882f2005-06-20 21:15:16 -07001027 info(DRIVER_DESC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028
1029 return result;
1030
Greg Kroah-Hartman06299db2005-05-26 05:55:55 -07001031exit_generic:
1032 usb_deregister(&usb_serial_driver);
1033
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034exit_tty:
1035 tty_unregister_driver(usb_serial_tty_driver);
1036
1037exit_reg_driver:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 bus_unregister(&usb_serial_bus_type);
1039
1040exit_bus:
1041 err ("%s - returning with error %d", __FUNCTION__, result);
1042 put_tty_driver(usb_serial_tty_driver);
1043 return result;
1044}
1045
1046
1047static void __exit usb_serial_exit(void)
1048{
1049 usb_serial_console_exit();
1050
1051 usb_serial_generic_deregister();
1052
1053 usb_deregister(&usb_serial_driver);
1054 tty_unregister_driver(usb_serial_tty_driver);
1055 put_tty_driver(usb_serial_tty_driver);
1056 bus_unregister(&usb_serial_bus_type);
1057}
1058
1059
1060module_init(usb_serial_init);
1061module_exit(usb_serial_exit);
1062
1063#define set_to_generic_if_null(type, function) \
1064 do { \
1065 if (!type->function) { \
1066 type->function = usb_serial_generic_##function; \
1067 dbg("Had to override the " #function \
1068 " usb serial operation with the generic one.");\
1069 } \
1070 } while (0)
1071
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -07001072static void fixup_generic(struct usb_serial_driver *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073{
1074 set_to_generic_if_null(device, open);
1075 set_to_generic_if_null(device, write);
1076 set_to_generic_if_null(device, close);
1077 set_to_generic_if_null(device, write_room);
1078 set_to_generic_if_null(device, chars_in_buffer);
1079 set_to_generic_if_null(device, read_bulk_callback);
1080 set_to_generic_if_null(device, write_bulk_callback);
1081 set_to_generic_if_null(device, shutdown);
1082}
1083
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -07001084int usb_serial_register(struct usb_serial_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085{
1086 int retval;
1087
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -07001088 fixup_generic(driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -07001090 if (!driver->description)
1091 driver->description = driver->driver.name;
1092
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093 /* Add this device to our list of devices */
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -07001094 list_add(&driver->driver_list, &usb_serial_driver_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -07001096 retval = usb_serial_bus_register(driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 if (retval) {
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -07001098 err("problem %d when registering driver %s", retval, driver->description);
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -07001099 list_del(&driver->driver_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 }
1101 else
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -07001102 info("USB Serial support registered for %s", driver->description);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103
1104 return retval;
1105}
1106
1107
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -07001108void usb_serial_deregister(struct usb_serial_driver *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109{
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -07001110 info("USB Serial deregistering driver %s", device->description);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 list_del(&device->driver_list);
1112 usb_serial_bus_deregister(device);
1113}
1114
1115
1116
1117/* If the usb-serial core is built into the core, the usb-serial drivers
1118 need these symbols to load properly as modules. */
1119EXPORT_SYMBOL_GPL(usb_serial_register);
1120EXPORT_SYMBOL_GPL(usb_serial_deregister);
1121EXPORT_SYMBOL_GPL(usb_serial_probe);
1122EXPORT_SYMBOL_GPL(usb_serial_disconnect);
1123EXPORT_SYMBOL_GPL(usb_serial_port_softint);
1124
1125
1126/* Module information */
1127MODULE_AUTHOR( DRIVER_AUTHOR );
1128MODULE_DESCRIPTION( DRIVER_DESC );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129MODULE_LICENSE("GPL");
1130
1131module_param(debug, bool, S_IRUGO | S_IWUSR);
1132MODULE_PARM_DESC(debug, "Debug enabled or not");