blob: dc7a65b9ec982113f5b40dc1fb23c0179b655dac [file] [log] [blame]
Greg Kroah-Hartman5fd54ac2017-11-03 11:28:30 +01001// SPDX-License-Identifier: GPL-2.0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * USB Serial Converter driver
4 *
Johan Hovold659597b72013-03-21 12:37:51 +01005 * Copyright (C) 2009 - 2013 Johan Hovold (jhovold@gmail.com)
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07006 * Copyright (C) 1999 - 2012 Greg Kroah-Hartman (greg@kroah.com)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 * Copyright (C) 2000 Peter Berger (pberger@brimson.com)
8 * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com)
9 *
Greg Kroah-Hartman502b95c2005-06-20 21:15:16 -070010 * This driver was originally based on the ACM driver by Armin Fuerst (which was
Linus Torvalds1da177e2005-04-16 15:20:36 -070011 * based on a driver by Brad Keryan)
12 *
Mauro Carvalho Chehabecefae62019-06-18 18:05:38 -030013 * See Documentation/usb/usb-serial.rst for more information on using this
Alan Coxa8d6f0a2008-07-22 11:12:24 +010014 * driver
Linus Torvalds1da177e2005-04-16 15:20:36 -070015 */
16
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -070017#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
Linus Torvalds1da177e2005-04-16 15:20:36 -070019#include <linux/kernel.h>
20#include <linux/errno.h>
21#include <linux/init.h>
22#include <linux/slab.h>
23#include <linux/tty.h>
24#include <linux/tty_driver.h>
25#include <linux/tty_flip.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -070028#include <linux/seq_file.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <linux/spinlock.h>
Luiz Fernando Capitulino1ce7dd22006-03-24 17:12:31 -030030#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/list.h>
Alan Coxa8d6f0a2008-07-22 11:12:24 +010032#include <linux/uaccess.h>
Alan Coxc56d3002009-07-28 00:34:58 +010033#include <linux/serial.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034#include <linux/usb.h>
Greg Kroah-Hartmana9698882006-07-11 21:22:58 -070035#include <linux/usb/serial.h>
David VomLehn8e8dce02009-08-28 12:54:27 -070036#include <linux/kfifo.h>
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070037#include <linux/idr.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
Greg Kroah-Hartmanee42f6c2012-09-18 17:10:29 +010039#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#define DRIVER_DESC "USB Serial Driver core"
41
Greg Kroah-Hartman455b4f72013-06-06 10:31:35 -070042#define USB_SERIAL_TTY_MAJOR 188
43#define USB_SERIAL_TTY_MINORS 512 /* should be enough for a while */
44
Linus Torvalds1da177e2005-04-16 15:20:36 -070045/* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead
46 the MODULE_DEVICE_TABLE declarations in each serial driver
47 cause the "hotplug" program to pull in whatever module is necessary
48 via modprobe, and modprobe will load usbserial because the serial
49 drivers depend on it.
50*/
51
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070052static DEFINE_IDR(serial_minors);
Oliver Neukum3ddad822007-07-24 15:13:42 +020053static DEFINE_MUTEX(table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070054static LIST_HEAD(usb_serial_driver_list);
55
Alan Stern8bc2c1b2009-09-01 11:38:59 -040056/*
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070057 * Look up the serial port structure. If it is found and it hasn't been
58 * disconnected, return with the parent usb_serial structure's disc_mutex held
59 * and its refcount incremented. Otherwise return NULL.
Alan Stern8bc2c1b2009-09-01 11:38:59 -040060 */
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070061struct usb_serial_port *usb_serial_port_get_by_minor(unsigned minor)
Linus Torvalds1da177e2005-04-16 15:20:36 -070062{
Oliver Neukum34ef50e2007-01-13 07:29:26 +010063 struct usb_serial *serial;
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070064 struct usb_serial_port *port;
Oliver Neukum34ef50e2007-01-13 07:29:26 +010065
Oliver Neukum3ddad822007-07-24 15:13:42 +020066 mutex_lock(&table_lock);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070067 port = idr_find(&serial_minors, minor);
68 if (!port)
69 goto exit;
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070071 serial = port->serial;
72 mutex_lock(&serial->disc_mutex);
73 if (serial->disconnected) {
74 mutex_unlock(&serial->disc_mutex);
75 port = NULL;
76 } else {
77 kref_get(&serial->kref);
Alan Stern8bc2c1b2009-09-01 11:38:59 -040078 }
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070079exit:
Oliver Neukum3ddad822007-07-24 15:13:42 +020080 mutex_unlock(&table_lock);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070081 return port;
Linus Torvalds1da177e2005-04-16 15:20:36 -070082}
83
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070084static int allocate_minors(struct usb_serial *serial, int num_ports)
Linus Torvalds1da177e2005-04-16 15:20:36 -070085{
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070086 struct usb_serial_port *port;
Linus Torvalds1da177e2005-04-16 15:20:36 -070087 unsigned int i, j;
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070088 int minor;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -070090 dev_dbg(&serial->interface->dev, "%s %d\n", __func__, num_ports);
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
Oliver Neukum3ddad822007-07-24 15:13:42 +020092 mutex_lock(&table_lock);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070093 for (i = 0; i < num_ports; ++i) {
94 port = serial->port[i];
Johan Hovold194e9582016-05-08 20:08:03 +020095 minor = idr_alloc(&serial_minors, port, 0,
96 USB_SERIAL_TTY_MINORS, GFP_KERNEL);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -070097 if (minor < 0)
98 goto error;
99 port->minor = minor;
100 port->port_number = i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 }
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700102 serial->minors_reserved = 1;
Oliver Neukum3ddad822007-07-24 15:13:42 +0200103 mutex_unlock(&table_lock);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700104 return 0;
105error:
106 /* unwind the already allocated minors */
107 for (j = 0; j < i; ++j)
108 idr_remove(&serial_minors, serial->port[j]->minor);
109 mutex_unlock(&table_lock);
110 return minor;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111}
112
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700113static void release_minors(struct usb_serial *serial)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114{
115 int i;
116
Alan Stern8bc2c1b2009-09-01 11:38:59 -0400117 mutex_lock(&table_lock);
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100118 for (i = 0; i < serial->num_ports; ++i)
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700119 idr_remove(&serial_minors, serial->port[i]->minor);
Alan Stern8bc2c1b2009-09-01 11:38:59 -0400120 mutex_unlock(&table_lock);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700121 serial->minors_reserved = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122}
123
124static void destroy_serial(struct kref *kref)
125{
126 struct usb_serial *serial;
127 struct usb_serial_port *port;
128 int i;
129
130 serial = to_usb_serial(kref);
131
Jim Radford521b85a2007-03-13 08:30:50 -0700132 /* return the minor range that this device had */
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700133 if (serial->minors_reserved)
134 release_minors(serial);
Jim Radford521b85a2007-03-13 08:30:50 -0700135
Johan Hovold79b80b82013-03-21 12:36:43 +0100136 if (serial->attached && serial->type->release)
Alan Sterna4720c62009-10-09 12:43:12 -0400137 serial->type->release(serial);
Alan Sternf9c99bb2009-06-02 11:53:55 -0400138
Alan Stern41bd34d2009-09-01 11:38:34 -0400139 /* Now that nothing is using the ports, they can be freed */
140 for (i = 0; i < serial->num_port_pointers; ++i) {
Alan Sternf9c99bb2009-06-02 11:53:55 -0400141 port = serial->port[i];
Alan Stern41bd34d2009-09-01 11:38:34 -0400142 if (port) {
143 port->serial = NULL;
Alan Sternf9c99bb2009-06-02 11:53:55 -0400144 put_device(&port->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145 }
146 }
147
Johan Hovoldd7971052013-03-19 09:21:09 +0100148 usb_put_intf(serial->interface);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 usb_put_dev(serial->dev);
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100150 kfree(serial);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151}
152
Guennadi Liakhovetski73e487f2006-04-25 07:46:17 +0200153void usb_serial_put(struct usb_serial *serial)
154{
155 kref_put(&serial->kref, destroy_serial);
156}
157
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158/*****************************************************************************
159 * Driver tty interface functions
160 *****************************************************************************/
Alan Sternf5b09532009-09-01 11:38:44 -0400161
162/**
163 * serial_install - install tty
164 * @driver: the driver (USB in our case)
165 * @tty: the tty being created
166 *
Johan Hovold579bebe2019-04-21 14:21:46 +0200167 * Initialise the termios structure for this tty. We use the default
Alan Sternf5b09532009-09-01 11:38:44 -0400168 * USB serial settings but permit them to be overridden by
Johan Hovold579bebe2019-04-21 14:21:46 +0200169 * serial->type->init_termios on first open.
Alan Sterncc56cd02009-09-01 11:39:13 -0400170 *
171 * This is the first place a new tty gets used. Hence this is where we
172 * acquire references to the usb_serial structure and the driver module,
173 * where we store a pointer to the port, and where we do an autoresume.
Dave Youngf278a2f2009-09-27 16:00:42 +0000174 * All these actions are reversed in serial_cleanup().
Alan Sternf5b09532009-09-01 11:38:44 -0400175 */
176static int serial_install(struct tty_driver *driver, struct tty_struct *tty)
177{
178 int idx = tty->index;
179 struct usb_serial *serial;
Alan Sterncc56cd02009-09-01 11:39:13 -0400180 struct usb_serial_port *port;
Johan Hovold579bebe2019-04-21 14:21:46 +0200181 bool init_termios;
Alan Sterncc56cd02009-09-01 11:39:13 -0400182 int retval = -ENODEV;
183
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700184 port = usb_serial_port_get_by_minor(idx);
185 if (!port)
Alan Sterncc56cd02009-09-01 11:39:13 -0400186 return retval;
187
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700188 serial = port->serial;
Alan Sterncc56cd02009-09-01 11:39:13 -0400189 if (!try_module_get(serial->type->driver.owner))
190 goto error_module_get;
191
192 retval = usb_autopm_get_interface(serial->interface);
193 if (retval)
194 goto error_get_interface;
Alan Sternf5b09532009-09-01 11:38:44 -0400195
Johan Hovold579bebe2019-04-21 14:21:46 +0200196 init_termios = (driver->termios[idx] == NULL);
197
Johan Hovold79ef5182018-05-16 11:42:07 +0200198 retval = tty_standard_install(driver, tty);
Jiri Slaby76f82a72012-01-30 21:14:29 +0100199 if (retval)
200 goto error_init_termios;
201
Alan Sterncc56cd02009-09-01 11:39:13 -0400202 mutex_unlock(&serial->disc_mutex);
203
Johan Hovold579bebe2019-04-21 14:21:46 +0200204 /* allow the driver to update the initial settings */
205 if (init_termios && serial->type->init_termios)
Alan Stern7e29bb42009-09-01 11:39:22 -0400206 serial->type->init_termios(tty);
207
Alan Sterncc56cd02009-09-01 11:39:13 -0400208 tty->driver_data = port;
209
Alan Sterncc56cd02009-09-01 11:39:13 -0400210 return retval;
211
Alan Stern7e29bb42009-09-01 11:39:22 -0400212 error_init_termios:
Jiri Slaby76f82a72012-01-30 21:14:29 +0100213 usb_autopm_put_interface(serial->interface);
214 error_get_interface:
Alan Sterncc56cd02009-09-01 11:39:13 -0400215 module_put(serial->type->driver.owner);
216 error_module_get:
Alan Sterncc56cd02009-09-01 11:39:13 -0400217 usb_serial_put(serial);
218 mutex_unlock(&serial->disc_mutex);
219 return retval;
Alan Sternf5b09532009-09-01 11:38:44 -0400220}
221
Johan Hovold395e08d2013-03-21 12:36:23 +0100222static int serial_port_activate(struct tty_port *tport, struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223{
Alan Cox64bc3972009-10-06 16:06:11 +0100224 struct usb_serial_port *port =
225 container_of(tport, struct usb_serial_port, port);
Alan Stern320348c2009-09-01 11:39:59 -0400226 struct usb_serial *serial = port->serial;
227 int retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
Alan Cox64bc3972009-10-06 16:06:11 +0100229 mutex_lock(&serial->disc_mutex);
230 if (serial->disconnected)
231 retval = -ENODEV;
232 else
233 retval = port->serial->type->open(tty, port);
234 mutex_unlock(&serial->disc_mutex);
Johan Hovold3827d872011-11-10 17:38:13 +0100235
236 if (retval < 0)
237 retval = usb_translate_errors(retval);
238
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239 return retval;
240}
241
Alan Cox64bc3972009-10-06 16:06:11 +0100242static int serial_open(struct tty_struct *tty, struct file *filp)
243{
244 struct usb_serial_port *port = tty->driver_data;
245
Johan Hovoldd12e2112013-03-21 12:36:25 +0100246 dev_dbg(tty->dev, "%s\n", __func__);
247
Alan Cox64bc3972009-10-06 16:06:11 +0100248 return tty_port_open(&port->port, tty, filp);
249}
250
Alan Cox335f8512009-06-11 12:26:29 +0100251/**
Johan Hovold395e08d2013-03-21 12:36:23 +0100252 * serial_port_shutdown - shut down hardware
Alan Coxe1108a62009-10-06 16:06:36 +0100253 * @tport: tty port to shut down
Alan Cox335f8512009-06-11 12:26:29 +0100254 *
Peter Hurley8a7298d2013-02-23 10:11:35 -0500255 * Shut down a USB serial port. Serialized against activate by the
256 * tport mutex and kept to matching open/close pairs
Peter Hurleyd41861c2016-04-09 17:53:25 -0700257 * of calls by the initialized flag.
Peter Hurley8a7298d2013-02-23 10:11:35 -0500258 *
259 * Not called if tty is console.
Alan Cox335f8512009-06-11 12:26:29 +0100260 */
Johan Hovold395e08d2013-03-21 12:36:23 +0100261static void serial_port_shutdown(struct tty_port *tport)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262{
Alan Coxe1108a62009-10-06 16:06:36 +0100263 struct usb_serial_port *port =
264 container_of(tport, struct usb_serial_port, port);
Alan Cox335f8512009-06-11 12:26:29 +0100265 struct usb_serial_driver *drv = port->serial->type;
Peter Hurley8a7298d2013-02-23 10:11:35 -0500266
Alan Cox335f8512009-06-11 12:26:29 +0100267 if (drv->close)
268 drv->close(port);
Alan Cox335f8512009-06-11 12:26:29 +0100269}
270
Alan Sternf5b09532009-09-01 11:38:44 -0400271static void serial_hangup(struct tty_struct *tty)
Alan Cox335f8512009-06-11 12:26:29 +0100272{
Alan Cox4455e342009-09-19 13:13:24 -0700273 struct usb_serial_port *port = tty->driver_data;
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700274
Johan Hovoldd12e2112013-03-21 12:36:25 +0100275 dev_dbg(tty->dev, "%s\n", __func__);
276
Alan Sternf5b09532009-09-01 11:38:44 -0400277 tty_port_hangup(&port->port);
Alan Cox335f8512009-06-11 12:26:29 +0100278}
279
280static void serial_close(struct tty_struct *tty, struct file *filp)
281{
282 struct usb_serial_port *port = tty->driver_data;
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700283
Johan Hovoldd12e2112013-03-21 12:36:25 +0100284 dev_dbg(tty->dev, "%s\n", __func__);
285
Alan Coxe1108a62009-10-06 16:06:36 +0100286 tty_port_close(&port->port, tty, filp);
Alan Cox335f8512009-06-11 12:26:29 +0100287}
288
Alan Sternf5b09532009-09-01 11:38:44 -0400289/**
Dave Youngf278a2f2009-09-27 16:00:42 +0000290 * serial_cleanup - free resources post close/hangup
Alan Sternf5b09532009-09-01 11:38:44 -0400291 * @port: port to free up
292 *
293 * Do the resource freeing and refcount dropping for the port.
294 * Avoid freeing the console.
295 *
Alan Cox36b3c072012-07-17 17:06:57 +0100296 * Called asynchronously after the last tty kref is dropped.
Alan Sternf5b09532009-09-01 11:38:44 -0400297 */
Dave Youngf278a2f2009-09-27 16:00:42 +0000298static void serial_cleanup(struct tty_struct *tty)
Alan Cox335f8512009-06-11 12:26:29 +0100299{
300 struct usb_serial_port *port = tty->driver_data;
Alan Sternf5b09532009-09-01 11:38:44 -0400301 struct usb_serial *serial;
302 struct module *owner;
303
Johan Hovoldd12e2112013-03-21 12:36:25 +0100304 dev_dbg(tty->dev, "%s\n", __func__);
305
Alan Sternf5b09532009-09-01 11:38:44 -0400306 /* The console is magical. Do not hang up the console hardware
307 * or there will be tears.
308 */
Jason Wesselbd5afa92010-03-08 21:50:12 -0600309 if (port->port.console)
Alan Sternf5b09532009-09-01 11:38:44 -0400310 return;
311
Alan Sterncc56cd02009-09-01 11:39:13 -0400312 tty->driver_data = NULL;
313
Alan Sternf5b09532009-09-01 11:38:44 -0400314 serial = port->serial;
315 owner = serial->type->driver.owner;
316
Johan Hovoldd51bdb92019-10-01 10:49:07 +0200317 usb_autopm_put_interface(serial->interface);
Alan Sternf5b09532009-09-01 11:38:44 -0400318
319 usb_serial_put(serial);
320 module_put(owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321}
322
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100323static int serial_write(struct tty_struct *tty, const unsigned char *buf,
324 int count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200326 struct usb_serial_port *port = tty->driver_data;
Oliver Neukum3ff4fd92007-01-13 07:32:27 +0100327 int retval = -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328
Alan Coxf34d7a52008-04-30 00:54:13 -0700329 if (port->serial->dev->state == USB_STATE_NOTATTACHED)
Luiz Fernando Capitulino487f9c62005-11-28 19:16:05 -0200330 goto exit;
331
Johan Hovoldd12e2112013-03-21 12:36:25 +0100332 dev_dbg(tty->dev, "%s - %d byte(s)\n", __func__, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333
Alan Cox95da3102008-07-22 11:09:07 +0100334 retval = port->serial->type->write(tty, port, buf, count);
Johan Hovoldc6249ff2011-11-10 17:40:44 +0100335 if (retval < 0)
336 retval = usb_translate_errors(retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337exit:
338 return retval;
339}
340
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100341static int serial_write_room(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200343 struct usb_serial_port *port = tty->driver_data;
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700344
Johan Hovoldd12e2112013-03-21 12:36:25 +0100345 dev_dbg(tty->dev, "%s\n", __func__);
Johan Hovold9993b422013-03-21 12:36:24 +0100346
Alan Cox95da3102008-07-22 11:09:07 +0100347 return port->serial->type->write_room(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348}
349
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100350static int serial_chars_in_buffer(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200352 struct usb_serial_port *port = tty->driver_data;
Johan Hovold810360a2013-01-14 16:52:56 +0100353 struct usb_serial *serial = port->serial;
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700354
Johan Hovoldd12e2112013-03-21 12:36:25 +0100355 dev_dbg(tty->dev, "%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356
Johan Hovold810360a2013-01-14 16:52:56 +0100357 if (serial->disconnected)
Johan Hovold4746b6c2013-05-05 20:32:33 +0200358 return 0;
Johan Hovold810360a2013-01-14 16:52:56 +0100359
Johan Hovold4746b6c2013-05-05 20:32:33 +0200360 return serial->type->chars_in_buffer(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361}
362
Johan Hovold06931962013-05-05 20:32:27 +0200363static void serial_wait_until_sent(struct tty_struct *tty, int timeout)
364{
365 struct usb_serial_port *port = tty->driver_data;
366 struct usb_serial *serial = port->serial;
367
368 dev_dbg(tty->dev, "%s\n", __func__);
369
370 if (!port->serial->type->wait_until_sent)
371 return;
372
373 mutex_lock(&serial->disc_mutex);
374 if (!serial->disconnected)
375 port->serial->type->wait_until_sent(tty, timeout);
376 mutex_unlock(&serial->disc_mutex);
377}
378
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100379static void serial_throttle(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200381 struct usb_serial_port *port = tty->driver_data;
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700382
Johan Hovoldd12e2112013-03-21 12:36:25 +0100383 dev_dbg(tty->dev, "%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 if (port->serial->type->throttle)
Alan Cox95da3102008-07-22 11:09:07 +0100386 port->serial->type->throttle(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387}
388
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100389static void serial_unthrottle(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200391 struct usb_serial_port *port = tty->driver_data;
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700392
Johan Hovoldd12e2112013-03-21 12:36:25 +0100393 dev_dbg(tty->dev, "%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 if (port->serial->type->unthrottle)
Alan Cox95da3102008-07-22 11:09:07 +0100396 port->serial->type->unthrottle(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397}
398
Al Viro81732b22018-09-11 23:28:07 -0400399static int serial_get_serial(struct tty_struct *tty, struct serial_struct *ss)
400{
401 struct usb_serial_port *port = tty->driver_data;
402
403 if (port->serial->type->get_serial)
404 return port->serial->type->get_serial(tty, ss);
Al Viro930236a2018-09-12 07:46:51 -0400405 return -ENOTTY;
Al Viro81732b22018-09-11 23:28:07 -0400406}
407
408static int serial_set_serial(struct tty_struct *tty, struct serial_struct *ss)
409{
410 struct usb_serial_port *port = tty->driver_data;
411
412 if (port->serial->type->set_serial)
413 return port->serial->type->set_serial(tty, ss);
Al Viro930236a2018-09-12 07:46:51 -0400414 return -ENOTTY;
Al Viro81732b22018-09-11 23:28:07 -0400415}
416
Alan Cox6caa76b2011-02-14 16:27:22 +0000417static int serial_ioctl(struct tty_struct *tty,
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100418 unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200420 struct usb_serial_port *port = tty->driver_data;
Johan Hovoldf4488032013-06-05 12:21:11 +0200421 int retval = -ENOIOCTLCMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422
Johan Hovold4d5147e2013-12-29 19:22:55 +0100423 dev_dbg(tty->dev, "%s - cmd 0x%04x\n", __func__, cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
Johan Hovold143d9d92013-03-21 12:36:51 +0100425 switch (cmd) {
426 case TIOCMIWAIT:
427 if (port->serial->type->tiocmiwait)
428 retval = port->serial->type->tiocmiwait(tty, arg);
429 break;
430 default:
431 if (port->serial->type->ioctl)
432 retval = port->serial->type->ioctl(tty, cmd, arg);
Johan Hovold143d9d92013-03-21 12:36:51 +0100433 }
Johan Hovold9993b422013-03-21 12:36:24 +0100434
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 return retval;
436}
437
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100438static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200440 struct usb_serial_port *port = tty->driver_data;
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700441
Johan Hovoldd12e2112013-03-21 12:36:25 +0100442 dev_dbg(tty->dev, "%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 if (port->serial->type->set_termios)
Alan Cox95da3102008-07-22 11:09:07 +0100445 port->serial->type->set_termios(tty, port, old);
Alan Cox33785092007-10-18 01:24:22 -0700446 else
Alan Coxadc8d742012-07-14 15:31:47 +0100447 tty_termios_copy_hw(&tty->termios, old);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448}
449
Alan Cox9e98966c2008-07-22 11:18:03 +0100450static int serial_break(struct tty_struct *tty, int break_state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200452 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453
Johan Hovoldd12e2112013-03-21 12:36:25 +0100454 dev_dbg(tty->dev, "%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455
Alan Cox6b447f042009-01-02 13:48:56 +0000456 if (port->serial->type->break_ctl)
Alan Cox95da3102008-07-22 11:09:07 +0100457 port->serial->type->break_ctl(tty, break_state);
Johan Hovold9993b422013-03-21 12:36:24 +0100458
Alan Cox9e98966c2008-07-22 11:18:03 +0100459 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460}
461
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700462static int serial_proc_show(struct seq_file *m, void *v)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463{
464 struct usb_serial *serial;
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700465 struct usb_serial_port *port;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 char tmp[40];
468
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700469 seq_puts(m, "usbserinfo:1.0 driver:2.0\n");
Greg Kroah-Hartman455b4f72013-06-06 10:31:35 -0700470 for (i = 0; i < USB_SERIAL_TTY_MINORS; ++i) {
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700471 port = usb_serial_port_get_by_minor(i);
472 if (port == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 continue;
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700474 serial = port->serial;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700476 seq_printf(m, "%d:", i);
Greg Kroah-Hartman18fcac32005-06-20 21:15:16 -0700477 if (serial->type->driver.owner)
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700478 seq_printf(m, " module:%s",
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100479 module_name(serial->type->driver.owner));
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700480 seq_printf(m, " name:\"%s\"",
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100481 serial->type->description);
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700482 seq_printf(m, " vendor:%04x product:%04x",
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100483 le16_to_cpu(serial->dev->descriptor.idVendor),
484 le16_to_cpu(serial->dev->descriptor.idProduct));
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700485 seq_printf(m, " num_ports:%d", serial->num_ports);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700486 seq_printf(m, " port:%d", port->port_number);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 usb_make_path(serial->dev, tmp, sizeof(tmp));
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700488 seq_printf(m, " path:%s", tmp);
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100489
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700490 seq_putc(m, '\n');
Guennadi Liakhovetski73e487f2006-04-25 07:46:17 +0200491 usb_serial_put(serial);
Alan Stern8bc2c1b2009-09-01 11:38:59 -0400492 mutex_unlock(&serial->disc_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 }
Alexey Dobriyan6fd69d32009-03-31 15:19:21 -0700494 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495}
496
Alan Cox60b33c12011-02-14 16:26:14 +0000497static int serial_tiocmget(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200499 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500
Johan Hovoldd12e2112013-03-21 12:36:25 +0100501 dev_dbg(tty->dev, "%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 if (port->serial->type->tiocmget)
Alan Cox60b33c12011-02-14 16:26:14 +0000504 return port->serial->type->tiocmget(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 return -EINVAL;
506}
507
Alan Cox20b9d172011-02-14 16:26:50 +0000508static int serial_tiocmset(struct tty_struct *tty,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 unsigned int set, unsigned int clear)
510{
Tobias Klauser81671dd2005-07-04 19:32:51 +0200511 struct usb_serial_port *port = tty->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512
Johan Hovoldd12e2112013-03-21 12:36:25 +0100513 dev_dbg(tty->dev, "%s\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 if (port->serial->type->tiocmset)
Alan Cox20b9d172011-02-14 16:26:50 +0000516 return port->serial->type->tiocmset(tty, set, clear);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 return -EINVAL;
518}
519
Alan Coxd281da72010-09-16 18:21:24 +0100520static int serial_get_icount(struct tty_struct *tty,
521 struct serial_icounter_struct *icount)
522{
523 struct usb_serial_port *port = tty->driver_data;
524
Johan Hovoldd12e2112013-03-21 12:36:25 +0100525 dev_dbg(tty->dev, "%s\n", __func__);
Alan Coxd281da72010-09-16 18:21:24 +0100526
527 if (port->serial->type->get_icount)
528 return port->serial->type->get_icount(tty, icount);
529 return -EINVAL;
530}
531
Pete Zaitcevcf2c7482006-05-22 21:58:49 -0700532/*
533 * We would be calling tty_wakeup here, but unfortunately some line
534 * disciplines have an annoying habit of calling tty->write from
535 * the write wakeup callback (e.g. n_hdlc.c).
536 */
537void usb_serial_port_softint(struct usb_serial_port *port)
538{
539 schedule_work(&port->work);
540}
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100541EXPORT_SYMBOL_GPL(usb_serial_port_softint);
Pete Zaitcevcf2c7482006-05-22 21:58:49 -0700542
David Howellsc4028952006-11-22 14:57:56 +0000543static void usb_serial_port_work(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544{
David Howellsc4028952006-11-22 14:57:56 +0000545 struct usb_serial_port *port =
546 container_of(work, struct usb_serial_port, work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547
Jiri Slaby6aad04f2013-03-07 13:12:29 +0100548 tty_port_tty_wakeup(&port->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549}
550
Johan Hovold6a5c8212013-03-21 12:36:49 +0100551static void usb_serial_port_poison_urbs(struct usb_serial_port *port)
Pete Zaitcev34f8e762006-06-21 15:00:45 -0700552{
Johan Hovold27c7acf2010-05-05 23:57:37 +0200553 int i;
554
Johan Hovoldd83b4052011-11-06 19:06:37 +0100555 for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i)
Johan Hovold6a5c8212013-03-21 12:36:49 +0100556 usb_poison_urb(port->read_urbs[i]);
Johan Hovold27c7acf2010-05-05 23:57:37 +0200557 for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i)
Johan Hovold6a5c8212013-03-21 12:36:49 +0100558 usb_poison_urb(port->write_urbs[i]);
559
560 usb_poison_urb(port->interrupt_in_urb);
561 usb_poison_urb(port->interrupt_out_urb);
Oliver Neukum34ef50e2007-01-13 07:29:26 +0100562}
563
Johan Hovold6a5c8212013-03-21 12:36:49 +0100564static void usb_serial_port_unpoison_urbs(struct usb_serial_port *port)
565{
566 int i;
567
568 for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i)
569 usb_unpoison_urb(port->read_urbs[i]);
570 for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i)
571 usb_unpoison_urb(port->write_urbs[i]);
572
573 usb_unpoison_urb(port->interrupt_in_urb);
574 usb_unpoison_urb(port->interrupt_out_urb);
Oliver Neukum34ef50e2007-01-13 07:29:26 +0100575}
576
Johan Hovold69a3d212013-03-21 12:36:47 +0100577static void usb_serial_port_release(struct device *dev)
Oliver Neukum34ef50e2007-01-13 07:29:26 +0100578{
Alan Stern41bd34d2009-09-01 11:38:34 -0400579 struct usb_serial_port *port = to_usb_serial_port(dev);
Johan Hovold27c7acf2010-05-05 23:57:37 +0200580 int i;
Alan Stern41bd34d2009-09-01 11:38:34 -0400581
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700582 dev_dbg(dev, "%s\n", __func__);
Alan Stern41bd34d2009-09-01 11:38:34 -0400583
Oliver Neukum34ef50e2007-01-13 07:29:26 +0100584 usb_free_urb(port->interrupt_in_urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 usb_free_urb(port->interrupt_out_urb);
Johan Hovoldd83b4052011-11-06 19:06:37 +0100586 for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) {
587 usb_free_urb(port->read_urbs[i]);
588 kfree(port->bulk_in_buffers[i]);
589 }
Johan Hovold27c7acf2010-05-05 23:57:37 +0200590 for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) {
591 usb_free_urb(port->write_urbs[i]);
592 kfree(port->bulk_out_buffers[i]);
593 }
Stefani Seibold119eecc2009-12-23 09:10:48 +0100594 kfifo_free(&port->write_fifo);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 kfree(port->interrupt_in_buffer);
596 kfree(port->interrupt_out_buffer);
Jiri Slaby191c5f12012-11-15 09:49:56 +0100597 tty_port_destroy(&port->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 kfree(port);
599}
600
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100601static struct usb_serial *create_serial(struct usb_device *dev,
602 struct usb_interface *interface,
603 struct usb_serial_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604{
605 struct usb_serial *serial;
606
Eric Sesterhenn80b6ca42006-02-27 21:29:43 +0100607 serial = kzalloc(sizeof(*serial), GFP_KERNEL);
Johan Hovold6b03f7f2013-03-21 12:36:26 +0100608 if (!serial)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 serial->dev = usb_get_dev(dev);
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700611 serial->type = driver;
Johan Hovoldd7971052013-03-19 09:21:09 +0100612 serial->interface = usb_get_intf(interface);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 kref_init(&serial->kref);
Oliver Neukuma1cd7e92008-01-16 17:18:52 +0100614 mutex_init(&serial->disc_mutex);
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -0700615 serial->minors_reserved = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616
617 return serial;
618}
619
Greg Kroah-Hartman93bacef2006-12-17 21:50:23 +0100620static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf,
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100621 struct usb_serial_driver *drv)
Greg Kroah-Hartman93bacef2006-12-17 21:50:23 +0100622{
623 struct usb_dynid *dynid;
624
625 spin_lock(&drv->dynids.lock);
626 list_for_each_entry(dynid, &drv->dynids.list, node) {
627 if (usb_match_one_id(intf, &dynid->id)) {
628 spin_unlock(&drv->dynids.lock);
629 return &dynid->id;
630 }
631 }
632 spin_unlock(&drv->dynids.lock);
633 return NULL;
634}
635
636static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv,
637 struct usb_interface *intf)
638{
639 const struct usb_device_id *id;
640
641 id = usb_match_id(intf, drv->id_table);
642 if (id) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700643 dev_dbg(&intf->dev, "static descriptor matches\n");
Greg Kroah-Hartman93bacef2006-12-17 21:50:23 +0100644 goto exit;
645 }
646 id = match_dynamic_id(intf, drv);
647 if (id)
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700648 dev_dbg(&intf->dev, "dynamic descriptor matches\n");
Greg Kroah-Hartman93bacef2006-12-17 21:50:23 +0100649exit:
650 return id;
651}
652
Andi Kleen0daeed32010-06-01 23:04:42 +0200653/* Caller must hold table_lock */
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100654static struct usb_serial_driver *search_serial_device(
655 struct usb_interface *iface)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656{
Bjørn Mork954c3f82012-05-30 10:00:14 +0200657 const struct usb_device_id *id = NULL;
Alan Stern063a2da2007-10-10 16:24:06 -0400658 struct usb_serial_driver *drv;
Bjørn Mork954c3f82012-05-30 10:00:14 +0200659 struct usb_driver *driver = to_usb_driver(iface->dev.driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660
Adrian Bunk93b1fae2006-01-10 00:13:33 +0100661 /* Check if the usb id matches a known device */
Alan Stern063a2da2007-10-10 16:24:06 -0400662 list_for_each_entry(drv, &usb_serial_driver_list, driver_list) {
Bjørn Mork954c3f82012-05-30 10:00:14 +0200663 if (drv->usb_driver == driver)
664 id = get_iface_id(drv, iface);
Greg Kroah-Hartman93bacef2006-12-17 21:50:23 +0100665 if (id)
Alan Stern063a2da2007-10-10 16:24:06 -0400666 return drv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 }
668
669 return NULL;
670}
671
Johan Hovold395e08d2013-03-21 12:36:23 +0100672static int serial_port_carrier_raised(struct tty_port *port)
Alan Cox335f8512009-06-11 12:26:29 +0100673{
674 struct usb_serial_port *p = container_of(port, struct usb_serial_port, port);
675 struct usb_serial_driver *drv = p->serial->type;
Johan Hovold3e1f4902011-11-10 17:40:43 +0100676
Alan Cox335f8512009-06-11 12:26:29 +0100677 if (drv->carrier_raised)
678 return drv->carrier_raised(p);
679 /* No carrier control - don't block */
Johan Hovold3e1f4902011-11-10 17:40:43 +0100680 return 1;
Alan Cox335f8512009-06-11 12:26:29 +0100681}
682
Johan Hovold395e08d2013-03-21 12:36:23 +0100683static void serial_port_dtr_rts(struct tty_port *port, int on)
Alan Cox335f8512009-06-11 12:26:29 +0100684{
685 struct usb_serial_port *p = container_of(port, struct usb_serial_port, port);
Johan Hovoldf5f45302013-06-26 16:47:22 +0200686 struct usb_serial_driver *drv = p->serial->type;
Johan Hovold3e1f4902011-11-10 17:40:43 +0100687
Johan Hovoldf5f45302013-06-26 16:47:22 +0200688 if (drv->dtr_rts)
Alan Cox335f8512009-06-11 12:26:29 +0100689 drv->dtr_rts(p, on);
690}
691
Johan Hovold2deb96b2015-02-18 10:34:52 +0700692static ssize_t port_number_show(struct device *dev,
693 struct device_attribute *attr, char *buf)
694{
695 struct usb_serial_port *port = to_usb_serial_port(dev);
696
697 return sprintf(buf, "%u\n", port->port_number);
698}
699static DEVICE_ATTR_RO(port_number);
700
701static struct attribute *usb_serial_port_attrs[] = {
702 &dev_attr_port_number.attr,
703 NULL
704};
705ATTRIBUTE_GROUPS(usb_serial_port);
706
Alan Cox335f8512009-06-11 12:26:29 +0100707static const struct tty_port_operations serial_port_ops = {
Johan Hovold395e08d2013-03-21 12:36:23 +0100708 .carrier_raised = serial_port_carrier_raised,
709 .dtr_rts = serial_port_dtr_rts,
710 .activate = serial_port_activate,
711 .shutdown = serial_port_shutdown,
Alan Cox335f8512009-06-11 12:26:29 +0100712};
713
Johan Hovold1546e6a2014-08-21 19:33:25 +0200714static void find_endpoints(struct usb_serial *serial,
715 struct usb_serial_endpoints *epds)
716{
717 struct device *dev = &serial->interface->dev;
718 struct usb_host_interface *iface_desc;
719 struct usb_endpoint_descriptor *epd;
720 unsigned int i;
721
Johan Hovold8520ac02017-03-02 12:51:18 +0100722 BUILD_BUG_ON(ARRAY_SIZE(epds->bulk_in) < USB_MAXENDPOINTS / 2);
723 BUILD_BUG_ON(ARRAY_SIZE(epds->bulk_out) < USB_MAXENDPOINTS / 2);
724 BUILD_BUG_ON(ARRAY_SIZE(epds->interrupt_in) < USB_MAXENDPOINTS / 2);
725 BUILD_BUG_ON(ARRAY_SIZE(epds->interrupt_out) < USB_MAXENDPOINTS / 2);
726
Johan Hovold1546e6a2014-08-21 19:33:25 +0200727 iface_desc = serial->interface->cur_altsetting;
728 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
729 epd = &iface_desc->endpoint[i].desc;
730
731 if (usb_endpoint_is_bulk_in(epd)) {
732 dev_dbg(dev, "found bulk in on endpoint %u\n", i);
Johan Hovold1546e6a2014-08-21 19:33:25 +0200733 epds->bulk_in[epds->num_bulk_in++] = epd;
734 } else if (usb_endpoint_is_bulk_out(epd)) {
735 dev_dbg(dev, "found bulk out on endpoint %u\n", i);
Johan Hovold1546e6a2014-08-21 19:33:25 +0200736 epds->bulk_out[epds->num_bulk_out++] = epd;
737 } else if (usb_endpoint_is_int_in(epd)) {
738 dev_dbg(dev, "found interrupt in on endpoint %u\n", i);
Johan Hovold1546e6a2014-08-21 19:33:25 +0200739 epds->interrupt_in[epds->num_interrupt_in++] = epd;
740 } else if (usb_endpoint_is_int_out(epd)) {
741 dev_dbg(dev, "found interrupt out on endpoint %u\n", i);
Johan Hovold1546e6a2014-08-21 19:33:25 +0200742 epds->interrupt_out[epds->num_interrupt_out++] = epd;
743 }
744 }
745}
746
Johan Hovold45e5d4d2017-06-20 12:52:02 +0200747static int setup_port_bulk_in(struct usb_serial_port *port,
748 struct usb_endpoint_descriptor *epd)
749{
750 struct usb_serial_driver *type = port->serial->type;
751 struct usb_device *udev = port->serial->dev;
752 int buffer_size;
753 int i;
754
755 buffer_size = max_t(int, type->bulk_in_size, usb_endpoint_maxp(epd));
756 port->bulk_in_size = buffer_size;
757 port->bulk_in_endpointAddress = epd->bEndpointAddress;
758
759 for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) {
760 set_bit(i, &port->read_urbs_free);
761 port->read_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
762 if (!port->read_urbs[i])
763 return -ENOMEM;
764 port->bulk_in_buffers[i] = kmalloc(buffer_size, GFP_KERNEL);
765 if (!port->bulk_in_buffers[i])
766 return -ENOMEM;
767 usb_fill_bulk_urb(port->read_urbs[i], udev,
768 usb_rcvbulkpipe(udev, epd->bEndpointAddress),
769 port->bulk_in_buffers[i], buffer_size,
770 type->read_bulk_callback, port);
771 }
772
773 port->read_urb = port->read_urbs[0];
774 port->bulk_in_buffer = port->bulk_in_buffers[0];
775
776 return 0;
777}
778
779static int setup_port_bulk_out(struct usb_serial_port *port,
780 struct usb_endpoint_descriptor *epd)
781{
782 struct usb_serial_driver *type = port->serial->type;
783 struct usb_device *udev = port->serial->dev;
784 int buffer_size;
785 int i;
786
787 if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL))
788 return -ENOMEM;
789 if (type->bulk_out_size)
790 buffer_size = type->bulk_out_size;
791 else
792 buffer_size = usb_endpoint_maxp(epd);
793 port->bulk_out_size = buffer_size;
794 port->bulk_out_endpointAddress = epd->bEndpointAddress;
795
796 for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) {
797 set_bit(i, &port->write_urbs_free);
798 port->write_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
799 if (!port->write_urbs[i])
800 return -ENOMEM;
801 port->bulk_out_buffers[i] = kmalloc(buffer_size, GFP_KERNEL);
802 if (!port->bulk_out_buffers[i])
803 return -ENOMEM;
804 usb_fill_bulk_urb(port->write_urbs[i], udev,
805 usb_sndbulkpipe(udev, epd->bEndpointAddress),
806 port->bulk_out_buffers[i], buffer_size,
807 type->write_bulk_callback, port);
808 }
809
810 port->write_urb = port->write_urbs[0];
811 port->bulk_out_buffer = port->bulk_out_buffers[0];
812
813 return 0;
814}
815
816static int setup_port_interrupt_in(struct usb_serial_port *port,
817 struct usb_endpoint_descriptor *epd)
818{
819 struct usb_serial_driver *type = port->serial->type;
820 struct usb_device *udev = port->serial->dev;
821 int buffer_size;
822
823 port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
824 if (!port->interrupt_in_urb)
825 return -ENOMEM;
826 buffer_size = usb_endpoint_maxp(epd);
827 port->interrupt_in_endpointAddress = epd->bEndpointAddress;
828 port->interrupt_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
829 if (!port->interrupt_in_buffer)
830 return -ENOMEM;
831 usb_fill_int_urb(port->interrupt_in_urb, udev,
832 usb_rcvintpipe(udev, epd->bEndpointAddress),
833 port->interrupt_in_buffer, buffer_size,
834 type->read_int_callback, port,
835 epd->bInterval);
836
837 return 0;
838}
839
840static int setup_port_interrupt_out(struct usb_serial_port *port,
841 struct usb_endpoint_descriptor *epd)
842{
843 struct usb_serial_driver *type = port->serial->type;
844 struct usb_device *udev = port->serial->dev;
845 int buffer_size;
846
847 port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
848 if (!port->interrupt_out_urb)
849 return -ENOMEM;
850 buffer_size = usb_endpoint_maxp(epd);
851 port->interrupt_out_size = buffer_size;
852 port->interrupt_out_endpointAddress = epd->bEndpointAddress;
853 port->interrupt_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
854 if (!port->interrupt_out_buffer)
855 return -ENOMEM;
856 usb_fill_int_urb(port->interrupt_out_urb, udev,
857 usb_sndintpipe(udev, epd->bEndpointAddress),
858 port->interrupt_out_buffer, buffer_size,
859 type->write_int_callback, port,
860 epd->bInterval);
861
862 return 0;
863}
864
Greg Kroah-Hartman2edd2842012-05-07 14:46:48 -0700865static int usb_serial_probe(struct usb_interface *interface,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 const struct usb_device_id *id)
867{
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700868 struct device *ddev = &interface->dev;
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100869 struct usb_device *dev = interface_to_usbdev(interface);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 struct usb_serial *serial = NULL;
871 struct usb_serial_port *port;
Johan Hovold1546e6a2014-08-21 19:33:25 +0200872 struct usb_serial_endpoints *epds;
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -0700873 struct usb_serial_driver *type = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 int retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876 int num_ports = 0;
Johan Hovoldef88f332017-03-02 12:51:15 +0100877 unsigned char max_endpoints;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878
Andi Kleen0daeed32010-06-01 23:04:42 +0200879 mutex_lock(&table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 type = search_serial_device(interface);
881 if (!type) {
Andi Kleen0daeed32010-06-01 23:04:42 +0200882 mutex_unlock(&table_lock);
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700883 dev_dbg(ddev, "none matched\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 return -ENODEV;
885 }
886
Andi Kleen0daeed32010-06-01 23:04:42 +0200887 if (!try_module_get(type->driver.owner)) {
888 mutex_unlock(&table_lock);
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700889 dev_err(ddev, "module get failed, exiting\n");
Andi Kleen0daeed32010-06-01 23:04:42 +0200890 return -EIO;
891 }
892 mutex_unlock(&table_lock);
893
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100894 serial = create_serial(dev, interface, type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895 if (!serial) {
Johan Hovoldc2fef452017-03-02 12:51:14 +0100896 retval = -ENOMEM;
897 goto err_put_module;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898 }
899
900 /* if this device type has a probe function, call it */
901 if (type->probe) {
902 const struct usb_device_id *id;
903
Greg Kroah-Hartman93bacef2006-12-17 21:50:23 +0100904 id = get_iface_id(type, interface);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 retval = type->probe(serial, id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906
907 if (retval) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700908 dev_dbg(ddev, "sub driver rejected device\n");
Johan Hovoldc2fef452017-03-02 12:51:14 +0100909 goto err_put_serial;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 }
911 }
912
913 /* descriptor matches, let's find the endpoints needed */
Johan Hovold1546e6a2014-08-21 19:33:25 +0200914 epds = kzalloc(sizeof(*epds), GFP_KERNEL);
915 if (!epds) {
916 retval = -ENOMEM;
917 goto err_put_serial;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 }
919
Johan Hovold1546e6a2014-08-21 19:33:25 +0200920 find_endpoints(serial, epds);
921
Johan Hovold92e6b2c2017-03-02 12:51:19 +0100922 if (epds->num_bulk_in < type->num_bulk_in ||
923 epds->num_bulk_out < type->num_bulk_out ||
924 epds->num_interrupt_in < type->num_interrupt_in ||
925 epds->num_interrupt_out < type->num_interrupt_out) {
926 dev_err(ddev, "required endpoints missing\n");
927 retval = -ENODEV;
928 goto err_free_epds;
929 }
Johan Hovolda7944992017-03-16 17:13:32 +0100930
931 if (type->calc_num_ports) {
932 retval = type->calc_num_ports(serial, epds);
933 if (retval < 0)
Johan Hovold92e6b2c2017-03-02 12:51:19 +0100934 goto err_free_epds;
Johan Hovolda7944992017-03-16 17:13:32 +0100935 num_ports = retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 }
Johan Hovolda7944992017-03-16 17:13:32 +0100937
938 if (!num_ports)
939 num_ports = type->num_ports;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940
Johan Hovold56546992014-08-27 11:55:19 +0200941 if (num_ports > MAX_NUM_PORTS) {
942 dev_warn(ddev, "too many ports requested: %d\n", num_ports);
943 num_ports = MAX_NUM_PORTS;
944 }
945
Johan Hovoldef88f332017-03-02 12:51:15 +0100946 serial->num_ports = (unsigned char)num_ports;
Johan Hovold1546e6a2014-08-21 19:33:25 +0200947 serial->num_bulk_in = epds->num_bulk_in;
948 serial->num_bulk_out = epds->num_bulk_out;
949 serial->num_interrupt_in = epds->num_interrupt_in;
950 serial->num_interrupt_out = epds->num_interrupt_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951
Alan Stern063a2da2007-10-10 16:24:06 -0400952 /* found all that we need */
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -0700953 dev_info(ddev, "%s converter detected\n", type->description);
Alan Stern063a2da2007-10-10 16:24:06 -0400954
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 /* create our ports, we need as many as the max endpoints */
Alan Coxa8d6f0a2008-07-22 11:12:24 +0100956 /* we don't use num_ports here because some devices have more
957 endpoint pairs than ports */
Johan Hovold1546e6a2014-08-21 19:33:25 +0200958 max_endpoints = max(epds->num_bulk_in, epds->num_bulk_out);
959 max_endpoints = max(max_endpoints, epds->num_interrupt_in);
960 max_endpoints = max(max_endpoints, epds->num_interrupt_out);
Johan Hovoldef88f332017-03-02 12:51:15 +0100961 max_endpoints = max(max_endpoints, serial->num_ports);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962 serial->num_port_pointers = max_endpoints;
Oliver Neukum4b10f0f2007-01-13 07:31:27 +0100963
Johan Hovoldd9a38a82014-03-12 19:09:42 +0100964 dev_dbg(ddev, "setting up %d port structure(s)\n", max_endpoints);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965 for (i = 0; i < max_endpoints; ++i) {
Eric Sesterhenn80b6ca42006-02-27 21:29:43 +0100966 port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
Johan Hovoldc22ac6d2017-06-20 12:52:03 +0200967 if (!port) {
968 retval = -ENOMEM;
969 goto err_free_epds;
970 }
Alan Cox4a90f092008-10-13 10:39:46 +0100971 tty_port_init(&port->port);
Alan Cox335f8512009-06-11 12:26:29 +0100972 port->port.ops = &serial_port_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 port->serial = serial;
Greg Kroah-Hartman507ca9b2005-04-23 12:49:16 -0700974 spin_lock_init(&port->lock);
Alan Coxe1108a62009-10-06 16:06:36 +0100975 /* Keep this for private driver use for the moment but
976 should probably go away */
David Howellsc4028952006-11-22 14:57:56 +0000977 INIT_WORK(&port->work, usb_serial_port_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978 serial->port[i] = port;
Alan Stern41bd34d2009-09-01 11:38:34 -0400979 port->dev.parent = &interface->dev;
980 port->dev.driver = NULL;
981 port->dev.bus = &usb_serial_bus_type;
Johan Hovold69a3d212013-03-21 12:36:47 +0100982 port->dev.release = &usb_serial_port_release;
Johan Hovold2deb96b2015-02-18 10:34:52 +0700983 port->dev.groups = usb_serial_port_groups;
Alan Stern41bd34d2009-09-01 11:38:34 -0400984 device_initialize(&port->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985 }
986
987 /* set up the endpoint information */
Johan Hovold1546e6a2014-08-21 19:33:25 +0200988 for (i = 0; i < epds->num_bulk_in; ++i) {
Johan Hovold45e5d4d2017-06-20 12:52:02 +0200989 retval = setup_port_bulk_in(serial->port[i], epds->bulk_in[i]);
990 if (retval)
Johan Hovoldc22ac6d2017-06-20 12:52:03 +0200991 goto err_free_epds;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992 }
993
Johan Hovold1546e6a2014-08-21 19:33:25 +0200994 for (i = 0; i < epds->num_bulk_out; ++i) {
Johan Hovold45e5d4d2017-06-20 12:52:02 +0200995 retval = setup_port_bulk_out(serial->port[i],
996 epds->bulk_out[i]);
997 if (retval)
Johan Hovoldc22ac6d2017-06-20 12:52:03 +0200998 goto err_free_epds;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999 }
1000
1001 if (serial->type->read_int_callback) {
Johan Hovold1546e6a2014-08-21 19:33:25 +02001002 for (i = 0; i < epds->num_interrupt_in; ++i) {
Johan Hovold45e5d4d2017-06-20 12:52:02 +02001003 retval = setup_port_interrupt_in(serial->port[i],
1004 epds->interrupt_in[i]);
1005 if (retval)
Johan Hovoldc22ac6d2017-06-20 12:52:03 +02001006 goto err_free_epds;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007 }
Johan Hovold1546e6a2014-08-21 19:33:25 +02001008 } else if (epds->num_interrupt_in) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001009 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 -07001010 }
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001011
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 if (serial->type->write_int_callback) {
Johan Hovold1546e6a2014-08-21 19:33:25 +02001013 for (i = 0; i < epds->num_interrupt_out; ++i) {
Johan Hovold45e5d4d2017-06-20 12:52:02 +02001014 retval = setup_port_interrupt_out(serial->port[i],
1015 epds->interrupt_out[i]);
1016 if (retval)
Johan Hovoldc22ac6d2017-06-20 12:52:03 +02001017 goto err_free_epds;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018 }
Johan Hovold1546e6a2014-08-21 19:33:25 +02001019 } else if (epds->num_interrupt_out) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001020 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 -07001021 }
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001022
Johan Hovoldbdce6612012-04-25 15:56:32 +02001023 usb_set_intfdata(interface, serial);
1024
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 /* if this device type has an attach function, call it */
1026 if (type->attach) {
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001027 retval = type->attach(serial);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 if (retval < 0)
Johan Hovoldc22ac6d2017-06-20 12:52:03 +02001029 goto err_free_epds;
Alan Sterna4720c62009-10-09 12:43:12 -04001030 serial->attached = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 if (retval > 0) {
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001032 /* quietly accept this device, but don't bind to a
1033 serial port as it's about to disappear */
Alan Stern0a3c8542009-05-27 11:25:52 -04001034 serial->num_ports = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035 goto exit;
1036 }
Alan Sterna4720c62009-10-09 12:43:12 -04001037 } else {
1038 serial->attached = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039 }
1040
Johan Hovoldc22ac6d2017-06-20 12:52:03 +02001041 retval = allocate_minors(serial, num_ports);
1042 if (retval) {
Greg Kroah-Hartmane5b1e202013-06-07 11:04:28 -07001043 dev_err(ddev, "No more free serial minor numbers\n");
Johan Hovoldc22ac6d2017-06-20 12:52:03 +02001044 goto err_free_epds;
Oliver Neukum34ef50e2007-01-13 07:29:26 +01001045 }
1046
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 /* register all of the individual ports with the driver core */
1048 for (i = 0; i < num_ports; ++i) {
1049 port = serial->port[i];
Greg Kroah-Hartman11438322013-06-06 10:32:00 -07001050 dev_set_name(&port->dev, "ttyUSB%d", port->minor);
Johan Hovoldd9a38a82014-03-12 19:09:42 +01001051 dev_dbg(ddev, "registering %s\n", dev_name(&port->dev));
Ming Leia7a6b792010-07-13 23:56:24 +08001052 device_enable_async_suspend(&port->dev);
1053
Alan Stern41bd34d2009-09-01 11:38:34 -04001054 retval = device_add(&port->dev);
Alan Stern891a3b12012-03-28 16:10:49 -04001055 if (retval)
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001056 dev_err(ddev, "Error registering port device, continuing\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 }
1058
Johan Hovold126d26f2016-10-21 12:56:27 +02001059 if (num_ports > 0)
1060 usb_serial_console_init(serial->port[0]->minor);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061exit:
Johan Hovold1546e6a2014-08-21 19:33:25 +02001062 kfree(epds);
Ming Leid92a3ca2010-08-07 16:20:35 +08001063 module_put(type->driver.owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 return 0;
1065
Johan Hovold92e6b2c2017-03-02 12:51:19 +01001066err_free_epds:
1067 kfree(epds);
Johan Hovoldc2fef452017-03-02 12:51:14 +01001068err_put_serial:
Alan Stern41bd34d2009-09-01 11:38:34 -04001069 usb_serial_put(serial);
Johan Hovoldc2fef452017-03-02 12:51:14 +01001070err_put_module:
Ming Leid92a3ca2010-08-07 16:20:35 +08001071 module_put(type->driver.owner);
Johan Hovoldc2fef452017-03-02 12:51:14 +01001072
1073 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074}
1075
Greg Kroah-Hartman32078f92012-05-07 14:02:13 -07001076static void usb_serial_disconnect(struct usb_interface *interface)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077{
1078 int i;
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001079 struct usb_serial *serial = usb_get_intfdata(interface);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 struct device *dev = &interface->dev;
1081 struct usb_serial_port *port;
Johan Hovold3fff3b42014-05-26 19:23:34 +02001082 struct tty_struct *tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083
Guennadi Liakhovetski73e487f2006-04-25 07:46:17 +02001084 usb_serial_console_disconnect(serial);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085
Oliver Neukuma1cd7e92008-01-16 17:18:52 +01001086 mutex_lock(&serial->disc_mutex);
Oliver Neukuma1cd7e92008-01-16 17:18:52 +01001087 /* must set a flag, to signal subdrivers */
1088 serial->disconnected = 1;
Alan Stern2d931482009-04-14 11:31:02 -04001089 mutex_unlock(&serial->disc_mutex);
1090
Oliver Neukuma1cd7e92008-01-16 17:18:52 +01001091 for (i = 0; i < serial->num_ports; ++i) {
1092 port = serial->port[i];
Johan Hovold3fff3b42014-05-26 19:23:34 +02001093 tty = tty_port_tty_get(&port->port);
1094 if (tty) {
1095 tty_vhangup(tty);
1096 tty_kref_put(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 }
Johan Hovold3fff3b42014-05-26 19:23:34 +02001098 usb_serial_port_poison_urbs(port);
1099 wake_up_interruptible(&port->port.delta_msr_wait);
1100 cancel_work_sync(&port->work);
1101 if (device_is_registered(&port->dev))
1102 device_del(&port->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 }
Johan Hovold0f16cfe2013-03-21 12:36:42 +01001104 if (serial->type->disconnect)
1105 serial->type->disconnect(serial);
Alan Stern2d931482009-04-14 11:31:02 -04001106
Alan Stern41bd34d2009-09-01 11:38:34 -04001107 /* let the last holder of this object cause it to be cleaned up */
Oliver Neukuma1cd7e92008-01-16 17:18:52 +01001108 usb_serial_put(serial);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109 dev_info(dev, "device disconnected\n");
1110}
1111
Oliver Neukumec225592007-04-27 20:54:57 +02001112int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
1113{
1114 struct usb_serial *serial = usb_get_intfdata(intf);
Oliver Neukumec225592007-04-27 20:54:57 +02001115 int i, r = 0;
1116
Oliver Neukumf8bece82009-02-05 16:54:25 +01001117 serial->suspending = 1;
1118
Ming Lei93e4f472013-03-15 12:08:54 +08001119 /*
1120 * serial->type->suspend() MUST return 0 in system sleep context,
1121 * otherwise, the resume callback has to recover device from
1122 * previous suspend failure.
1123 */
Oliver Neukum81e5b232009-07-21 08:47:34 +02001124 if (serial->type->suspend) {
1125 r = serial->type->suspend(serial, message);
Oliver Neukuma5f60052009-10-01 15:01:17 +02001126 if (r < 0) {
1127 serial->suspending = 0;
Oliver Neukum81e5b232009-07-21 08:47:34 +02001128 goto err_out;
Oliver Neukuma5f60052009-10-01 15:01:17 +02001129 }
Oliver Neukum81e5b232009-07-21 08:47:34 +02001130 }
1131
Johan Hovold3fff3b42014-05-26 19:23:34 +02001132 for (i = 0; i < serial->num_ports; ++i)
1133 usb_serial_port_poison_urbs(serial->port[i]);
Oliver Neukum81e5b232009-07-21 08:47:34 +02001134err_out:
Oliver Neukumec225592007-04-27 20:54:57 +02001135 return r;
1136}
1137EXPORT_SYMBOL(usb_serial_suspend);
1138
Johan Hovold6a5c8212013-03-21 12:36:49 +01001139static void usb_serial_unpoison_port_urbs(struct usb_serial *serial)
1140{
Johan Hovold6a5c8212013-03-21 12:36:49 +01001141 int i;
1142
Johan Hovold3fff3b42014-05-26 19:23:34 +02001143 for (i = 0; i < serial->num_ports; ++i)
1144 usb_serial_port_unpoison_urbs(serial->port[i]);
Johan Hovold6a5c8212013-03-21 12:36:49 +01001145}
1146
Oliver Neukumec225592007-04-27 20:54:57 +02001147int usb_serial_resume(struct usb_interface *intf)
1148{
1149 struct usb_serial *serial = usb_get_intfdata(intf);
Oliver Neukumc49cfa912009-02-06 18:06:43 +01001150 int rv;
Oliver Neukumec225592007-04-27 20:54:57 +02001151
Johan Hovold6a5c8212013-03-21 12:36:49 +01001152 usb_serial_unpoison_port_urbs(serial);
1153
Oliver Neukumf8bece82009-02-05 16:54:25 +01001154 serial->suspending = 0;
Sarah Sharp8abaee22007-10-25 10:58:43 -07001155 if (serial->type->resume)
Oliver Neukumc49cfa912009-02-06 18:06:43 +01001156 rv = serial->type->resume(serial);
1157 else
1158 rv = usb_serial_generic_resume(serial);
Oliver Neukumf8bece82009-02-05 16:54:25 +01001159
Oliver Neukumc49cfa912009-02-06 18:06:43 +01001160 return rv;
Oliver Neukumec225592007-04-27 20:54:57 +02001161}
1162EXPORT_SYMBOL(usb_serial_resume);
1163
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07001164static int usb_serial_reset_resume(struct usb_interface *intf)
1165{
1166 struct usb_serial *serial = usb_get_intfdata(intf);
1167 int rv;
1168
Johan Hovold6a5c8212013-03-21 12:36:49 +01001169 usb_serial_unpoison_port_urbs(serial);
1170
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07001171 serial->suspending = 0;
Johan Hovoldca0400d2014-03-12 19:09:41 +01001172 if (serial->type->reset_resume) {
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07001173 rv = serial->type->reset_resume(serial);
Johan Hovoldca0400d2014-03-12 19:09:41 +01001174 } else {
Greg Kroah-Hartmandcd82cd2012-05-16 08:37:17 -07001175 rv = -EOPNOTSUPP;
1176 intf->needs_binding = 1;
1177 }
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07001178
1179 return rv;
1180}
1181
Jeff Dikeb68e31d2006-10-02 02:17:18 -07001182static const struct tty_operations serial_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 .open = serial_open,
1184 .close = serial_close,
1185 .write = serial_write,
Johan Hovold3e1f4902011-11-10 17:40:43 +01001186 .hangup = serial_hangup,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187 .write_room = serial_write_room,
1188 .ioctl = serial_ioctl,
1189 .set_termios = serial_set_termios,
1190 .throttle = serial_throttle,
1191 .unthrottle = serial_unthrottle,
1192 .break_ctl = serial_break,
1193 .chars_in_buffer = serial_chars_in_buffer,
Johan Hovold06931962013-05-05 20:32:27 +02001194 .wait_until_sent = serial_wait_until_sent,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 .tiocmget = serial_tiocmget,
1196 .tiocmset = serial_tiocmset,
Johan Hovold3e1f4902011-11-10 17:40:43 +01001197 .get_icount = serial_get_icount,
Al Viro81732b22018-09-11 23:28:07 -04001198 .set_serial = serial_set_serial,
1199 .get_serial = serial_get_serial,
Johan Hovold3e1f4902011-11-10 17:40:43 +01001200 .cleanup = serial_cleanup,
1201 .install = serial_install,
Christoph Hellwig8a8dcab2018-04-13 21:04:45 +02001202 .proc_show = serial_proc_show,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203};
1204
Alan Cox335f8512009-06-11 12:26:29 +01001205
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206struct tty_driver *usb_serial_tty_driver;
1207
1208static int __init usb_serial_init(void)
1209{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 int result;
1211
Greg Kroah-Hartman455b4f72013-06-06 10:31:35 -07001212 usb_serial_tty_driver = alloc_tty_driver(USB_SERIAL_TTY_MINORS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 if (!usb_serial_tty_driver)
1214 return -ENOMEM;
1215
1216 /* Initialize our global data */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217 result = bus_register(&usb_serial_bus_type);
1218 if (result) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001219 pr_err("%s - registering bus driver failed\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 goto exit_bus;
1221 }
1222
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 usb_serial_tty_driver->driver_name = "usbserial";
Johan Hovold3e1f4902011-11-10 17:40:43 +01001224 usb_serial_tty_driver->name = "ttyUSB";
Greg Kroah-Hartman455b4f72013-06-06 10:31:35 -07001225 usb_serial_tty_driver->major = USB_SERIAL_TTY_MAJOR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226 usb_serial_tty_driver->minor_start = 0;
1227 usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
1228 usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL;
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001229 usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW |
1230 TTY_DRIVER_DYNAMIC_DEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 usb_serial_tty_driver->init_termios = tty_std_termios;
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001232 usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD
1233 | HUPCL | CLOCAL;
Alan Coxa5b6f602008-04-08 17:16:06 +01001234 usb_serial_tty_driver->init_termios.c_ispeed = 9600;
1235 usb_serial_tty_driver->init_termios.c_ospeed = 9600;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 tty_set_operations(usb_serial_tty_driver, &serial_ops);
1237 result = tty_register_driver(usb_serial_tty_driver);
1238 if (result) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001239 pr_err("%s - tty_register_driver failed\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 goto exit_reg_driver;
1241 }
1242
Greg Kroah-Hartman06299db2005-05-26 05:55:55 -07001243 /* register the generic driver, if we should */
Greg Kroah-Hartman3033bc82012-09-18 16:05:17 +01001244 result = usb_serial_generic_register();
Greg Kroah-Hartman06299db2005-05-26 05:55:55 -07001245 if (result < 0) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001246 pr_err("%s - registering generic driver failed\n", __func__);
Greg Kroah-Hartman06299db2005-05-26 05:55:55 -07001247 goto exit_generic;
1248 }
1249
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250 return result;
1251
Greg Kroah-Hartman06299db2005-05-26 05:55:55 -07001252exit_generic:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 tty_unregister_driver(usb_serial_tty_driver);
1254
1255exit_reg_driver:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 bus_unregister(&usb_serial_bus_type);
1257
1258exit_bus:
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001259 pr_err("%s - returning with error %d\n", __func__, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260 put_tty_driver(usb_serial_tty_driver);
1261 return result;
1262}
1263
1264
1265static void __exit usb_serial_exit(void)
1266{
1267 usb_serial_console_exit();
1268
1269 usb_serial_generic_deregister();
1270
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271 tty_unregister_driver(usb_serial_tty_driver);
1272 put_tty_driver(usb_serial_tty_driver);
1273 bus_unregister(&usb_serial_bus_type);
Johannes Thumshirnd23f47d2015-07-08 17:26:37 +02001274 idr_destroy(&serial_minors);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275}
1276
1277
1278module_init(usb_serial_init);
1279module_exit(usb_serial_exit);
1280
1281#define set_to_generic_if_null(type, function) \
1282 do { \
1283 if (!type->function) { \
1284 type->function = usb_serial_generic_##function; \
Johan Hovoldc3452f52013-03-21 12:36:44 +01001285 pr_debug("%s: using generic " #function "\n", \
1286 type->driver.name); \
1287 } \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288 } while (0)
1289
Johan Hovoldc3452f52013-03-21 12:36:44 +01001290static void usb_serial_operations_init(struct usb_serial_driver *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291{
1292 set_to_generic_if_null(device, open);
1293 set_to_generic_if_null(device, write);
1294 set_to_generic_if_null(device, close);
1295 set_to_generic_if_null(device, write_room);
1296 set_to_generic_if_null(device, chars_in_buffer);
Johan Hovolddcf01052013-05-08 17:51:43 +02001297 if (device->tx_empty)
1298 set_to_generic_if_null(device, wait_until_sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299 set_to_generic_if_null(device, read_bulk_callback);
1300 set_to_generic_if_null(device, write_bulk_callback);
Johan Hovold23154322010-03-17 23:05:57 +01001301 set_to_generic_if_null(device, process_read_urb);
Johan Hovoldeaa3bcb2010-03-17 23:06:08 +01001302 set_to_generic_if_null(device, prepare_write_buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303}
1304
Greg Kroah-Hartmanf799e762012-02-24 12:50:30 -08001305static int usb_serial_register(struct usb_serial_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306{
1307 int retval;
1308
Dave Younge4abe662009-02-14 21:21:13 +08001309 if (usb_disabled())
1310 return -ENODEV;
1311
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -07001312 if (!driver->description)
1313 driver->description = driver->driver.name;
Alan Stern5620b5f2011-01-11 14:16:50 -05001314 if (!driver->usb_driver) {
1315 WARN(1, "Serial driver %s has no usb_driver\n",
1316 driver->description);
1317 return -EINVAL;
1318 }
Greg Kroah-Hartman269bda12005-06-20 21:15:16 -07001319
Johan Hovoldfdb838e2020-01-16 17:07:05 +01001320 /* Prevent individual ports from being unbound. */
1321 driver->driver.suppress_bind_attrs = true;
1322
Johan Hovoldc3452f52013-03-21 12:36:44 +01001323 usb_serial_operations_init(driver);
1324
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325 /* Add this device to our list of devices */
Andi Kleen0daeed32010-06-01 23:04:42 +02001326 mutex_lock(&table_lock);
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -07001327 list_add(&driver->driver_list, &usb_serial_driver_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -07001329 retval = usb_serial_bus_register(driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330 if (retval) {
Greg Kroah-Hartman92931d22012-09-13 16:30:31 -07001331 pr_err("problem %d when registering driver %s\n", retval, driver->description);
Greg Kroah-Hartmanea653702005-06-20 21:15:16 -07001332 list_del(&driver->driver_list);
Johan Hovoldca0400d2014-03-12 19:09:41 +01001333 } else {
Greg Kroah-Hartmanee42f6c2012-09-18 17:10:29 +01001334 pr_info("USB Serial support registered for %s\n", driver->description);
Johan Hovoldca0400d2014-03-12 19:09:41 +01001335 }
Andi Kleen0daeed32010-06-01 23:04:42 +02001336 mutex_unlock(&table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 return retval;
1338}
1339
Greg Kroah-Hartmanf799e762012-02-24 12:50:30 -08001340static void usb_serial_deregister(struct usb_serial_driver *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341{
Greg Kroah-Hartmanee42f6c2012-09-18 17:10:29 +01001342 pr_info("USB Serial deregistering driver %s\n", device->description);
Johan Hovold10164c22014-04-23 11:32:19 +02001343
Andi Kleen0daeed32010-06-01 23:04:42 +02001344 mutex_lock(&table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 list_del(&device->driver_list);
Andi Kleen0daeed32010-06-01 23:04:42 +02001346 mutex_unlock(&table_lock);
Johan Hovold10164c22014-04-23 11:32:19 +02001347
1348 usb_serial_bus_deregister(device);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350
Alan Stern765e0ba2012-02-23 14:55:59 -05001351/**
1352 * usb_serial_register_drivers - register drivers for a usb-serial module
Alan Stern765e0ba2012-02-23 14:55:59 -05001353 * @serial_drivers: NULL-terminated array of pointers to drivers to be registered
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001354 * @name: name of the usb_driver for this set of @serial_drivers
1355 * @id_table: list of all devices this @serial_drivers set binds to
Alan Stern765e0ba2012-02-23 14:55:59 -05001356 *
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001357 * Registers all the drivers in the @serial_drivers array, and dynamically
1358 * creates a struct usb_driver with the name @name and id_table of @id_table.
Alan Stern765e0ba2012-02-23 14:55:59 -05001359 */
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001360int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[],
1361 const char *name,
1362 const struct usb_device_id *id_table)
Alan Stern765e0ba2012-02-23 14:55:59 -05001363{
1364 int rc;
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001365 struct usb_driver *udriver;
Alan Stern765e0ba2012-02-23 14:55:59 -05001366 struct usb_serial_driver * const *sd;
1367
1368 /*
1369 * udriver must be registered before any of the serial drivers,
1370 * because the store_new_id() routine for the serial drivers (in
1371 * bus.c) probes udriver.
1372 *
1373 * Performance hack: We don't want udriver to be probed until
1374 * the serial drivers are registered, because the probe would
1375 * simply fail for lack of a matching serial driver.
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001376 * So we leave udriver's id_table set to NULL until we are all set.
Alan Stern5cbe61c2012-05-07 11:20:06 -04001377 *
1378 * Suspend/resume support is implemented in the usb-serial core,
1379 * so fill in the PM-related fields in udriver.
Alan Stern765e0ba2012-02-23 14:55:59 -05001380 */
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001381 udriver = kzalloc(sizeof(*udriver), GFP_KERNEL);
1382 if (!udriver)
1383 return -ENOMEM;
Alan Stern765e0ba2012-02-23 14:55:59 -05001384
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001385 udriver->name = name;
Alan Stern765e0ba2012-02-23 14:55:59 -05001386 udriver->no_dynamic_id = 1;
Alan Stern5cbe61c2012-05-07 11:20:06 -04001387 udriver->supports_autosuspend = 1;
1388 udriver->suspend = usb_serial_suspend;
1389 udriver->resume = usb_serial_resume;
Greg Kroah-Hartman5026bb02012-05-07 13:48:33 -07001390 udriver->probe = usb_serial_probe;
Greg Kroah-Hartman32078f92012-05-07 14:02:13 -07001391 udriver->disconnect = usb_serial_disconnect;
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07001392
1393 /* we only set the reset_resume field if the serial_driver has one */
1394 for (sd = serial_drivers; *sd; ++sd) {
Greg Kroah-Hartman44b0f082012-09-19 08:15:21 +01001395 if ((*sd)->reset_resume) {
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07001396 udriver->reset_resume = usb_serial_reset_resume;
1397 break;
Greg Kroah-Hartman44b0f082012-09-19 08:15:21 +01001398 }
Greg Kroah-Hartman71863642012-05-15 15:40:00 -07001399 }
1400
Alan Stern765e0ba2012-02-23 14:55:59 -05001401 rc = usb_register(udriver);
1402 if (rc)
Alexey Klimov647024a2016-08-08 02:34:46 +01001403 goto failed_usb_register;
Alan Stern765e0ba2012-02-23 14:55:59 -05001404
1405 for (sd = serial_drivers; *sd; ++sd) {
1406 (*sd)->usb_driver = udriver;
1407 rc = usb_serial_register(*sd);
1408 if (rc)
1409 goto failed;
1410 }
1411
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001412 /* Now set udriver's id_table and look for matches */
1413 udriver->id_table = id_table;
Alan Stern765e0ba2012-02-23 14:55:59 -05001414 rc = driver_attach(&udriver->drvwrap.driver);
1415 return 0;
1416
1417 failed:
1418 while (sd-- > serial_drivers)
1419 usb_serial_deregister(*sd);
1420 usb_deregister(udriver);
Alexey Klimov647024a2016-08-08 02:34:46 +01001421failed_usb_register:
1422 kfree(udriver);
Alan Stern765e0ba2012-02-23 14:55:59 -05001423 return rc;
1424}
1425EXPORT_SYMBOL_GPL(usb_serial_register_drivers);
1426
1427/**
1428 * usb_serial_deregister_drivers - deregister drivers for a usb-serial module
Alan Stern765e0ba2012-02-23 14:55:59 -05001429 * @serial_drivers: NULL-terminated array of pointers to drivers to be deregistered
1430 *
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001431 * Deregisters all the drivers in the @serial_drivers array and deregisters and
1432 * frees the struct usb_driver that was created by the call to
1433 * usb_serial_register_drivers().
Alan Stern765e0ba2012-02-23 14:55:59 -05001434 */
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001435void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[])
Alan Stern765e0ba2012-02-23 14:55:59 -05001436{
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001437 struct usb_driver *udriver = (*serial_drivers)->usb_driver;
1438
Alan Stern765e0ba2012-02-23 14:55:59 -05001439 for (; *serial_drivers; ++serial_drivers)
1440 usb_serial_deregister(*serial_drivers);
1441 usb_deregister(udriver);
Greg Kroah-Hartman68e24112012-05-08 15:46:14 -07001442 kfree(udriver);
Alan Stern765e0ba2012-02-23 14:55:59 -05001443}
1444EXPORT_SYMBOL_GPL(usb_serial_deregister_drivers);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445
Alan Coxa8d6f0a2008-07-22 11:12:24 +01001446MODULE_AUTHOR(DRIVER_AUTHOR);
1447MODULE_DESCRIPTION(DRIVER_DESC);
Johan Hovold627cfa82017-11-03 18:12:08 +01001448MODULE_LICENSE("GPL v2");