blob: ccc729d17a896b02a5208c10ab13ff3c923502ed [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * USB Serial Converter driver
3 *
Johan Hovold659597b72013-03-21 12:37:51 +01004 * Copyright (C) 2009 - 2013 Johan Hovold (jhovold@gmail.com)
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07005 * Copyright (C) 1999 - 2012 Greg Kroah-Hartman (greg@kroah.com)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 * Copyright (C) 2000 Peter Berger (pberger@brimson.com)
7 * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com)
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License version
11 * 2 as published by the Free Software Foundation.
12 *
Greg Kroah-Hartman502b95c2005-06-20 21:15:16 -070013 * This driver was originally based on the ACM driver by Armin Fuerst (which was
Linus Torvalds1da177e2005-04-16 15:20:36 -070014 * based on a driver by Brad Keryan)
15 *
Alan Coxa8d6f0a2008-07-22 11:12:24 +010016 * See Documentation/usb/usb-serial.txt for more information on using this
17 * driver
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 */
19
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -070020#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21
Linus Torvalds1da177e2005-04-16 15:20:36 -070022#include <linux/kernel.h>
23#include <linux/errno.h>
24#include <linux/init.h>
25#include <linux/slab.h>
26#include <linux/tty.h>
27#include <linux/tty_driver.h>
28#include <linux/tty_flip.h>
29#include <linux/module.h>
30#include <linux/moduleparam.h>
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -070031#include <linux/seq_file.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/spinlock.h>
Luiz Fernando Capitulino1ce7dd22006-03-24 17:12:31 -030033#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034#include <linux/list.h>
Alan Coxa8d6f0a2008-07-22 11:12:24 +010035#include <linux/uaccess.h>
Alan Coxc56d3002009-07-28 00:34:58 +010036#include <linux/serial.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070037#include <linux/usb.h>
Greg Kroah-Hartmana9698882006-07-11 21:22:58 -070038#include <linux/usb/serial.h>
David VomLehn8e8dce02009-08-28 12:54:27 -070039#include <linux/kfifo.h>
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070040#include <linux/idr.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include "pl2303.h"
42
Greg Kroah-Hartmanee42f6c2012-09-18 17:10:29 +010043#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#define DRIVER_DESC "USB Serial Driver core"
45
Greg Kroah-Hartman455b4f72013-06-06 10:31:35 -070046#define USB_SERIAL_TTY_MAJOR 188
47#define USB_SERIAL_TTY_MINORS 512 /* should be enough for a while */
48
Linus Torvalds1da177e2005-04-16 15:20:36 -070049/* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead
50 the MODULE_DEVICE_TABLE declarations in each serial driver
51 cause the "hotplug" program to pull in whatever module is necessary
52 via modprobe, and modprobe will load usbserial because the serial
53 drivers depend on it.
54*/
55
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070056static DEFINE_IDR(serial_minors);
Oliver Neukum3ddad822007-07-24 15:13:42 +020057static DEFINE_MUTEX(table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058static LIST_HEAD(usb_serial_driver_list);
59
Alan Stern8bc2c1b2009-09-01 11:38:59 -040060/*
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070061 * Look up the serial port structure. If it is found and it hasn't been
62 * disconnected, return with the parent usb_serial structure's disc_mutex held
63 * and its refcount incremented. Otherwise return NULL.
Alan Stern8bc2c1b2009-09-01 11:38:59 -040064 */
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070065struct usb_serial_port *usb_serial_port_get_by_minor(unsigned minor)
Linus Torvalds1da177e2005-04-16 15:20:36 -070066{
Oliver Neukum34ef50e2007-01-13 07:29:26 +010067 struct usb_serial *serial;
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070068 struct usb_serial_port *port;
Oliver Neukum34ef50e2007-01-13 07:29:26 +010069
Oliver Neukum3ddad822007-07-24 15:13:42 +020070 mutex_lock(&table_lock);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070071 port = idr_find(&serial_minors, minor);
72 if (!port)
73 goto exit;
Linus Torvalds1da177e2005-04-16 15:20:36 -070074
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070075 serial = port->serial;
76 mutex_lock(&serial->disc_mutex);
77 if (serial->disconnected) {
78 mutex_unlock(&serial->disc_mutex);
79 port = NULL;
80 } else {
81 kref_get(&serial->kref);
Alan Stern8bc2c1b2009-09-01 11:38:59 -040082 }
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070083exit:
Oliver Neukum3ddad822007-07-24 15:13:42 +020084 mutex_unlock(&table_lock);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070085 return port;
Linus Torvalds1da177e2005-04-16 15:20:36 -070086}
87
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070088static int allocate_minors(struct usb_serial *serial, int num_ports)
Linus Torvalds1da177e2005-04-16 15:20:36 -070089{
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070090 struct usb_serial_port *port;
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 unsigned int i, j;
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070092 int minor;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -070094 dev_dbg(&serial->interface->dev, "%s %d\n", __func__, num_ports);
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
Oliver Neukum3ddad822007-07-24 15:13:42 +020096 mutex_lock(&table_lock);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070097 for (i = 0; i < num_ports; ++i) {
98 port = serial->port[i];
Johan Hovold194e9582016-05-08 20:08:03 +020099 minor = idr_alloc(&serial_minors, port, 0,
100 USB_SERIAL_TTY_MINORS, GFP_KERNEL);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700101 if (minor < 0)
102 goto error;
103 port->minor = minor;
104 port->port_number = i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 }
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700106 serial->minors_reserved = 1;
Oliver Neukum3ddad822007-07-24 15:13:42 +0200107 mutex_unlock(&table_lock);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700108 return 0;
109error:
110 /* unwind the already allocated minors */
111 for (j = 0; j < i; ++j)
112 idr_remove(&serial_minors, serial->port[j]->minor);
113 mutex_unlock(&table_lock);
114 return minor;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115}
116
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700117static void release_minors(struct usb_serial *serial)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118{
119 int i;
120
Alan Stern8bc2c1b2009-09-01 11:38:59 -0400121 mutex_lock(&table_lock);
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100122 for (i = 0; i < serial->num_ports; ++i)
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700123 idr_remove(&serial_minors, serial->port[i]->minor);
Alan Stern8bc2c1b2009-09-01 11:38:59 -0400124 mutex_unlock(&table_lock);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700125 serial->minors_reserved = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126}
127
128static void destroy_serial(struct kref *kref)
129{
130 struct usb_serial *serial;
131 struct usb_serial_port *port;
132 int i;
133
134 serial = to_usb_serial(kref);
135
Jim Radford521b85a2007-03-13 08:30:50 -0700136 /* return the minor range that this device had */
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700137 if (serial->minors_reserved)
138 release_minors(serial);
Jim Radford521b85a2007-03-13 08:30:50 -0700139
Johan Hovold79b80b82013-03-21 12:36:43 +0100140 if (serial->attached && serial->type->release)
Alan Sterna4720c62009-10-09 12:43:12 -0400141 serial->type->release(serial);
Alan Sternf9c99bb2009-06-02 11:53:55 -0400142
Alan Stern41bd34d2009-09-01 11:38:34 -0400143 /* Now that nothing is using the ports, they can be freed */
144 for (i = 0; i < serial->num_port_pointers; ++i) {
Alan Sternf9c99bb2009-06-02 11:53:55 -0400145 port = serial->port[i];
Alan Stern41bd34d2009-09-01 11:38:34 -0400146 if (port) {
147 port->serial = NULL;
Alan Sternf9c99bb2009-06-02 11:53:55 -0400148 put_device(&port->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 }
150 }
151
Johan Hovoldd7971052013-03-19 09:21:09 +0100152 usb_put_intf(serial->interface);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153 usb_put_dev(serial->dev);
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100154 kfree(serial);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155}
156
Guennadi Liakhovetski73e487f2006-04-25 07:46:17 +0200157void usb_serial_put(struct usb_serial *serial)
158{
159 kref_put(&serial->kref, destroy_serial);
160}
161
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162/*****************************************************************************
163 * Driver tty interface functions
164 *****************************************************************************/
Alan Sternf5b09532009-09-01 11:38:44 -0400165
166/**
167 * serial_install - install tty
168 * @driver: the driver (USB in our case)
169 * @tty: the tty being created
170 *
171 * Create the termios objects for this tty. We use the default
172 * USB serial settings but permit them to be overridden by
173 * serial->type->init_termios.
Alan Sterncc56cd02009-09-01 11:39:13 -0400174 *
175 * This is the first place a new tty gets used. Hence this is where we
176 * acquire references to the usb_serial structure and the driver module,
177 * where we store a pointer to the port, and where we do an autoresume.
Dave Youngf278a2f2009-09-27 16:00:42 +0000178 * All these actions are reversed in serial_cleanup().
Alan Sternf5b09532009-09-01 11:38:44 -0400179 */
180static int serial_install(struct tty_driver *driver, struct tty_struct *tty)
181{
182 int idx = tty->index;
183 struct usb_serial *serial;
Alan Sterncc56cd02009-09-01 11:39:13 -0400184 struct usb_serial_port *port;
185 int retval = -ENODEV;
186
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700187 port = usb_serial_port_get_by_minor(idx);
188 if (!port)
Alan Sterncc56cd02009-09-01 11:39:13 -0400189 return retval;
190
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700191 serial = port->serial;
Alan Sterncc56cd02009-09-01 11:39:13 -0400192 if (!try_module_get(serial->type->driver.owner))
193 goto error_module_get;
194
195 retval = usb_autopm_get_interface(serial->interface);
196 if (retval)
197 goto error_get_interface;
Alan Sternf5b09532009-09-01 11:38:44 -0400198
Jiri Slabyca4ff102012-06-04 13:35:34 +0200199 retval = tty_port_install(&port->port, driver, tty);
Jiri Slaby76f82a72012-01-30 21:14:29 +0100200 if (retval)
201 goto error_init_termios;
202
Alan Sterncc56cd02009-09-01 11:39:13 -0400203 mutex_unlock(&serial->disc_mutex);
204
Alan Stern7e29bb42009-09-01 11:39:22 -0400205 /* allow the driver to update the settings */
206 if (serial->type->init_termios)
207 serial->type->init_termios(tty);
208
Alan Sterncc56cd02009-09-01 11:39:13 -0400209 tty->driver_data = port;
210
Alan Sterncc56cd02009-09-01 11:39:13 -0400211 return retval;
212
Alan Stern7e29bb42009-09-01 11:39:22 -0400213 error_init_termios:
Jiri Slaby76f82a72012-01-30 21:14:29 +0100214 usb_autopm_put_interface(serial->interface);
215 error_get_interface:
Alan Sterncc56cd02009-09-01 11:39:13 -0400216 module_put(serial->type->driver.owner);
217 error_module_get:
Alan Sterncc56cd02009-09-01 11:39:13 -0400218 usb_serial_put(serial);
219 mutex_unlock(&serial->disc_mutex);
220 return retval;
Alan Sternf5b09532009-09-01 11:38:44 -0400221}
222
Johan Hovold395e08d2013-03-21 12:36:23 +0100223static int serial_port_activate(struct tty_port *tport, struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224{
Alan Cox64bc3972009-10-06 16:06:11 +0100225 struct usb_serial_port *port =
226 container_of(tport, struct usb_serial_port, port);
Alan Stern320348c2009-09-01 11:39:59 -0400227 struct usb_serial *serial = port->serial;
228 int retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229
Alan Cox64bc3972009-10-06 16:06:11 +0100230 mutex_lock(&serial->disc_mutex);
231 if (serial->disconnected)
232 retval = -ENODEV;
233 else
234 retval = port->serial->type->open(tty, port);
235 mutex_unlock(&serial->disc_mutex);
Johan Hovold3827d872011-11-10 17:38:13 +0100236
237 if (retval < 0)
238 retval = usb_translate_errors(retval);
239
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 return retval;
241}
242
Alan Cox64bc3972009-10-06 16:06:11 +0100243static int serial_open(struct tty_struct *tty, struct file *filp)
244{
245 struct usb_serial_port *port = tty->driver_data;
246
Johan Hovoldd12e2112013-03-21 12:36:25 +0100247 dev_dbg(tty->dev, "%s\n", __func__);
248
Alan Cox64bc3972009-10-06 16:06:11 +0100249 return tty_port_open(&port->port, tty, filp);
250}
251
Alan Cox335f8512009-06-11 12:26:29 +0100252/**
Johan Hovold395e08d2013-03-21 12:36:23 +0100253 * serial_port_shutdown - shut down hardware
Alan Coxe1108a62009-10-06 16:06:36 +0100254 * @tport: tty port to shut down
Alan Cox335f8512009-06-11 12:26:29 +0100255 *
Peter Hurley8a7298d2013-02-23 10:11:35 -0500256 * Shut down a USB serial port. Serialized against activate by the
257 * tport mutex and kept to matching open/close pairs
Peter Hurleyd41861c2016-04-09 17:53:25 -0700258 * of calls by the initialized flag.
Peter Hurley8a7298d2013-02-23 10:11:35 -0500259 *
260 * Not called if tty is console.
Alan Cox335f8512009-06-11 12:26:29 +0100261 */
Johan Hovold395e08d2013-03-21 12:36:23 +0100262static void serial_port_shutdown(struct tty_port *tport)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263{
Alan Coxe1108a62009-10-06 16:06:36 +0100264 struct usb_serial_port *port =
265 container_of(tport, struct usb_serial_port, port);
Alan Cox335f8512009-06-11 12:26:29 +0100266 struct usb_serial_driver *drv = port->serial->type;
Peter Hurley8a7298d2013-02-23 10:11:35 -0500267
Alan Cox335f8512009-06-11 12:26:29 +0100268 if (drv->close)
269 drv->close(port);
Alan Cox335f8512009-06-11 12:26:29 +0100270}
271
Alan Sternf5b09532009-09-01 11:38:44 -0400272static void serial_hangup(struct tty_struct *tty)
Alan Cox335f8512009-06-11 12:26:29 +0100273{
Alan Cox4455e342009-09-19 13:13:24 -0700274 struct usb_serial_port *port = tty->driver_data;
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700275
Johan Hovoldd12e2112013-03-21 12:36:25 +0100276 dev_dbg(tty->dev, "%s\n", __func__);
277
Alan Sternf5b09532009-09-01 11:38:44 -0400278 tty_port_hangup(&port->port);
Alan Cox335f8512009-06-11 12:26:29 +0100279}
280
281static void serial_close(struct tty_struct *tty, struct file *filp)
282{
283 struct usb_serial_port *port = tty->driver_data;
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700284
Johan Hovoldd12e2112013-03-21 12:36:25 +0100285 dev_dbg(tty->dev, "%s\n", __func__);
286
Alan Coxe1108a62009-10-06 16:06:36 +0100287 tty_port_close(&port->port, tty, filp);
Alan Cox335f8512009-06-11 12:26:29 +0100288}
289
Alan Sternf5b09532009-09-01 11:38:44 -0400290/**
Dave Youngf278a2f2009-09-27 16:00:42 +0000291 * serial_cleanup - free resources post close/hangup
Alan Sternf5b09532009-09-01 11:38:44 -0400292 * @port: port to free up
293 *
294 * Do the resource freeing and refcount dropping for the port.
295 * Avoid freeing the console.
296 *
Alan Cox36b3c072012-07-17 17:06:57 +0100297 * Called asynchronously after the last tty kref is dropped.
Alan Sternf5b09532009-09-01 11:38:44 -0400298 */
Dave Youngf278a2f2009-09-27 16:00:42 +0000299static void serial_cleanup(struct tty_struct *tty)
Alan Cox335f8512009-06-11 12:26:29 +0100300{
301 struct usb_serial_port *port = tty->driver_data;
Alan Sternf5b09532009-09-01 11:38:44 -0400302 struct usb_serial *serial;
303 struct module *owner;
304
Johan Hovoldd12e2112013-03-21 12:36:25 +0100305 dev_dbg(tty->dev, "%s\n", __func__);
306
Alan Sternf5b09532009-09-01 11:38:44 -0400307 /* The console is magical. Do not hang up the console hardware
308 * or there will be tears.
309 */
Jason Wesselbd5afa92010-03-08 21:50:12 -0600310 if (port->port.console)
Alan Sternf5b09532009-09-01 11:38:44 -0400311 return;
312
Alan Sterncc56cd02009-09-01 11:39:13 -0400313 tty->driver_data = NULL;
314
Alan Sternf5b09532009-09-01 11:38:44 -0400315 serial = port->serial;
316 owner = serial->type->driver.owner;
317
318 mutex_lock(&serial->disc_mutex);
319 if (!serial->disconnected)
320 usb_autopm_put_interface(serial->interface);
321 mutex_unlock(&serial->disc_mutex);
322
323 usb_serial_put(serial);
324 module_put(owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325}
326
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100327static int serial_write(struct tty_struct *tty, const unsigned char *buf,
328 int count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200330 struct usb_serial_port *port = tty->driver_data;
Oliver Neukum3ff4fd92007-01-13 07:32:27 +0100331 int retval = -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332
Alan Coxf34d7a52008-04-30 00:54:13 -0700333 if (port->serial->dev->state == USB_STATE_NOTATTACHED)
Luiz Fernando Capitulino487f9c62005-11-28 19:16:05 -0200334 goto exit;
335
Johan Hovoldd12e2112013-03-21 12:36:25 +0100336 dev_dbg(tty->dev, "%s - %d byte(s)\n", __func__, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337
Alan Cox95da3102008-07-22 11:09:07 +0100338 retval = port->serial->type->write(tty, port, buf, count);
Johan Hovoldc6249ff2011-11-10 17:40:44 +0100339 if (retval < 0)
340 retval = usb_translate_errors(retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341exit:
342 return retval;
343}
344
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100345static int serial_write_room(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200347 struct usb_serial_port *port = tty->driver_data;
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700348
Johan Hovoldd12e2112013-03-21 12:36:25 +0100349 dev_dbg(tty->dev, "%s\n", __func__);
Johan Hovold9993b422013-03-21 12:36:24 +0100350
Alan Cox95da3102008-07-22 11:09:07 +0100351 return port->serial->type->write_room(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352}
353
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100354static int serial_chars_in_buffer(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200356 struct usb_serial_port *port = tty->driver_data;
Johan Hovold810360a2013-01-14 16:52:56 +0100357 struct usb_serial *serial = port->serial;
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700358
Johan Hovoldd12e2112013-03-21 12:36:25 +0100359 dev_dbg(tty->dev, "%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360
Johan Hovold810360a2013-01-14 16:52:56 +0100361 if (serial->disconnected)
Johan Hovold4746b6c2013-05-05 20:32:33 +0200362 return 0;
Johan Hovold810360a2013-01-14 16:52:56 +0100363
Johan Hovold4746b6c2013-05-05 20:32:33 +0200364 return serial->type->chars_in_buffer(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365}
366
Johan Hovold06931962013-05-05 20:32:27 +0200367static void serial_wait_until_sent(struct tty_struct *tty, int timeout)
368{
369 struct usb_serial_port *port = tty->driver_data;
370 struct usb_serial *serial = port->serial;
371
372 dev_dbg(tty->dev, "%s\n", __func__);
373
374 if (!port->serial->type->wait_until_sent)
375 return;
376
377 mutex_lock(&serial->disc_mutex);
378 if (!serial->disconnected)
379 port->serial->type->wait_until_sent(tty, timeout);
380 mutex_unlock(&serial->disc_mutex);
381}
382
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100383static void serial_throttle(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200385 struct usb_serial_port *port = tty->driver_data;
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700386
Johan Hovoldd12e2112013-03-21 12:36:25 +0100387 dev_dbg(tty->dev, "%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 if (port->serial->type->throttle)
Alan Cox95da3102008-07-22 11:09:07 +0100390 port->serial->type->throttle(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391}
392
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100393static void serial_unthrottle(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200395 struct usb_serial_port *port = tty->driver_data;
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700396
Johan Hovoldd12e2112013-03-21 12:36:25 +0100397 dev_dbg(tty->dev, "%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 if (port->serial->type->unthrottle)
Alan Cox95da3102008-07-22 11:09:07 +0100400 port->serial->type->unthrottle(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401}
402
Alan Cox6caa76b2011-02-14 16:27:22 +0000403static int serial_ioctl(struct tty_struct *tty,
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100404 unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200406 struct usb_serial_port *port = tty->driver_data;
Johan Hovoldf4488032013-06-05 12:21:11 +0200407 int retval = -ENOIOCTLCMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Johan Hovold4d5147e2013-12-29 19:22:55 +0100409 dev_dbg(tty->dev, "%s - cmd 0x%04x\n", __func__, cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
Johan Hovold143d9d92013-03-21 12:36:51 +0100411 switch (cmd) {
412 case TIOCMIWAIT:
413 if (port->serial->type->tiocmiwait)
414 retval = port->serial->type->tiocmiwait(tty, arg);
415 break;
416 default:
417 if (port->serial->type->ioctl)
418 retval = port->serial->type->ioctl(tty, cmd, arg);
Johan Hovold143d9d92013-03-21 12:36:51 +0100419 }
Johan Hovold9993b422013-03-21 12:36:24 +0100420
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 return retval;
422}
423
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100424static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200426 struct usb_serial_port *port = tty->driver_data;
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700427
Johan Hovoldd12e2112013-03-21 12:36:25 +0100428 dev_dbg(tty->dev, "%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 if (port->serial->type->set_termios)
Alan Cox95da3102008-07-22 11:09:07 +0100431 port->serial->type->set_termios(tty, port, old);
Alan Cox33785092007-10-18 01:24:22 -0700432 else
Alan Coxadc8d742012-07-14 15:31:47 +0100433 tty_termios_copy_hw(&tty->termios, old);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434}
435
Alan Cox9e989662008-07-22 11:18:03 +0100436static int serial_break(struct tty_struct *tty, int break_state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200438 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439
Johan Hovoldd12e2112013-03-21 12:36:25 +0100440 dev_dbg(tty->dev, "%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441
Alan Cox6b447f042009-01-02 13:48:56 +0000442 if (port->serial->type->break_ctl)
Alan Cox95da3102008-07-22 11:09:07 +0100443 port->serial->type->break_ctl(tty, break_state);
Johan Hovold9993b422013-03-21 12:36:24 +0100444
Alan Cox9e989662008-07-22 11:18:03 +0100445 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446}
447
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700448static int serial_proc_show(struct seq_file *m, void *v)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449{
450 struct usb_serial *serial;
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700451 struct usb_serial_port *port;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 char tmp[40];
454
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700455 seq_puts(m, "usbserinfo:1.0 driver:2.0\n");
Greg Kroah-Hartman455b4f72013-06-06 10:31:35 -0700456 for (i = 0; i < USB_SERIAL_TTY_MINORS; ++i) {
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700457 port = usb_serial_port_get_by_minor(i);
458 if (port == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459 continue;
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700460 serial = port->serial;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700462 seq_printf(m, "%d:", i);
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700463 if (serial->type->driver.owner)
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700464 seq_printf(m, " module:%s",
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100465 module_name(serial->type->driver.owner));
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700466 seq_printf(m, " name:\"%s\"",
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100467 serial->type->description);
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700468 seq_printf(m, " vendor:%04x product:%04x",
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100469 le16_to_cpu(serial->dev->descriptor.idVendor),
470 le16_to_cpu(serial->dev->descriptor.idProduct));
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700471 seq_printf(m, " num_ports:%d", serial->num_ports);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700472 seq_printf(m, " port:%d", port->port_number);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 usb_make_path(serial->dev, tmp, sizeof(tmp));
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700474 seq_printf(m, " path:%s", tmp);
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100475
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700476 seq_putc(m, '\n');
Guennadi Liakhovetski73e487f2006-04-25 07:46:17 +0200477 usb_serial_put(serial);
Alan Stern8bc2c1b2009-09-01 11:38:59 -0400478 mutex_unlock(&serial->disc_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 }
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700480 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481}
482
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700483static int serial_proc_open(struct inode *inode, struct file *file)
484{
485 return single_open(file, serial_proc_show, NULL);
486}
487
488static const struct file_operations serial_proc_fops = {
489 .owner = THIS_MODULE,
490 .open = serial_proc_open,
491 .read = seq_read,
492 .llseek = seq_lseek,
493 .release = single_release,
494};
495
Alan Cox60b33c12011-02-14 16:26:14 +0000496static int serial_tiocmget(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200498 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499
Johan Hovoldd12e2112013-03-21 12:36:25 +0100500 dev_dbg(tty->dev, "%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502 if (port->serial->type->tiocmget)
Alan Cox60b33c12011-02-14 16:26:14 +0000503 return port->serial->type->tiocmget(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 return -EINVAL;
505}
506
Alan Cox20b9d172011-02-14 16:26:50 +0000507static int serial_tiocmset(struct tty_struct *tty,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 unsigned int set, unsigned int clear)
509{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200510 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511
Johan Hovoldd12e2112013-03-21 12:36:25 +0100512 dev_dbg(tty->dev, "%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 if (port->serial->type->tiocmset)
Alan Cox20b9d172011-02-14 16:26:50 +0000515 return port->serial->type->tiocmset(tty, set, clear);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 return -EINVAL;
517}
518
Alan Coxd281da72010-09-16 18:21:24 +0100519static int serial_get_icount(struct tty_struct *tty,
520 struct serial_icounter_struct *icount)
521{
522 struct usb_serial_port *port = tty->driver_data;
523
Johan Hovoldd12e2112013-03-21 12:36:25 +0100524 dev_dbg(tty->dev, "%s\n", __func__);
Alan Coxd281da72010-09-16 18:21:24 +0100525
526 if (port->serial->type->get_icount)
527 return port->serial->type->get_icount(tty, icount);
528 return -EINVAL;
529}
530
Pete Zaitcevcf2c7482006-05-22 21:58:49 -0700531/*
532 * We would be calling tty_wakeup here, but unfortunately some line
533 * disciplines have an annoying habit of calling tty->write from
534 * the write wakeup callback (e.g. n_hdlc.c).
535 */
536void usb_serial_port_softint(struct usb_serial_port *port)
537{
538 schedule_work(&port->work);
539}
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100540EXPORT_SYMBOL_GPL(usb_serial_port_softint);
Pete Zaitcevcf2c7482006-05-22 21:58:49 -0700541
David Howellsc4028952006-11-22 14:57:56 +0000542static void usb_serial_port_work(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543{
David Howellsc4028952006-11-22 14:57:56 +0000544 struct usb_serial_port *port =
545 container_of(work, struct usb_serial_port, work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546
Jiri Slaby6aad04f2013-03-07 13:12:29 +0100547 tty_port_tty_wakeup(&port->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548}
549
Johan Hovold6a5c8212013-03-21 12:36:49 +0100550static void usb_serial_port_poison_urbs(struct usb_serial_port *port)
Pete Zaitcev34f8e762006-06-21 15:00:45 -0700551{
Johan Hovold27c7acf2010-05-05 23:57:37 +0200552 int i;
553
Johan Hovoldd83b4052011-11-06 19:06:37 +0100554 for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i)
Johan Hovold6a5c8212013-03-21 12:36:49 +0100555 usb_poison_urb(port->read_urbs[i]);
Johan Hovold27c7acf2010-05-05 23:57:37 +0200556 for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i)
Johan Hovold6a5c8212013-03-21 12:36:49 +0100557 usb_poison_urb(port->write_urbs[i]);
558
559 usb_poison_urb(port->interrupt_in_urb);
560 usb_poison_urb(port->interrupt_out_urb);
Oliver Neukum34ef50e2007-01-13 07:29:26 +0100561}
562
Johan Hovold6a5c8212013-03-21 12:36:49 +0100563static void usb_serial_port_unpoison_urbs(struct usb_serial_port *port)
564{
565 int i;
566
567 for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i)
568 usb_unpoison_urb(port->read_urbs[i]);
569 for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i)
570 usb_unpoison_urb(port->write_urbs[i]);
571
572 usb_unpoison_urb(port->interrupt_in_urb);
573 usb_unpoison_urb(port->interrupt_out_urb);
Oliver Neukum34ef50e2007-01-13 07:29:26 +0100574}
575
Johan Hovold69a3d212013-03-21 12:36:47 +0100576static void usb_serial_port_release(struct device *dev)
Oliver Neukum34ef50e2007-01-13 07:29:26 +0100577{
Alan Stern41bd34d2009-09-01 11:38:34 -0400578 struct usb_serial_port *port = to_usb_serial_port(dev);
Johan Hovold27c7acf2010-05-05 23:57:37 +0200579 int i;
Alan Stern41bd34d2009-09-01 11:38:34 -0400580
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700581 dev_dbg(dev, "%s\n", __func__);
Alan Stern41bd34d2009-09-01 11:38:34 -0400582
Oliver Neukum34ef50e2007-01-13 07:29:26 +0100583 usb_free_urb(port->interrupt_in_urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 usb_free_urb(port->interrupt_out_urb);
Johan Hovoldd83b4052011-11-06 19:06:37 +0100585 for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) {
586 usb_free_urb(port->read_urbs[i]);
587 kfree(port->bulk_in_buffers[i]);
588 }
Johan Hovold27c7acf2010-05-05 23:57:37 +0200589 for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) {
590 usb_free_urb(port->write_urbs[i]);
591 kfree(port->bulk_out_buffers[i]);
592 }
Stefani Seibold119eecc2009-12-23 09:10:48 +0100593 kfifo_free(&port->write_fifo);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 kfree(port->interrupt_in_buffer);
595 kfree(port->interrupt_out_buffer);
Jiri Slaby191c5f12012-11-15 09:49:56 +0100596 tty_port_destroy(&port->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 kfree(port);
598}
599
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100600static struct usb_serial *create_serial(struct usb_device *dev,
601 struct usb_interface *interface,
602 struct usb_serial_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603{
604 struct usb_serial *serial;
605
Eric Sesterhenn80b6ca42006-02-27 21:29:43 +0100606 serial = kzalloc(sizeof(*serial), GFP_KERNEL);
Johan Hovold6b03f7f2013-03-21 12:36:26 +0100607 if (!serial)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 serial->dev = usb_get_dev(dev);
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700610 serial->type = driver;
Johan Hovoldd7971052013-03-19 09:21:09 +0100611 serial->interface = usb_get_intf(interface);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612 kref_init(&serial->kref);
Oliver Neukuma1cd7e92008-01-16 17:18:52 +0100613 mutex_init(&serial->disc_mutex);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700614 serial->minors_reserved = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615
616 return serial;
617}
618
Greg Kroah-Hartman93bacef2006-12-17 21:50:23 +0100619static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf,
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100620 struct usb_serial_driver *drv)
Greg Kroah-Hartman93bacef2006-12-17 21:50:23 +0100621{
622 struct usb_dynid *dynid;
623
624 spin_lock(&drv->dynids.lock);
625 list_for_each_entry(dynid, &drv->dynids.list, node) {
626 if (usb_match_one_id(intf, &dynid->id)) {
627 spin_unlock(&drv->dynids.lock);
628 return &dynid->id;
629 }
630 }
631 spin_unlock(&drv->dynids.lock);
632 return NULL;
633}
634
635static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv,
636 struct usb_interface *intf)
637{
638 const struct usb_device_id *id;
639
640 id = usb_match_id(intf, drv->id_table);
641 if (id) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700642 dev_dbg(&intf->dev, "static descriptor matches\n");
Greg Kroah-Hartman93bacef2006-12-17 21:50:23 +0100643 goto exit;
644 }
645 id = match_dynamic_id(intf, drv);
646 if (id)
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700647 dev_dbg(&intf->dev, "dynamic descriptor matches\n");
Greg Kroah-Hartman93bacef2006-12-17 21:50:23 +0100648exit:
649 return id;
650}
651
Andi Kleen0daeed32010-06-01 23:04:42 +0200652/* Caller must hold table_lock */
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100653static struct usb_serial_driver *search_serial_device(
654 struct usb_interface *iface)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655{
Bjørn Mork954c3f82012-05-30 10:00:14 +0200656 const struct usb_device_id *id = NULL;
Alan Stern063a2da2007-10-10 16:24:06 -0400657 struct usb_serial_driver *drv;
Bjørn Mork954c3f82012-05-30 10:00:14 +0200658 struct usb_driver *driver = to_usb_driver(iface->dev.driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659
Adrian Bunk93b1fae2006-01-10 00:13:33 +0100660 /* Check if the usb id matches a known device */
Alan Stern063a2da2007-10-10 16:24:06 -0400661 list_for_each_entry(drv, &usb_serial_driver_list, driver_list) {
Bjørn Mork954c3f82012-05-30 10:00:14 +0200662 if (drv->usb_driver == driver)
663 id = get_iface_id(drv, iface);
Greg Kroah-Hartman93bacef2006-12-17 21:50:23 +0100664 if (id)
Alan Stern063a2da2007-10-10 16:24:06 -0400665 return drv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 }
667
668 return NULL;
669}
670
Johan Hovold395e08d2013-03-21 12:36:23 +0100671static int serial_port_carrier_raised(struct tty_port *port)
Alan Cox335f8512009-06-11 12:26:29 +0100672{
673 struct usb_serial_port *p = container_of(port, struct usb_serial_port, port);
674 struct usb_serial_driver *drv = p->serial->type;
Johan Hovold3e1f4902011-11-10 17:40:43 +0100675
Alan Cox335f8512009-06-11 12:26:29 +0100676 if (drv->carrier_raised)
677 return drv->carrier_raised(p);
678 /* No carrier control - don't block */
Johan Hovold3e1f4902011-11-10 17:40:43 +0100679 return 1;
Alan Cox335f8512009-06-11 12:26:29 +0100680}
681
Johan Hovold395e08d2013-03-21 12:36:23 +0100682static void serial_port_dtr_rts(struct tty_port *port, int on)
Alan Cox335f8512009-06-11 12:26:29 +0100683{
684 struct usb_serial_port *p = container_of(port, struct usb_serial_port, port);
Johan Hovoldf5f45302013-06-26 16:47:22 +0200685 struct usb_serial_driver *drv = p->serial->type;
Johan Hovold3e1f4902011-11-10 17:40:43 +0100686
Johan Hovoldf5f45302013-06-26 16:47:22 +0200687 if (drv->dtr_rts)
Alan Cox335f8512009-06-11 12:26:29 +0100688 drv->dtr_rts(p, on);
689}
690
Johan Hovold2deb96b2015-02-18 10:34:52 +0700691static ssize_t port_number_show(struct device *dev,
692 struct device_attribute *attr, char *buf)
693{
694 struct usb_serial_port *port = to_usb_serial_port(dev);
695
696 return sprintf(buf, "%u\n", port->port_number);
697}
698static DEVICE_ATTR_RO(port_number);
699
700static struct attribute *usb_serial_port_attrs[] = {
701 &dev_attr_port_number.attr,
702 NULL
703};
704ATTRIBUTE_GROUPS(usb_serial_port);
705
Alan Cox335f8512009-06-11 12:26:29 +0100706static const struct tty_port_operations serial_port_ops = {
Johan Hovold395e08d2013-03-21 12:36:23 +0100707 .carrier_raised = serial_port_carrier_raised,
708 .dtr_rts = serial_port_dtr_rts,
709 .activate = serial_port_activate,
710 .shutdown = serial_port_shutdown,
Alan Cox335f8512009-06-11 12:26:29 +0100711};
712
Johan Hovold1546e6a2014-08-21 19:33:25 +0200713struct usb_serial_endpoints {
714 unsigned char num_bulk_in;
715 unsigned char num_bulk_out;
716 unsigned char num_interrupt_in;
717 unsigned char num_interrupt_out;
718 struct usb_endpoint_descriptor *bulk_in[MAX_NUM_PORTS];
719 struct usb_endpoint_descriptor *bulk_out[MAX_NUM_PORTS];
720 struct usb_endpoint_descriptor *interrupt_in[MAX_NUM_PORTS];
721 struct usb_endpoint_descriptor *interrupt_out[MAX_NUM_PORTS];
722};
723
724static void find_endpoints(struct usb_serial *serial,
725 struct usb_serial_endpoints *epds)
726{
727 struct device *dev = &serial->interface->dev;
728 struct usb_host_interface *iface_desc;
729 struct usb_endpoint_descriptor *epd;
730 unsigned int i;
731
Johan Hovold8520ac02017-03-02 12:51:18 +0100732 BUILD_BUG_ON(ARRAY_SIZE(epds->bulk_in) < USB_MAXENDPOINTS / 2);
733 BUILD_BUG_ON(ARRAY_SIZE(epds->bulk_out) < USB_MAXENDPOINTS / 2);
734 BUILD_BUG_ON(ARRAY_SIZE(epds->interrupt_in) < USB_MAXENDPOINTS / 2);
735 BUILD_BUG_ON(ARRAY_SIZE(epds->interrupt_out) < USB_MAXENDPOINTS / 2);
736
Johan Hovold1546e6a2014-08-21 19:33:25 +0200737 iface_desc = serial->interface->cur_altsetting;
738 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
739 epd = &iface_desc->endpoint[i].desc;
740
741 if (usb_endpoint_is_bulk_in(epd)) {
742 dev_dbg(dev, "found bulk in on endpoint %u\n", i);
Johan Hovold1546e6a2014-08-21 19:33:25 +0200743 epds->bulk_in[epds->num_bulk_in++] = epd;
744 } else if (usb_endpoint_is_bulk_out(epd)) {
745 dev_dbg(dev, "found bulk out on endpoint %u\n", i);
Johan Hovold1546e6a2014-08-21 19:33:25 +0200746 epds->bulk_out[epds->num_bulk_out++] = epd;
747 } else if (usb_endpoint_is_int_in(epd)) {
748 dev_dbg(dev, "found interrupt in on endpoint %u\n", i);
Johan Hovold1546e6a2014-08-21 19:33:25 +0200749 epds->interrupt_in[epds->num_interrupt_in++] = epd;
750 } else if (usb_endpoint_is_int_out(epd)) {
751 dev_dbg(dev, "found interrupt out on endpoint %u\n", i);
Johan Hovold1546e6a2014-08-21 19:33:25 +0200752 epds->interrupt_out[epds->num_interrupt_out++] = epd;
753 }
754 }
755}
756
Greg Kroah-Hartman2edd2842012-05-07 14:46:48 -0700757static int usb_serial_probe(struct usb_interface *interface,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 const struct usb_device_id *id)
759{
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700760 struct device *ddev = &interface->dev;
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100761 struct usb_device *dev = interface_to_usbdev(interface);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762 struct usb_serial *serial = NULL;
763 struct usb_serial_port *port;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 struct usb_endpoint_descriptor *endpoint;
Johan Hovold1546e6a2014-08-21 19:33:25 +0200765 struct usb_serial_endpoints *epds;
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700766 struct usb_serial_driver *type = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 int retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 int buffer_size;
769 int i;
Johan Hovoldd83b4052011-11-06 19:06:37 +0100770 int j;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 int num_ports = 0;
Johan Hovoldef88f332017-03-02 12:51:15 +0100772 unsigned char max_endpoints;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773
Andi Kleen0daeed32010-06-01 23:04:42 +0200774 mutex_lock(&table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 type = search_serial_device(interface);
776 if (!type) {
Andi Kleen0daeed32010-06-01 23:04:42 +0200777 mutex_unlock(&table_lock);
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700778 dev_dbg(ddev, "none matched\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779 return -ENODEV;
780 }
781
Andi Kleen0daeed32010-06-01 23:04:42 +0200782 if (!try_module_get(type->driver.owner)) {
783 mutex_unlock(&table_lock);
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700784 dev_err(ddev, "module get failed, exiting\n");
Andi Kleen0daeed32010-06-01 23:04:42 +0200785 return -EIO;
786 }
787 mutex_unlock(&table_lock);
788
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100789 serial = create_serial(dev, interface, type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 if (!serial) {
Johan Hovoldc2fef452017-03-02 12:51:14 +0100791 retval = -ENOMEM;
792 goto err_put_module;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 }
794
795 /* if this device type has a probe function, call it */
796 if (type->probe) {
797 const struct usb_device_id *id;
798
Greg Kroah-Hartman93bacef2006-12-17 21:50:23 +0100799 id = get_iface_id(type, interface);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 retval = type->probe(serial, id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801
802 if (retval) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700803 dev_dbg(ddev, "sub driver rejected device\n");
Johan Hovoldc2fef452017-03-02 12:51:14 +0100804 goto err_put_serial;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 }
806 }
807
808 /* descriptor matches, let's find the endpoints needed */
Johan Hovold1546e6a2014-08-21 19:33:25 +0200809 epds = kzalloc(sizeof(*epds), GFP_KERNEL);
810 if (!epds) {
811 retval = -ENOMEM;
812 goto err_put_serial;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 }
814
Johan Hovold1546e6a2014-08-21 19:33:25 +0200815 find_endpoints(serial, epds);
816
Javier Martinez Canillas8c34d822016-04-20 14:26:58 -0400817#if IS_ENABLED(CONFIG_USB_SERIAL_PL2303)
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100818 /* BEGIN HORRIBLE HACK FOR PL2303 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 /* this is needed due to the looney way its endpoints are set up */
820 if (((le16_to_cpu(dev->descriptor.idVendor) == PL2303_VENDOR_ID) &&
821 (le16_to_cpu(dev->descriptor.idProduct) == PL2303_PRODUCT_ID)) ||
822 ((le16_to_cpu(dev->descriptor.idVendor) == ATEN_VENDOR_ID) &&
Johannes Steingraeber8fd80132006-09-16 16:17:34 +0200823 (le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID)) ||
824 ((le16_to_cpu(dev->descriptor.idVendor) == ALCOR_VENDOR_ID) &&
Andreas Bombece816cf2008-09-14 01:58:55 +0200825 (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID)) ||
826 ((le16_to_cpu(dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) &&
827 (le16_to_cpu(dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_EF81))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828 if (interface != dev->actconfig->interface[0]) {
Johan Hovold1546e6a2014-08-21 19:33:25 +0200829 struct usb_host_interface *iface_desc;
830
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 /* check out the endpoints of the other interface*/
832 iface_desc = dev->actconfig->interface[0]->cur_altsetting;
833 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
834 endpoint = &iface_desc->endpoint[i].desc;
Luiz Fernando N. Capitulino4fa1bbf2006-09-27 11:58:53 -0700835 if (usb_endpoint_is_int_in(endpoint)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 /* we found a interrupt in endpoint */
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700837 dev_dbg(ddev, "found interrupt in for Prolific device on separate interface\n");
Johan Hovold1546e6a2014-08-21 19:33:25 +0200838 if (epds->num_interrupt_in < ARRAY_SIZE(epds->interrupt_in))
839 epds->interrupt_in[epds->num_interrupt_in++] = endpoint;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 }
841 }
842 }
843
844 /* Now make sure the PL-2303 is configured correctly.
845 * If not, give up now and hope this hack will work
846 * properly during a later invocation of usb_serial_probe
847 */
Johan Hovold1546e6a2014-08-21 19:33:25 +0200848 if (epds->num_bulk_in == 0 || epds->num_bulk_out == 0) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700849 dev_info(ddev, "PL-2303 hack: descriptors matched but endpoints did not\n");
Johan Hovoldc2fef452017-03-02 12:51:14 +0100850 retval = -ENODEV;
Johan Hovold1546e6a2014-08-21 19:33:25 +0200851 kfree(epds);
Johan Hovoldc2fef452017-03-02 12:51:14 +0100852 goto err_put_serial;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 }
854 }
855 /* END HORRIBLE HACK FOR PL2303 */
856#endif
857
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858#ifdef CONFIG_USB_SERIAL_GENERIC
859 if (type == &usb_serial_generic_device) {
Johan Hovold1546e6a2014-08-21 19:33:25 +0200860 num_ports = epds->num_bulk_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861 if (num_ports == 0) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700862 dev_err(ddev, "Generic device with no bulk out, not allowed.\n");
Johan Hovoldc2fef452017-03-02 12:51:14 +0100863 retval = -EIO;
Johan Hovold1546e6a2014-08-21 19:33:25 +0200864 kfree(epds);
Johan Hovoldc2fef452017-03-02 12:51:14 +0100865 goto err_put_serial;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 }
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700867 dev_info(ddev, "The \"generic\" usb-serial driver is only for testing and one-off prototypes.\n");
868 dev_info(ddev, "Tell linux-usb@vger.kernel.org to add your device to a proper driver.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 }
870#endif
871 if (!num_ports) {
872 /* if this device type has a calc_num_ports function, call it */
Ming Leid92a3ca2010-08-07 16:20:35 +0800873 if (type->calc_num_ports)
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100874 num_ports = type->calc_num_ports(serial);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 if (!num_ports)
876 num_ports = type->num_ports;
877 }
878
Johan Hovold56546992014-08-27 11:55:19 +0200879 if (num_ports > MAX_NUM_PORTS) {
880 dev_warn(ddev, "too many ports requested: %d\n", num_ports);
881 num_ports = MAX_NUM_PORTS;
882 }
883
Johan Hovoldef88f332017-03-02 12:51:15 +0100884 serial->num_ports = (unsigned char)num_ports;
Johan Hovold1546e6a2014-08-21 19:33:25 +0200885 serial->num_bulk_in = epds->num_bulk_in;
886 serial->num_bulk_out = epds->num_bulk_out;
887 serial->num_interrupt_in = epds->num_interrupt_in;
888 serial->num_interrupt_out = epds->num_interrupt_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889
Alan Stern063a2da2007-10-10 16:24:06 -0400890 /* found all that we need */
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700891 dev_info(ddev, "%s converter detected\n", type->description);
Alan Stern063a2da2007-10-10 16:24:06 -0400892
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 /* create our ports, we need as many as the max endpoints */
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100894 /* we don't use num_ports here because some devices have more
895 endpoint pairs than ports */
Johan Hovold1546e6a2014-08-21 19:33:25 +0200896 max_endpoints = max(epds->num_bulk_in, epds->num_bulk_out);
897 max_endpoints = max(max_endpoints, epds->num_interrupt_in);
898 max_endpoints = max(max_endpoints, epds->num_interrupt_out);
Johan Hovoldef88f332017-03-02 12:51:15 +0100899 max_endpoints = max(max_endpoints, serial->num_ports);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 serial->num_port_pointers = max_endpoints;
Oliver Neukum4b10f0f2007-01-13 07:31:27 +0100901
Johan Hovoldd9a38a82014-03-12 19:09:42 +0100902 dev_dbg(ddev, "setting up %d port structure(s)\n", max_endpoints);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 for (i = 0; i < max_endpoints; ++i) {
Eric Sesterhenn80b6ca42006-02-27 21:29:43 +0100904 port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 if (!port)
906 goto probe_error;
Alan Cox4a90f092008-10-13 10:39:46 +0100907 tty_port_init(&port->port);
Alan Cox335f8512009-06-11 12:26:29 +0100908 port->port.ops = &serial_port_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 port->serial = serial;
Greg Kroah-Hartman507ca9b2005-04-23 12:49:16 -0700910 spin_lock_init(&port->lock);
Alan Coxe1108a62009-10-06 16:06:36 +0100911 /* Keep this for private driver use for the moment but
912 should probably go away */
David Howellsc4028952006-11-22 14:57:56 +0000913 INIT_WORK(&port->work, usb_serial_port_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 serial->port[i] = port;
Alan Stern41bd34d2009-09-01 11:38:34 -0400915 port->dev.parent = &interface->dev;
916 port->dev.driver = NULL;
917 port->dev.bus = &usb_serial_bus_type;
Johan Hovold69a3d212013-03-21 12:36:47 +0100918 port->dev.release = &usb_serial_port_release;
Johan Hovold2deb96b2015-02-18 10:34:52 +0700919 port->dev.groups = usb_serial_port_groups;
Alan Stern41bd34d2009-09-01 11:38:34 -0400920 device_initialize(&port->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 }
922
923 /* set up the endpoint information */
Johan Hovold1546e6a2014-08-21 19:33:25 +0200924 for (i = 0; i < epds->num_bulk_in; ++i) {
925 endpoint = epds->bulk_in[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 port = serial->port[i];
Alan Stern969e3032011-02-23 15:28:18 -0500927 buffer_size = max_t(int, serial->type->bulk_in_size,
Kuninori Morimoto29cc8892011-08-23 03:12:03 -0700928 usb_endpoint_maxp(endpoint));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 port->bulk_in_size = buffer_size;
930 port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
Johan Hovoldd83b4052011-11-06 19:06:37 +0100931
932 for (j = 0; j < ARRAY_SIZE(port->read_urbs); ++j) {
933 set_bit(j, &port->read_urbs_free);
934 port->read_urbs[j] = usb_alloc_urb(0, GFP_KERNEL);
Johan Hovold6b03f7f2013-03-21 12:36:26 +0100935 if (!port->read_urbs[j])
Johan Hovoldd83b4052011-11-06 19:06:37 +0100936 goto probe_error;
Johan Hovoldd83b4052011-11-06 19:06:37 +0100937 port->bulk_in_buffers[j] = kmalloc(buffer_size,
938 GFP_KERNEL);
Johan Hovold6b03f7f2013-03-21 12:36:26 +0100939 if (!port->bulk_in_buffers[j])
Johan Hovoldd83b4052011-11-06 19:06:37 +0100940 goto probe_error;
Johan Hovoldd83b4052011-11-06 19:06:37 +0100941 usb_fill_bulk_urb(port->read_urbs[j], dev,
942 usb_rcvbulkpipe(dev,
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100943 endpoint->bEndpointAddress),
Johan Hovoldd83b4052011-11-06 19:06:37 +0100944 port->bulk_in_buffers[j], buffer_size,
945 serial->type->read_bulk_callback,
946 port);
947 }
948
949 port->read_urb = port->read_urbs[0];
950 port->bulk_in_buffer = port->bulk_in_buffers[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951 }
952
Johan Hovold1546e6a2014-08-21 19:33:25 +0200953 for (i = 0; i < epds->num_bulk_out; ++i) {
954 endpoint = epds->bulk_out[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 port = serial->port[i];
Stefani Seibold119eecc2009-12-23 09:10:48 +0100956 if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL))
David VomLehn8e8dce02009-08-28 12:54:27 -0700957 goto probe_error;
Johan Hovoldbc4b1f42015-02-15 11:57:53 +0700958 buffer_size = serial->type->bulk_out_size;
959 if (!buffer_size)
960 buffer_size = usb_endpoint_maxp(endpoint);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961 port->bulk_out_size = buffer_size;
962 port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
Johan Hovold1ce7b932011-11-06 19:06:31 +0100963
Johan Hovold27c7acf2010-05-05 23:57:37 +0200964 for (j = 0; j < ARRAY_SIZE(port->write_urbs); ++j) {
965 set_bit(j, &port->write_urbs_free);
966 port->write_urbs[j] = usb_alloc_urb(0, GFP_KERNEL);
Johan Hovold6b03f7f2013-03-21 12:36:26 +0100967 if (!port->write_urbs[j])
Johan Hovold27c7acf2010-05-05 23:57:37 +0200968 goto probe_error;
Johan Hovold27c7acf2010-05-05 23:57:37 +0200969 port->bulk_out_buffers[j] = kmalloc(buffer_size,
970 GFP_KERNEL);
Johan Hovold6b03f7f2013-03-21 12:36:26 +0100971 if (!port->bulk_out_buffers[j])
Johan Hovold27c7acf2010-05-05 23:57:37 +0200972 goto probe_error;
Johan Hovold27c7acf2010-05-05 23:57:37 +0200973 usb_fill_bulk_urb(port->write_urbs[j], dev,
974 usb_sndbulkpipe(dev,
975 endpoint->bEndpointAddress),
976 port->bulk_out_buffers[j], buffer_size,
977 serial->type->write_bulk_callback,
978 port);
979 }
Johan Hovold1ce7b932011-11-06 19:06:31 +0100980
981 port->write_urb = port->write_urbs[0];
982 port->bulk_out_buffer = port->bulk_out_buffers[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983 }
984
985 if (serial->type->read_int_callback) {
Johan Hovold1546e6a2014-08-21 19:33:25 +0200986 for (i = 0; i < epds->num_interrupt_in; ++i) {
987 endpoint = epds->interrupt_in[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 port = serial->port[i];
989 port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
Johan Hovold6b03f7f2013-03-21 12:36:26 +0100990 if (!port->interrupt_in_urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991 goto probe_error;
Kuninori Morimoto29cc8892011-08-23 03:12:03 -0700992 buffer_size = usb_endpoint_maxp(endpoint);
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100993 port->interrupt_in_endpointAddress =
994 endpoint->bEndpointAddress;
995 port->interrupt_in_buffer = kmalloc(buffer_size,
996 GFP_KERNEL);
Johan Hovold6b03f7f2013-03-21 12:36:26 +0100997 if (!port->interrupt_in_buffer)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 goto probe_error;
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100999 usb_fill_int_urb(port->interrupt_in_urb, dev,
1000 usb_rcvintpipe(dev,
1001 endpoint->bEndpointAddress),
1002 port->interrupt_in_buffer, buffer_size,
1003 serial->type->read_int_callback, port,
1004 endpoint->bInterval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005 }
Johan Hovold1546e6a2014-08-21 19:33:25 +02001006 } else if (epds->num_interrupt_in) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001007 dev_dbg(ddev, "The device claims to support interrupt in transfers, but read_int_callback is not defined\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008 }
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001009
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010 if (serial->type->write_int_callback) {
Johan Hovold1546e6a2014-08-21 19:33:25 +02001011 for (i = 0; i < epds->num_interrupt_out; ++i) {
1012 endpoint = epds->interrupt_out[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 port = serial->port[i];
1014 port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
Johan Hovold6b03f7f2013-03-21 12:36:26 +01001015 if (!port->interrupt_out_urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 goto probe_error;
Kuninori Morimoto29cc8892011-08-23 03:12:03 -07001017 buffer_size = usb_endpoint_maxp(endpoint);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018 port->interrupt_out_size = buffer_size;
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001019 port->interrupt_out_endpointAddress =
1020 endpoint->bEndpointAddress;
1021 port->interrupt_out_buffer = kmalloc(buffer_size,
1022 GFP_KERNEL);
Johan Hovold6b03f7f2013-03-21 12:36:26 +01001023 if (!port->interrupt_out_buffer)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 goto probe_error;
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001025 usb_fill_int_urb(port->interrupt_out_urb, dev,
1026 usb_sndintpipe(dev,
1027 endpoint->bEndpointAddress),
1028 port->interrupt_out_buffer, buffer_size,
1029 serial->type->write_int_callback, port,
1030 endpoint->bInterval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 }
Johan Hovold1546e6a2014-08-21 19:33:25 +02001032 } else if (epds->num_interrupt_out) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001033 dev_dbg(ddev, "The device claims to support interrupt out transfers, but write_int_callback is not defined\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034 }
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001035
Johan Hovoldbdce6612012-04-25 15:56:32 +02001036 usb_set_intfdata(interface, serial);
1037
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 /* if this device type has an attach function, call it */
1039 if (type->attach) {
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001040 retval = type->attach(serial);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 if (retval < 0)
1042 goto probe_error;
Alan Sterna4720c62009-10-09 12:43:12 -04001043 serial->attached = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 if (retval > 0) {
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001045 /* quietly accept this device, but don't bind to a
1046 serial port as it's about to disappear */
Alan Stern0a3c8542009-05-27 11:25:52 -04001047 serial->num_ports = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 goto exit;
1049 }
Alan Sterna4720c62009-10-09 12:43:12 -04001050 } else {
1051 serial->attached = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 }
1053
Johan Hovolda65a6f12012-03-20 16:59:33 +01001054 /* Avoid race with tty_open and serial_install by setting the
1055 * disconnected flag and not clearing it until all ports have been
1056 * registered.
1057 */
1058 serial->disconnected = 1;
1059
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -07001060 if (allocate_minors(serial, num_ports)) {
1061 dev_err(ddev, "No more free serial minor numbers\n");
Oliver Neukum34ef50e2007-01-13 07:29:26 +01001062 goto probe_error;
1063 }
1064
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 /* register all of the individual ports with the driver core */
1066 for (i = 0; i < num_ports; ++i) {
1067 port = serial->port[i];
Greg Kroah-Hartman11438322013-06-06 10:32:00 -07001068 dev_set_name(&port->dev, "ttyUSB%d", port->minor);
Johan Hovoldd9a38a82014-03-12 19:09:42 +01001069 dev_dbg(ddev, "registering %s\n", dev_name(&port->dev));
Ming Leia7a6b792010-07-13 23:56:24 +08001070 device_enable_async_suspend(&port->dev);
1071
Alan Stern41bd34d2009-09-01 11:38:34 -04001072 retval = device_add(&port->dev);
Alan Stern891a3b12012-03-28 16:10:49 -04001073 if (retval)
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001074 dev_err(ddev, "Error registering port device, continuing\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 }
1076
Johan Hovolda65a6f12012-03-20 16:59:33 +01001077 serial->disconnected = 0;
1078
Johan Hovold126d26f2016-10-21 12:56:27 +02001079 if (num_ports > 0)
1080 usb_serial_console_init(serial->port[0]->minor);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081exit:
Johan Hovold1546e6a2014-08-21 19:33:25 +02001082 kfree(epds);
Ming Leid92a3ca2010-08-07 16:20:35 +08001083 module_put(type->driver.owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084 return 0;
1085
1086probe_error:
Johan Hovoldc2fef452017-03-02 12:51:14 +01001087 retval = -EIO;
1088err_put_serial:
Alan Stern41bd34d2009-09-01 11:38:34 -04001089 usb_serial_put(serial);
Johan Hovoldc2fef452017-03-02 12:51:14 +01001090err_put_module:
Ming Leid92a3ca2010-08-07 16:20:35 +08001091 module_put(type->driver.owner);
Johan Hovoldc2fef452017-03-02 12:51:14 +01001092
1093 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094}
1095
Greg Kroah-Hartman32078f92012-05-07 14:02:13 -07001096static void usb_serial_disconnect(struct usb_interface *interface)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097{
1098 int i;
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001099 struct usb_serial *serial = usb_get_intfdata(interface);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 struct device *dev = &interface->dev;
1101 struct usb_serial_port *port;
Johan Hovold3fff3b42014-05-26 19:23:34 +02001102 struct tty_struct *tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103
Guennadi Liakhovetski73e487f2006-04-25 07:46:17 +02001104 usb_serial_console_disconnect(serial);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
Oliver Neukuma1cd7e92008-01-16 17:18:52 +01001106 mutex_lock(&serial->disc_mutex);
Oliver Neukuma1cd7e92008-01-16 17:18:52 +01001107 /* must set a flag, to signal subdrivers */
1108 serial->disconnected = 1;
Alan Stern2d931482009-04-14 11:31:02 -04001109 mutex_unlock(&serial->disc_mutex);
1110
Oliver Neukuma1cd7e92008-01-16 17:18:52 +01001111 for (i = 0; i < serial->num_ports; ++i) {
1112 port = serial->port[i];
Johan Hovold3fff3b42014-05-26 19:23:34 +02001113 tty = tty_port_tty_get(&port->port);
1114 if (tty) {
1115 tty_vhangup(tty);
1116 tty_kref_put(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 }
Johan Hovold3fff3b42014-05-26 19:23:34 +02001118 usb_serial_port_poison_urbs(port);
1119 wake_up_interruptible(&port->port.delta_msr_wait);
1120 cancel_work_sync(&port->work);
1121 if (device_is_registered(&port->dev))
1122 device_del(&port->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 }
Johan Hovold0f16cfe2013-03-21 12:36:42 +01001124 if (serial->type->disconnect)
1125 serial->type->disconnect(serial);
Alan Stern2d931482009-04-14 11:31:02 -04001126
Alan Stern41bd34d2009-09-01 11:38:34 -04001127 /* let the last holder of this object cause it to be cleaned up */
Oliver Neukuma1cd7e92008-01-16 17:18:52 +01001128 usb_serial_put(serial);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 dev_info(dev, "device disconnected\n");
1130}
1131
Oliver Neukumec225592007-04-27 20:54:57 +02001132int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
1133{
1134 struct usb_serial *serial = usb_get_intfdata(intf);
Oliver Neukumec225592007-04-27 20:54:57 +02001135 int i, r = 0;
1136
Oliver Neukumf8bece82009-02-05 16:54:25 +01001137 serial->suspending = 1;
1138
Ming Lei93e4f472013-03-15 12:08:54 +08001139 /*
1140 * serial->type->suspend() MUST return 0 in system sleep context,
1141 * otherwise, the resume callback has to recover device from
1142 * previous suspend failure.
1143 */
Oliver Neukum81e5b232009-07-21 08:47:34 +02001144 if (serial->type->suspend) {
1145 r = serial->type->suspend(serial, message);
Oliver Neukuma5f60052009-10-01 15:01:17 +02001146 if (r < 0) {
1147 serial->suspending = 0;
Oliver Neukum81e5b232009-07-21 08:47:34 +02001148 goto err_out;
Oliver Neukuma5f60052009-10-01 15:01:17 +02001149 }
Oliver Neukum81e5b232009-07-21 08:47:34 +02001150 }
1151
Johan Hovold3fff3b42014-05-26 19:23:34 +02001152 for (i = 0; i < serial->num_ports; ++i)
1153 usb_serial_port_poison_urbs(serial->port[i]);
Oliver Neukum81e5b232009-07-21 08:47:34 +02001154err_out:
Oliver Neukumec225592007-04-27 20:54:57 +02001155 return r;
1156}
1157EXPORT_SYMBOL(usb_serial_suspend);
1158
Johan Hovold6a5c8212013-03-21 12:36:49 +01001159static void usb_serial_unpoison_port_urbs(struct usb_serial *serial)
1160{
Johan Hovold6a5c8212013-03-21 12:36:49 +01001161 int i;
1162
Johan Hovold3fff3b42014-05-26 19:23:34 +02001163 for (i = 0; i < serial->num_ports; ++i)
1164 usb_serial_port_unpoison_urbs(serial->port[i]);
Johan Hovold6a5c8212013-03-21 12:36:49 +01001165}
1166
Oliver Neukumec225592007-04-27 20:54:57 +02001167int usb_serial_resume(struct usb_interface *intf)
1168{
1169 struct usb_serial *serial = usb_get_intfdata(intf);
Oliver Neukumc49cfa912009-02-06 18:06:43 +01001170 int rv;
Oliver Neukumec225592007-04-27 20:54:57 +02001171
Johan Hovold6a5c8212013-03-21 12:36:49 +01001172 usb_serial_unpoison_port_urbs(serial);
1173
Oliver Neukumf8bece82009-02-05 16:54:25 +01001174 serial->suspending = 0;
Sarah Sharp8abaee22007-10-25 10:58:43 -07001175 if (serial->type->resume)
Oliver Neukumc49cfa912009-02-06 18:06:43 +01001176 rv = serial->type->resume(serial);
1177 else
1178 rv = usb_serial_generic_resume(serial);
Oliver Neukumf8bece82009-02-05 16:54:25 +01001179
Oliver Neukumc49cfa912009-02-06 18:06:43 +01001180 return rv;
Oliver Neukumec225592007-04-27 20:54:57 +02001181}
1182EXPORT_SYMBOL(usb_serial_resume);
1183
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07001184static int usb_serial_reset_resume(struct usb_interface *intf)
1185{
1186 struct usb_serial *serial = usb_get_intfdata(intf);
1187 int rv;
1188
Johan Hovold6a5c8212013-03-21 12:36:49 +01001189 usb_serial_unpoison_port_urbs(serial);
1190
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07001191 serial->suspending = 0;
Johan Hovoldca0400d2014-03-12 19:09:41 +01001192 if (serial->type->reset_resume) {
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07001193 rv = serial->type->reset_resume(serial);
Johan Hovoldca0400d2014-03-12 19:09:41 +01001194 } else {
Greg Kroah-Hartmandcd82cd2012-05-16 08:37:17 -07001195 rv = -EOPNOTSUPP;
1196 intf->needs_binding = 1;
1197 }
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07001198
1199 return rv;
1200}
1201
Jeff Dikeb68e31d2006-10-02 02:17:18 -07001202static const struct tty_operations serial_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 .open = serial_open,
1204 .close = serial_close,
1205 .write = serial_write,
Johan Hovold3e1f4902011-11-10 17:40:43 +01001206 .hangup = serial_hangup,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 .write_room = serial_write_room,
1208 .ioctl = serial_ioctl,
1209 .set_termios = serial_set_termios,
1210 .throttle = serial_throttle,
1211 .unthrottle = serial_unthrottle,
1212 .break_ctl = serial_break,
1213 .chars_in_buffer = serial_chars_in_buffer,
Johan Hovold06931962013-05-05 20:32:27 +02001214 .wait_until_sent = serial_wait_until_sent,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215 .tiocmget = serial_tiocmget,
1216 .tiocmset = serial_tiocmset,
Johan Hovold3e1f4902011-11-10 17:40:43 +01001217 .get_icount = serial_get_icount,
1218 .cleanup = serial_cleanup,
1219 .install = serial_install,
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -07001220 .proc_fops = &serial_proc_fops,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221};
1222
Alan Cox335f8512009-06-11 12:26:29 +01001223
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224struct tty_driver *usb_serial_tty_driver;
1225
Greg Kroah-Hartman32078f92012-05-07 14:02:13 -07001226/* Driver structure we register with the USB core */
1227static struct usb_driver usb_serial_driver = {
1228 .name = "usbserial",
1229 .probe = usb_serial_probe,
1230 .disconnect = usb_serial_disconnect,
1231 .suspend = usb_serial_suspend,
1232 .resume = usb_serial_resume,
1233 .no_dynamic_id = 1,
1234 .supports_autosuspend = 1,
1235};
1236
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237static int __init usb_serial_init(void)
1238{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239 int result;
1240
Greg Kroah-Hartman455b4f72013-06-06 10:31:35 -07001241 usb_serial_tty_driver = alloc_tty_driver(USB_SERIAL_TTY_MINORS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 if (!usb_serial_tty_driver)
1243 return -ENOMEM;
1244
1245 /* Initialize our global data */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246 result = bus_register(&usb_serial_bus_type);
1247 if (result) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001248 pr_err("%s - registering bus driver failed\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249 goto exit_bus;
1250 }
1251
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252 usb_serial_tty_driver->driver_name = "usbserial";
Johan Hovold3e1f4902011-11-10 17:40:43 +01001253 usb_serial_tty_driver->name = "ttyUSB";
Greg Kroah-Hartman455b4f72013-06-06 10:31:35 -07001254 usb_serial_tty_driver->major = USB_SERIAL_TTY_MAJOR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 usb_serial_tty_driver->minor_start = 0;
1256 usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
1257 usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL;
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001258 usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW |
1259 TTY_DRIVER_DYNAMIC_DEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260 usb_serial_tty_driver->init_termios = tty_std_termios;
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001261 usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD
1262 | HUPCL | CLOCAL;
Alan Coxa5b6f602008-04-08 17:16:06 +01001263 usb_serial_tty_driver->init_termios.c_ispeed = 9600;
1264 usb_serial_tty_driver->init_termios.c_ospeed = 9600;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001265 tty_set_operations(usb_serial_tty_driver, &serial_ops);
1266 result = tty_register_driver(usb_serial_tty_driver);
1267 if (result) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001268 pr_err("%s - tty_register_driver failed\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269 goto exit_reg_driver;
1270 }
1271
1272 /* register the USB driver */
1273 result = usb_register(&usb_serial_driver);
1274 if (result < 0) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001275 pr_err("%s - usb_register failed\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276 goto exit_tty;
1277 }
1278
Greg Kroah-Hartman06299db2005-05-26 05:55:55 -07001279 /* register the generic driver, if we should */
Greg Kroah-Hartman3033bc82012-09-18 16:05:17 +01001280 result = usb_serial_generic_register();
Greg Kroah-Hartman06299db2005-05-26 05:55:55 -07001281 if (result < 0) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001282 pr_err("%s - registering generic driver failed\n", __func__);
Greg Kroah-Hartman06299db2005-05-26 05:55:55 -07001283 goto exit_generic;
1284 }
1285
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286 return result;
1287
Greg Kroah-Hartman06299db2005-05-26 05:55:55 -07001288exit_generic:
1289 usb_deregister(&usb_serial_driver);
1290
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291exit_tty:
1292 tty_unregister_driver(usb_serial_tty_driver);
1293
1294exit_reg_driver:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295 bus_unregister(&usb_serial_bus_type);
1296
1297exit_bus:
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001298 pr_err("%s - returning with error %d\n", __func__, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299 put_tty_driver(usb_serial_tty_driver);
1300 return result;
1301}
1302
1303
1304static void __exit usb_serial_exit(void)
1305{
1306 usb_serial_console_exit();
1307
1308 usb_serial_generic_deregister();
1309
1310 usb_deregister(&usb_serial_driver);
1311 tty_unregister_driver(usb_serial_tty_driver);
1312 put_tty_driver(usb_serial_tty_driver);
1313 bus_unregister(&usb_serial_bus_type);
Johannes Thumshirnd23f47d2015-07-08 17:26:37 +02001314 idr_destroy(&serial_minors);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315}
1316
1317
1318module_init(usb_serial_init);
1319module_exit(usb_serial_exit);
1320
1321#define set_to_generic_if_null(type, function) \
1322 do { \
1323 if (!type->function) { \
1324 type->function = usb_serial_generic_##function; \
Johan Hovoldc3452f52013-03-21 12:36:44 +01001325 pr_debug("%s: using generic " #function "\n", \
1326 type->driver.name); \
1327 } \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 } while (0)
1329
Johan Hovoldc3452f52013-03-21 12:36:44 +01001330static void usb_serial_operations_init(struct usb_serial_driver *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331{
1332 set_to_generic_if_null(device, open);
1333 set_to_generic_if_null(device, write);
1334 set_to_generic_if_null(device, close);
1335 set_to_generic_if_null(device, write_room);
1336 set_to_generic_if_null(device, chars_in_buffer);
Johan Hovolddcf01052013-05-08 17:51:43 +02001337 if (device->tx_empty)
1338 set_to_generic_if_null(device, wait_until_sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 set_to_generic_if_null(device, read_bulk_callback);
1340 set_to_generic_if_null(device, write_bulk_callback);
Johan Hovold23154322010-03-17 23:05:57 +01001341 set_to_generic_if_null(device, process_read_urb);
Johan Hovoldeaa3bcb2010-03-17 23:06:08 +01001342 set_to_generic_if_null(device, prepare_write_buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343}
1344
Greg Kroah-Hartmanf799e762012-02-24 12:50:30 -08001345static int usb_serial_register(struct usb_serial_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346{
1347 int retval;
1348
Dave Younge4abe662009-02-14 21:21:13 +08001349 if (usb_disabled())
1350 return -ENODEV;
1351
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -07001352 if (!driver->description)
1353 driver->description = driver->driver.name;
Alan Stern5620b5f2011-01-11 14:16:50 -05001354 if (!driver->usb_driver) {
1355 WARN(1, "Serial driver %s has no usb_driver\n",
1356 driver->description);
1357 return -EINVAL;
1358 }
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -07001359
Johan Hovoldc3452f52013-03-21 12:36:44 +01001360 usb_serial_operations_init(driver);
1361
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362 /* Add this device to our list of devices */
Andi Kleen0daeed32010-06-01 23:04:42 +02001363 mutex_lock(&table_lock);
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -07001364 list_add(&driver->driver_list, &usb_serial_driver_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -07001366 retval = usb_serial_bus_register(driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367 if (retval) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001368 pr_err("problem %d when registering driver %s\n", retval, driver->description);
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -07001369 list_del(&driver->driver_list);
Johan Hovoldca0400d2014-03-12 19:09:41 +01001370 } else {
Greg Kroah-Hartmanee42f6c2012-09-18 17:10:29 +01001371 pr_info("USB Serial support registered for %s\n", driver->description);
Johan Hovoldca0400d2014-03-12 19:09:41 +01001372 }
Andi Kleen0daeed32010-06-01 23:04:42 +02001373 mutex_unlock(&table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374 return retval;
1375}
1376
Greg Kroah-Hartmanf799e762012-02-24 12:50:30 -08001377static void usb_serial_deregister(struct usb_serial_driver *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378{
Greg Kroah-Hartmanee42f6c2012-09-18 17:10:29 +01001379 pr_info("USB Serial deregistering driver %s\n", device->description);
Johan Hovold10164c22014-04-23 11:32:19 +02001380
Andi Kleen0daeed32010-06-01 23:04:42 +02001381 mutex_lock(&table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382 list_del(&device->driver_list);
Andi Kleen0daeed32010-06-01 23:04:42 +02001383 mutex_unlock(&table_lock);
Johan Hovold10164c22014-04-23 11:32:19 +02001384
1385 usb_serial_bus_deregister(device);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387
Alan Stern765e0ba2012-02-23 14:55:59 -05001388/**
1389 * usb_serial_register_drivers - register drivers for a usb-serial module
Alan Stern765e0ba2012-02-23 14:55:59 -05001390 * @serial_drivers: NULL-terminated array of pointers to drivers to be registered
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001391 * @name: name of the usb_driver for this set of @serial_drivers
1392 * @id_table: list of all devices this @serial_drivers set binds to
Alan Stern765e0ba2012-02-23 14:55:59 -05001393 *
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001394 * Registers all the drivers in the @serial_drivers array, and dynamically
1395 * creates a struct usb_driver with the name @name and id_table of @id_table.
Alan Stern765e0ba2012-02-23 14:55:59 -05001396 */
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001397int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[],
1398 const char *name,
1399 const struct usb_device_id *id_table)
Alan Stern765e0ba2012-02-23 14:55:59 -05001400{
1401 int rc;
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001402 struct usb_driver *udriver;
Alan Stern765e0ba2012-02-23 14:55:59 -05001403 struct usb_serial_driver * const *sd;
1404
1405 /*
1406 * udriver must be registered before any of the serial drivers,
1407 * because the store_new_id() routine for the serial drivers (in
1408 * bus.c) probes udriver.
1409 *
1410 * Performance hack: We don't want udriver to be probed until
1411 * the serial drivers are registered, because the probe would
1412 * simply fail for lack of a matching serial driver.
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001413 * So we leave udriver's id_table set to NULL until we are all set.
Alan Stern5cbe61c2012-05-07 11:20:06 -04001414 *
1415 * Suspend/resume support is implemented in the usb-serial core,
1416 * so fill in the PM-related fields in udriver.
Alan Stern765e0ba2012-02-23 14:55:59 -05001417 */
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001418 udriver = kzalloc(sizeof(*udriver), GFP_KERNEL);
1419 if (!udriver)
1420 return -ENOMEM;
Alan Stern765e0ba2012-02-23 14:55:59 -05001421
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001422 udriver->name = name;
Alan Stern765e0ba2012-02-23 14:55:59 -05001423 udriver->no_dynamic_id = 1;
Alan Stern5cbe61c2012-05-07 11:20:06 -04001424 udriver->supports_autosuspend = 1;
1425 udriver->suspend = usb_serial_suspend;
1426 udriver->resume = usb_serial_resume;
Greg Kroah-Hartman5026bb02012-05-07 13:48:33 -07001427 udriver->probe = usb_serial_probe;
Greg Kroah-Hartman32078f92012-05-07 14:02:13 -07001428 udriver->disconnect = usb_serial_disconnect;
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07001429
1430 /* we only set the reset_resume field if the serial_driver has one */
1431 for (sd = serial_drivers; *sd; ++sd) {
Greg Kroah-Hartman44b0f082012-09-19 08:15:21 +01001432 if ((*sd)->reset_resume) {
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07001433 udriver->reset_resume = usb_serial_reset_resume;
1434 break;
Greg Kroah-Hartman44b0f082012-09-19 08:15:21 +01001435 }
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07001436 }
1437
Alan Stern765e0ba2012-02-23 14:55:59 -05001438 rc = usb_register(udriver);
1439 if (rc)
Alexey Klimov647024a2016-08-08 02:34:46 +01001440 goto failed_usb_register;
Alan Stern765e0ba2012-02-23 14:55:59 -05001441
1442 for (sd = serial_drivers; *sd; ++sd) {
1443 (*sd)->usb_driver = udriver;
1444 rc = usb_serial_register(*sd);
1445 if (rc)
1446 goto failed;
1447 }
1448
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001449 /* Now set udriver's id_table and look for matches */
1450 udriver->id_table = id_table;
Alan Stern765e0ba2012-02-23 14:55:59 -05001451 rc = driver_attach(&udriver->drvwrap.driver);
1452 return 0;
1453
1454 failed:
1455 while (sd-- > serial_drivers)
1456 usb_serial_deregister(*sd);
1457 usb_deregister(udriver);
Alexey Klimov647024a2016-08-08 02:34:46 +01001458failed_usb_register:
1459 kfree(udriver);
Alan Stern765e0ba2012-02-23 14:55:59 -05001460 return rc;
1461}
1462EXPORT_SYMBOL_GPL(usb_serial_register_drivers);
1463
1464/**
1465 * usb_serial_deregister_drivers - deregister drivers for a usb-serial module
Alan Stern765e0ba2012-02-23 14:55:59 -05001466 * @serial_drivers: NULL-terminated array of pointers to drivers to be deregistered
1467 *
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001468 * Deregisters all the drivers in the @serial_drivers array and deregisters and
1469 * frees the struct usb_driver that was created by the call to
1470 * usb_serial_register_drivers().
Alan Stern765e0ba2012-02-23 14:55:59 -05001471 */
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001472void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[])
Alan Stern765e0ba2012-02-23 14:55:59 -05001473{
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001474 struct usb_driver *udriver = (*serial_drivers)->usb_driver;
1475
Alan Stern765e0ba2012-02-23 14:55:59 -05001476 for (; *serial_drivers; ++serial_drivers)
1477 usb_serial_deregister(*serial_drivers);
1478 usb_deregister(udriver);
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001479 kfree(udriver);
Alan Stern765e0ba2012-02-23 14:55:59 -05001480}
1481EXPORT_SYMBOL_GPL(usb_serial_deregister_drivers);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001483MODULE_AUTHOR(DRIVER_AUTHOR);
1484MODULE_DESCRIPTION(DRIVER_DESC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485MODULE_LICENSE("GPL");