Commit | Line | Data |
---|---|---|
5fd54ace | 1 | // SPDX-License-Identifier: GPL-2.0 |
1da177e4 LT |
2 | /* |
3 | * USB Serial Converter driver | |
4 | * | |
659597b7 | 5 | * Copyright (C) 2009 - 2013 Johan Hovold (jhovold@gmail.com) |
7186364e | 6 | * Copyright (C) 1999 - 2012 Greg Kroah-Hartman (greg@kroah.com) |
1da177e4 LT |
7 | * Copyright (C) 2000 Peter Berger (pberger@brimson.com) |
8 | * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com) | |
9 | * | |
502b95c1 | 10 | * This driver was originally based on the ACM driver by Armin Fuerst (which was |
1da177e4 LT |
11 | * based on a driver by Brad Keryan) |
12 | * | |
ecefae6d | 13 | * See Documentation/usb/usb-serial.rst for more information on using this |
a8d6f0a9 | 14 | * driver |
1da177e4 LT |
15 | */ |
16 | ||
92931d24 GKH |
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
18 | ||
1da177e4 LT |
19 | #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> | |
6fd69d3c | 28 | #include <linux/seq_file.h> |
1da177e4 | 29 | #include <linux/spinlock.h> |
1ce7dd26 | 30 | #include <linux/mutex.h> |
1da177e4 | 31 | #include <linux/list.h> |
a8d6f0a9 | 32 | #include <linux/uaccess.h> |
c56d3000 | 33 | #include <linux/serial.h> |
1da177e4 | 34 | #include <linux/usb.h> |
a969888c | 35 | #include <linux/usb/serial.h> |
8e8dce06 | 36 | #include <linux/kfifo.h> |
e5b1e206 | 37 | #include <linux/idr.h> |
1da177e4 | 38 | |
ee42f6c9 | 39 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@linuxfoundation.org>" |
1da177e4 LT |
40 | #define DRIVER_DESC "USB Serial Driver core" |
41 | ||
455b4f7e GKH |
42 | #define USB_SERIAL_TTY_MAJOR 188 |
43 | #define USB_SERIAL_TTY_MINORS 512 /* should be enough for a while */ | |
44 | ||
1da177e4 LT |
45 | /* 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 | ||
e5b1e206 | 52 | static DEFINE_IDR(serial_minors); |
3ddad823 | 53 | static DEFINE_MUTEX(table_lock); |
1da177e4 LT |
54 | static LIST_HEAD(usb_serial_driver_list); |
55 | ||
8bc2c1b2 | 56 | /* |
e5b1e206 GKH |
57 | * 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. | |
8bc2c1b2 | 60 | */ |
e5b1e206 | 61 | struct usb_serial_port *usb_serial_port_get_by_minor(unsigned minor) |
1da177e4 | 62 | { |
34ef50e5 | 63 | struct usb_serial *serial; |
e5b1e206 | 64 | struct usb_serial_port *port; |
34ef50e5 | 65 | |
3ddad823 | 66 | mutex_lock(&table_lock); |
e5b1e206 GKH |
67 | port = idr_find(&serial_minors, minor); |
68 | if (!port) | |
69 | goto exit; | |
70 | ||
71 | 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); | |
8bc2c1b2 | 78 | } |
e5b1e206 | 79 | exit: |
3ddad823 | 80 | mutex_unlock(&table_lock); |
e5b1e206 | 81 | return port; |
1da177e4 LT |
82 | } |
83 | ||
e5b1e206 | 84 | static int allocate_minors(struct usb_serial *serial, int num_ports) |
1da177e4 | 85 | { |
e5b1e206 | 86 | struct usb_serial_port *port; |
1da177e4 | 87 | unsigned int i, j; |
e5b1e206 | 88 | int minor; |
1da177e4 | 89 | |
92931d24 | 90 | dev_dbg(&serial->interface->dev, "%s %d\n", __func__, num_ports); |
1da177e4 | 91 | |
3ddad823 | 92 | mutex_lock(&table_lock); |
e5b1e206 GKH |
93 | for (i = 0; i < num_ports; ++i) { |
94 | port = serial->port[i]; | |
194e958c JH |
95 | minor = idr_alloc(&serial_minors, port, 0, |
96 | USB_SERIAL_TTY_MINORS, GFP_KERNEL); | |
e5b1e206 GKH |
97 | if (minor < 0) |
98 | goto error; | |
99 | port->minor = minor; | |
100 | port->port_number = i; | |
1da177e4 | 101 | } |
e5b1e206 | 102 | serial->minors_reserved = 1; |
3ddad823 | 103 | mutex_unlock(&table_lock); |
e5b1e206 GKH |
104 | return 0; |
105 | error: | |
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; | |
1da177e4 LT |
111 | } |
112 | ||
e5b1e206 | 113 | static void release_minors(struct usb_serial *serial) |
1da177e4 LT |
114 | { |
115 | int i; | |
116 | ||
8bc2c1b2 | 117 | mutex_lock(&table_lock); |
a8d6f0a9 | 118 | for (i = 0; i < serial->num_ports; ++i) |
e5b1e206 | 119 | idr_remove(&serial_minors, serial->port[i]->minor); |
8bc2c1b2 | 120 | mutex_unlock(&table_lock); |
e5b1e206 | 121 | serial->minors_reserved = 0; |
1da177e4 LT |
122 | } |
123 | ||
5de03c99 JH |
124 | int usb_serial_claim_interface(struct usb_serial *serial, struct usb_interface *intf) |
125 | { | |
126 | struct usb_driver *driver = serial->type->usb_driver; | |
127 | int ret; | |
128 | ||
129 | if (serial->sibling) | |
130 | return -EBUSY; | |
131 | ||
132 | ret = usb_driver_claim_interface(driver, intf, serial); | |
133 | if (ret) { | |
134 | dev_err(&serial->interface->dev, | |
135 | "failed to claim sibling interface: %d\n", ret); | |
136 | return ret; | |
137 | } | |
138 | ||
139 | serial->sibling = intf; | |
140 | ||
141 | return 0; | |
142 | } | |
143 | EXPORT_SYMBOL_GPL(usb_serial_claim_interface); | |
144 | ||
145 | static void release_sibling(struct usb_serial *serial, struct usb_interface *intf) | |
146 | { | |
147 | struct usb_driver *driver = serial->type->usb_driver; | |
148 | struct usb_interface *sibling; | |
149 | ||
150 | if (!serial->sibling) | |
151 | return; | |
152 | ||
153 | if (intf == serial->sibling) | |
154 | sibling = serial->interface; | |
155 | else | |
156 | sibling = serial->sibling; | |
157 | ||
158 | usb_set_intfdata(sibling, NULL); | |
159 | usb_driver_release_interface(driver, sibling); | |
160 | } | |
161 | ||
1da177e4 LT |
162 | static void destroy_serial(struct kref *kref) |
163 | { | |
164 | struct usb_serial *serial; | |
165 | struct usb_serial_port *port; | |
166 | int i; | |
167 | ||
168 | serial = to_usb_serial(kref); | |
169 | ||
521b85ae | 170 | /* return the minor range that this device had */ |
e5b1e206 GKH |
171 | if (serial->minors_reserved) |
172 | release_minors(serial); | |
521b85ae | 173 | |
79b80b8a | 174 | if (serial->attached && serial->type->release) |
a4720c65 | 175 | serial->type->release(serial); |
f9c99bb8 | 176 | |
41bd34dd AS |
177 | /* Now that nothing is using the ports, they can be freed */ |
178 | for (i = 0; i < serial->num_port_pointers; ++i) { | |
f9c99bb8 | 179 | port = serial->port[i]; |
41bd34dd AS |
180 | if (port) { |
181 | port->serial = NULL; | |
f9c99bb8 | 182 | put_device(&port->dev); |
1da177e4 LT |
183 | } |
184 | } | |
185 | ||
d7971051 | 186 | usb_put_intf(serial->interface); |
1da177e4 | 187 | usb_put_dev(serial->dev); |
a8d6f0a9 | 188 | kfree(serial); |
1da177e4 LT |
189 | } |
190 | ||
73e487fd GL |
191 | void usb_serial_put(struct usb_serial *serial) |
192 | { | |
193 | kref_put(&serial->kref, destroy_serial); | |
194 | } | |
195 | ||
1da177e4 LT |
196 | /***************************************************************************** |
197 | * Driver tty interface functions | |
198 | *****************************************************************************/ | |
f5b0953a AS |
199 | |
200 | /** | |
201 | * serial_install - install tty | |
202 | * @driver: the driver (USB in our case) | |
203 | * @tty: the tty being created | |
204 | * | |
579bebe5 | 205 | * Initialise the termios structure for this tty. We use the default |
f5b0953a | 206 | * USB serial settings but permit them to be overridden by |
579bebe5 | 207 | * serial->type->init_termios on first open. |
cc56cd01 AS |
208 | * |
209 | * This is the first place a new tty gets used. Hence this is where we | |
210 | * acquire references to the usb_serial structure and the driver module, | |
6400b974 JH |
211 | * where we store a pointer to the port. All these actions are reversed |
212 | * in serial_cleanup(). | |
f5b0953a AS |
213 | */ |
214 | static int serial_install(struct tty_driver *driver, struct tty_struct *tty) | |
215 | { | |
216 | int idx = tty->index; | |
217 | struct usb_serial *serial; | |
cc56cd01 | 218 | struct usb_serial_port *port; |
579bebe5 | 219 | bool init_termios; |
cc56cd01 AS |
220 | int retval = -ENODEV; |
221 | ||
e5b1e206 GKH |
222 | port = usb_serial_port_get_by_minor(idx); |
223 | if (!port) | |
cc56cd01 AS |
224 | return retval; |
225 | ||
e5b1e206 | 226 | serial = port->serial; |
cc56cd01 | 227 | if (!try_module_get(serial->type->driver.owner)) |
96a83c95 | 228 | goto err_put_serial; |
cc56cd01 | 229 | |
579bebe5 JH |
230 | init_termios = (driver->termios[idx] == NULL); |
231 | ||
79ef5189 | 232 | retval = tty_standard_install(driver, tty); |
76f82a7a | 233 | if (retval) |
6400b974 | 234 | goto err_put_module; |
76f82a7a | 235 | |
cc56cd01 AS |
236 | mutex_unlock(&serial->disc_mutex); |
237 | ||
579bebe5 JH |
238 | /* allow the driver to update the initial settings */ |
239 | if (init_termios && serial->type->init_termios) | |
7e29bb4b AS |
240 | serial->type->init_termios(tty); |
241 | ||
cc56cd01 AS |
242 | tty->driver_data = port; |
243 | ||
cc56cd01 AS |
244 | return retval; |
245 | ||
96a83c95 | 246 | err_put_module: |
cc56cd01 | 247 | module_put(serial->type->driver.owner); |
96a83c95 | 248 | err_put_serial: |
cc56cd01 AS |
249 | usb_serial_put(serial); |
250 | mutex_unlock(&serial->disc_mutex); | |
251 | return retval; | |
f5b0953a AS |
252 | } |
253 | ||
395e08da | 254 | static int serial_port_activate(struct tty_port *tport, struct tty_struct *tty) |
1da177e4 | 255 | { |
64bc3979 AC |
256 | struct usb_serial_port *port = |
257 | container_of(tport, struct usb_serial_port, port); | |
320348c8 AS |
258 | struct usb_serial *serial = port->serial; |
259 | int retval; | |
331879fd | 260 | |
64bc3979 | 261 | mutex_lock(&serial->disc_mutex); |
6400b974 | 262 | if (serial->disconnected) { |
64bc3979 | 263 | retval = -ENODEV; |
6400b974 JH |
264 | goto out_unlock; |
265 | } | |
266 | ||
267 | retval = usb_autopm_get_interface(serial->interface); | |
268 | if (retval) | |
269 | goto out_unlock; | |
270 | ||
271 | retval = port->serial->type->open(tty, port); | |
272 | if (retval) | |
273 | usb_autopm_put_interface(serial->interface); | |
274 | out_unlock: | |
64bc3979 | 275 | mutex_unlock(&serial->disc_mutex); |
3827d876 JH |
276 | |
277 | if (retval < 0) | |
278 | retval = usb_translate_errors(retval); | |
279 | ||
64bc3979 AC |
280 | return retval; |
281 | } | |
1da177e4 | 282 | |
64bc3979 AC |
283 | static int serial_open(struct tty_struct *tty, struct file *filp) |
284 | { | |
285 | struct usb_serial_port *port = tty->driver_data; | |
320348c8 | 286 | |
07125072 | 287 | dev_dbg(&port->dev, "%s\n", __func__); |
d12e211d | 288 | |
64bc3979 | 289 | return tty_port_open(&port->port, tty, filp); |
1da177e4 LT |
290 | } |
291 | ||
335f8514 | 292 | /** |
395e08da | 293 | * serial_port_shutdown - shut down hardware |
e1108a63 | 294 | * @tport: tty port to shut down |
335f8514 | 295 | * |
8a7298d3 PH |
296 | * Shut down a USB serial port. Serialized against activate by the |
297 | * tport mutex and kept to matching open/close pairs | |
688ee1d1 | 298 | * of calls by the tty-port initialized flag. |
8a7298d3 PH |
299 | * |
300 | * Not called if tty is console. | |
335f8514 | 301 | */ |
395e08da | 302 | static void serial_port_shutdown(struct tty_port *tport) |
1da177e4 | 303 | { |
e1108a63 AC |
304 | struct usb_serial_port *port = |
305 | container_of(tport, struct usb_serial_port, port); | |
335f8514 | 306 | struct usb_serial_driver *drv = port->serial->type; |
8a7298d3 | 307 | |
335f8514 AC |
308 | if (drv->close) |
309 | drv->close(port); | |
6400b974 JH |
310 | |
311 | usb_autopm_put_interface(port->serial->interface); | |
335f8514 AC |
312 | } |
313 | ||
f5b0953a AS |
314 | static void serial_hangup(struct tty_struct *tty) |
315 | { | |
316 | struct usb_serial_port *port = tty->driver_data; | |
92931d24 | 317 | |
07125072 | 318 | dev_dbg(&port->dev, "%s\n", __func__); |
d12e211d | 319 | |
f5b0953a | 320 | tty_port_hangup(&port->port); |
f5b0953a AS |
321 | } |
322 | ||
323 | static void serial_close(struct tty_struct *tty, struct file *filp) | |
324 | { | |
325 | struct usb_serial_port *port = tty->driver_data; | |
92931d24 | 326 | |
07125072 | 327 | dev_dbg(&port->dev, "%s\n", __func__); |
d12e211d | 328 | |
e1108a63 | 329 | tty_port_close(&port->port, tty, filp); |
f5b0953a AS |
330 | } |
331 | ||
335f8514 | 332 | /** |
f278a2f7 | 333 | * serial_cleanup - free resources post close/hangup |
615e58cc | 334 | * @tty: tty to clean up |
335f8514 | 335 | * |
f5b0953a AS |
336 | * Do the resource freeing and refcount dropping for the port. |
337 | * Avoid freeing the console. | |
4455e344 | 338 | * |
36b3c070 | 339 | * Called asynchronously after the last tty kref is dropped. |
335f8514 | 340 | */ |
f278a2f7 | 341 | static void serial_cleanup(struct tty_struct *tty) |
335f8514 | 342 | { |
4455e344 | 343 | struct usb_serial_port *port = tty->driver_data; |
335f8514 AC |
344 | struct usb_serial *serial; |
345 | struct module *owner; | |
346 | ||
07125072 | 347 | dev_dbg(&port->dev, "%s\n", __func__); |
d12e211d | 348 | |
f5b0953a AS |
349 | /* The console is magical. Do not hang up the console hardware |
350 | * or there will be tears. | |
351 | */ | |
bd5afa9e | 352 | if (port->port.console) |
335f8514 AC |
353 | return; |
354 | ||
cc56cd01 AS |
355 | tty->driver_data = NULL; |
356 | ||
335f8514 AC |
357 | serial = port->serial; |
358 | owner = serial->type->driver.owner; | |
41bd34dd | 359 | |
2d93148a | 360 | usb_serial_put(serial); |
335f8514 AC |
361 | module_put(owner); |
362 | } | |
363 | ||
95713967 | 364 | static ssize_t serial_write(struct tty_struct *tty, const u8 *buf, size_t count) |
1da177e4 | 365 | { |
81671ddb | 366 | struct usb_serial_port *port = tty->driver_data; |
3ff4fd94 | 367 | int retval = -ENODEV; |
1da177e4 | 368 | |
f34d7a5b | 369 | if (port->serial->dev->state == USB_STATE_NOTATTACHED) |
487f9c67 LFC |
370 | goto exit; |
371 | ||
95713967 | 372 | dev_dbg(&port->dev, "%s - %zu byte(s)\n", __func__, count); |
1da177e4 | 373 | |
95da310e | 374 | retval = port->serial->type->write(tty, port, buf, count); |
c6249ff7 JH |
375 | if (retval < 0) |
376 | retval = usb_translate_errors(retval); | |
1da177e4 LT |
377 | exit: |
378 | return retval; | |
379 | } | |
380 | ||
03b3b1a2 | 381 | static unsigned int serial_write_room(struct tty_struct *tty) |
1da177e4 | 382 | { |
81671ddb | 383 | struct usb_serial_port *port = tty->driver_data; |
92931d24 | 384 | |
07125072 | 385 | dev_dbg(&port->dev, "%s\n", __func__); |
9993b42b | 386 | |
95da310e | 387 | return port->serial->type->write_room(tty); |
1da177e4 LT |
388 | } |
389 | ||
fff4ef17 | 390 | static unsigned int serial_chars_in_buffer(struct tty_struct *tty) |
1da177e4 | 391 | { |
81671ddb | 392 | struct usb_serial_port *port = tty->driver_data; |
810360a0 | 393 | struct usb_serial *serial = port->serial; |
92931d24 | 394 | |
07125072 | 395 | dev_dbg(&port->dev, "%s\n", __func__); |
1da177e4 | 396 | |
810360a0 | 397 | if (serial->disconnected) |
4746b6c6 | 398 | return 0; |
810360a0 | 399 | |
4746b6c6 | 400 | return serial->type->chars_in_buffer(tty); |
1da177e4 LT |
401 | } |
402 | ||
0693196f JH |
403 | static void serial_wait_until_sent(struct tty_struct *tty, int timeout) |
404 | { | |
405 | struct usb_serial_port *port = tty->driver_data; | |
406 | struct usb_serial *serial = port->serial; | |
407 | ||
07125072 | 408 | dev_dbg(&port->dev, "%s\n", __func__); |
0693196f JH |
409 | |
410 | if (!port->serial->type->wait_until_sent) | |
411 | return; | |
412 | ||
413 | mutex_lock(&serial->disc_mutex); | |
414 | if (!serial->disconnected) | |
415 | port->serial->type->wait_until_sent(tty, timeout); | |
416 | mutex_unlock(&serial->disc_mutex); | |
417 | } | |
418 | ||
a8d6f0a9 | 419 | static void serial_throttle(struct tty_struct *tty) |
1da177e4 | 420 | { |
81671ddb | 421 | struct usb_serial_port *port = tty->driver_data; |
92931d24 | 422 | |
07125072 | 423 | dev_dbg(&port->dev, "%s\n", __func__); |
1da177e4 | 424 | |
1da177e4 | 425 | if (port->serial->type->throttle) |
95da310e | 426 | port->serial->type->throttle(tty); |
1da177e4 LT |
427 | } |
428 | ||
a8d6f0a9 | 429 | static void serial_unthrottle(struct tty_struct *tty) |
1da177e4 | 430 | { |
81671ddb | 431 | struct usb_serial_port *port = tty->driver_data; |
92931d24 | 432 | |
07125072 | 433 | dev_dbg(&port->dev, "%s\n", __func__); |
1da177e4 | 434 | |
1da177e4 | 435 | if (port->serial->type->unthrottle) |
95da310e | 436 | port->serial->type->unthrottle(tty); |
1da177e4 LT |
437 | } |
438 | ||
81732b26 AV |
439 | static int serial_get_serial(struct tty_struct *tty, struct serial_struct *ss) |
440 | { | |
441 | struct usb_serial_port *port = tty->driver_data; | |
01fd45f6 JH |
442 | struct tty_port *tport = &port->port; |
443 | unsigned int close_delay, closing_wait; | |
444 | ||
445 | mutex_lock(&tport->mutex); | |
446 | ||
447 | close_delay = jiffies_to_msecs(tport->close_delay) / 10; | |
448 | closing_wait = tport->closing_wait; | |
449 | if (closing_wait != ASYNC_CLOSING_WAIT_NONE) | |
450 | closing_wait = jiffies_to_msecs(closing_wait) / 10; | |
451 | ||
452 | ss->line = port->minor; | |
453 | ss->close_delay = close_delay; | |
454 | ss->closing_wait = closing_wait; | |
81732b26 AV |
455 | |
456 | if (port->serial->type->get_serial) | |
01fd45f6 JH |
457 | port->serial->type->get_serial(tty, ss); |
458 | ||
459 | mutex_unlock(&tport->mutex); | |
460 | ||
461 | return 0; | |
81732b26 AV |
462 | } |
463 | ||
464 | static int serial_set_serial(struct tty_struct *tty, struct serial_struct *ss) | |
465 | { | |
466 | struct usb_serial_port *port = tty->driver_data; | |
01fd45f6 JH |
467 | struct tty_port *tport = &port->port; |
468 | unsigned int close_delay, closing_wait; | |
469 | int ret = 0; | |
470 | ||
471 | close_delay = msecs_to_jiffies(ss->close_delay * 10); | |
472 | closing_wait = ss->closing_wait; | |
473 | if (closing_wait != ASYNC_CLOSING_WAIT_NONE) | |
474 | closing_wait = msecs_to_jiffies(closing_wait * 10); | |
475 | ||
476 | mutex_lock(&tport->mutex); | |
477 | ||
478 | if (!capable(CAP_SYS_ADMIN)) { | |
479 | if (close_delay != tport->close_delay || | |
480 | closing_wait != tport->closing_wait) { | |
481 | ret = -EPERM; | |
482 | goto out_unlock; | |
483 | } | |
484 | } | |
485 | ||
486 | if (port->serial->type->set_serial) { | |
487 | ret = port->serial->type->set_serial(tty, ss); | |
488 | if (ret) | |
489 | goto out_unlock; | |
490 | } | |
491 | ||
492 | tport->close_delay = close_delay; | |
493 | tport->closing_wait = closing_wait; | |
494 | out_unlock: | |
495 | mutex_unlock(&tport->mutex); | |
81732b26 | 496 | |
01fd45f6 | 497 | return ret; |
81732b26 AV |
498 | } |
499 | ||
6caa76b7 | 500 | static int serial_ioctl(struct tty_struct *tty, |
a8d6f0a9 | 501 | unsigned int cmd, unsigned long arg) |
1da177e4 | 502 | { |
81671ddb | 503 | struct usb_serial_port *port = tty->driver_data; |
f4488035 | 504 | int retval = -ENOIOCTLCMD; |
1da177e4 | 505 | |
07125072 | 506 | dev_dbg(&port->dev, "%s - cmd 0x%04x\n", __func__, cmd); |
1da177e4 | 507 | |
143d9d96 JH |
508 | switch (cmd) { |
509 | case TIOCMIWAIT: | |
510 | if (port->serial->type->tiocmiwait) | |
511 | retval = port->serial->type->tiocmiwait(tty, arg); | |
512 | break; | |
513 | default: | |
514 | if (port->serial->type->ioctl) | |
515 | retval = port->serial->type->ioctl(tty, cmd, arg); | |
143d9d96 | 516 | } |
1da177e4 | 517 | |
1da177e4 LT |
518 | return retval; |
519 | } | |
520 | ||
a8c11c15 IJ |
521 | static void serial_set_termios(struct tty_struct *tty, |
522 | const struct ktermios *old) | |
1da177e4 | 523 | { |
81671ddb | 524 | struct usb_serial_port *port = tty->driver_data; |
92931d24 | 525 | |
07125072 | 526 | dev_dbg(&port->dev, "%s\n", __func__); |
1da177e4 | 527 | |
1da177e4 | 528 | if (port->serial->type->set_termios) |
95da310e | 529 | port->serial->type->set_termios(tty, port, old); |
33785091 | 530 | else |
adc8d746 | 531 | tty_termios_copy_hw(&tty->termios, old); |
1da177e4 LT |
532 | } |
533 | ||
9e98966c | 534 | static int serial_break(struct tty_struct *tty, int break_state) |
1da177e4 | 535 | { |
81671ddb | 536 | struct usb_serial_port *port = tty->driver_data; |
1da177e4 | 537 | |
07125072 | 538 | dev_dbg(&port->dev, "%s\n", __func__); |
1da177e4 | 539 | |
6b447f04 | 540 | if (port->serial->type->break_ctl) |
6ff58ae1 | 541 | return port->serial->type->break_ctl(tty, break_state); |
9993b42b | 542 | |
c9d93405 | 543 | return -ENOTTY; |
1da177e4 LT |
544 | } |
545 | ||
6fd69d3c | 546 | static int serial_proc_show(struct seq_file *m, void *v) |
1da177e4 LT |
547 | { |
548 | struct usb_serial *serial; | |
e5b1e206 | 549 | struct usb_serial_port *port; |
1da177e4 | 550 | int i; |
1da177e4 LT |
551 | char tmp[40]; |
552 | ||
6fd69d3c | 553 | seq_puts(m, "usbserinfo:1.0 driver:2.0\n"); |
455b4f7e | 554 | for (i = 0; i < USB_SERIAL_TTY_MINORS; ++i) { |
e5b1e206 GKH |
555 | port = usb_serial_port_get_by_minor(i); |
556 | if (port == NULL) | |
1da177e4 | 557 | continue; |
e5b1e206 | 558 | serial = port->serial; |
1da177e4 | 559 | |
6fd69d3c | 560 | seq_printf(m, "%d:", i); |
18fcac35 | 561 | if (serial->type->driver.owner) |
6fd69d3c | 562 | seq_printf(m, " module:%s", |
a8d6f0a9 | 563 | module_name(serial->type->driver.owner)); |
6fd69d3c | 564 | seq_printf(m, " name:\"%s\"", |
a8d6f0a9 | 565 | serial->type->description); |
6fd69d3c | 566 | seq_printf(m, " vendor:%04x product:%04x", |
a8d6f0a9 AC |
567 | le16_to_cpu(serial->dev->descriptor.idVendor), |
568 | le16_to_cpu(serial->dev->descriptor.idProduct)); | |
6fd69d3c | 569 | seq_printf(m, " num_ports:%d", serial->num_ports); |
e5b1e206 | 570 | seq_printf(m, " port:%d", port->port_number); |
1da177e4 | 571 | usb_make_path(serial->dev, tmp, sizeof(tmp)); |
6fd69d3c | 572 | seq_printf(m, " path:%s", tmp); |
a8d6f0a9 | 573 | |
6fd69d3c | 574 | seq_putc(m, '\n'); |
73e487fd | 575 | usb_serial_put(serial); |
8bc2c1b2 | 576 | mutex_unlock(&serial->disc_mutex); |
1da177e4 | 577 | } |
6fd69d3c | 578 | return 0; |
1da177e4 LT |
579 | } |
580 | ||
60b33c13 | 581 | static int serial_tiocmget(struct tty_struct *tty) |
1da177e4 | 582 | { |
81671ddb | 583 | struct usb_serial_port *port = tty->driver_data; |
1da177e4 | 584 | |
07125072 | 585 | dev_dbg(&port->dev, "%s\n", __func__); |
1da177e4 | 586 | |
1da177e4 | 587 | if (port->serial->type->tiocmget) |
60b33c13 | 588 | return port->serial->type->tiocmget(tty); |
5f92aee9 | 589 | return -ENOTTY; |
1da177e4 LT |
590 | } |
591 | ||
20b9d177 | 592 | static int serial_tiocmset(struct tty_struct *tty, |
1da177e4 LT |
593 | unsigned int set, unsigned int clear) |
594 | { | |
81671ddb | 595 | struct usb_serial_port *port = tty->driver_data; |
1da177e4 | 596 | |
07125072 | 597 | dev_dbg(&port->dev, "%s\n", __func__); |
1da177e4 | 598 | |
1da177e4 | 599 | if (port->serial->type->tiocmset) |
20b9d177 | 600 | return port->serial->type->tiocmset(tty, set, clear); |
5f92aee9 | 601 | return -ENOTTY; |
1da177e4 LT |
602 | } |
603 | ||
d281da7f AC |
604 | static int serial_get_icount(struct tty_struct *tty, |
605 | struct serial_icounter_struct *icount) | |
606 | { | |
607 | struct usb_serial_port *port = tty->driver_data; | |
608 | ||
07125072 | 609 | dev_dbg(&port->dev, "%s\n", __func__); |
d281da7f AC |
610 | |
611 | if (port->serial->type->get_icount) | |
612 | return port->serial->type->get_icount(tty, icount); | |
5f92aee9 | 613 | return -ENOTTY; |
d281da7f AC |
614 | } |
615 | ||
cf2c7481 PZ |
616 | /* |
617 | * We would be calling tty_wakeup here, but unfortunately some line | |
618 | * disciplines have an annoying habit of calling tty->write from | |
619 | * the write wakeup callback (e.g. n_hdlc.c). | |
620 | */ | |
621 | void usb_serial_port_softint(struct usb_serial_port *port) | |
622 | { | |
623 | schedule_work(&port->work); | |
624 | } | |
a8d6f0a9 | 625 | EXPORT_SYMBOL_GPL(usb_serial_port_softint); |
cf2c7481 | 626 | |
c4028958 | 627 | static void usb_serial_port_work(struct work_struct *work) |
1da177e4 | 628 | { |
c4028958 DH |
629 | struct usb_serial_port *port = |
630 | container_of(work, struct usb_serial_port, work); | |
1da177e4 | 631 | |
6aad04f2 | 632 | tty_port_tty_wakeup(&port->port); |
1da177e4 LT |
633 | } |
634 | ||
6a5c821c | 635 | static void usb_serial_port_poison_urbs(struct usb_serial_port *port) |
34f8e761 | 636 | { |
27c7acf2 JH |
637 | int i; |
638 | ||
d83b4053 | 639 | for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) |
6a5c821c | 640 | usb_poison_urb(port->read_urbs[i]); |
27c7acf2 | 641 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) |
6a5c821c JH |
642 | usb_poison_urb(port->write_urbs[i]); |
643 | ||
644 | usb_poison_urb(port->interrupt_in_urb); | |
645 | usb_poison_urb(port->interrupt_out_urb); | |
646 | } | |
647 | ||
648 | static void usb_serial_port_unpoison_urbs(struct usb_serial_port *port) | |
649 | { | |
650 | int i; | |
651 | ||
652 | for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) | |
653 | usb_unpoison_urb(port->read_urbs[i]); | |
654 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) | |
655 | usb_unpoison_urb(port->write_urbs[i]); | |
656 | ||
657 | usb_unpoison_urb(port->interrupt_in_urb); | |
658 | usb_unpoison_urb(port->interrupt_out_urb); | |
34ef50e5 ON |
659 | } |
660 | ||
69a3d212 | 661 | static void usb_serial_port_release(struct device *dev) |
34ef50e5 | 662 | { |
41bd34dd | 663 | struct usb_serial_port *port = to_usb_serial_port(dev); |
27c7acf2 | 664 | int i; |
41bd34dd | 665 | |
92931d24 | 666 | dev_dbg(dev, "%s\n", __func__); |
41bd34dd | 667 | |
34ef50e5 | 668 | usb_free_urb(port->interrupt_in_urb); |
1da177e4 | 669 | usb_free_urb(port->interrupt_out_urb); |
d83b4053 JH |
670 | for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) { |
671 | usb_free_urb(port->read_urbs[i]); | |
672 | kfree(port->bulk_in_buffers[i]); | |
673 | } | |
27c7acf2 JH |
674 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) { |
675 | usb_free_urb(port->write_urbs[i]); | |
676 | kfree(port->bulk_out_buffers[i]); | |
677 | } | |
119eecc8 | 678 | kfifo_free(&port->write_fifo); |
1da177e4 LT |
679 | kfree(port->interrupt_in_buffer); |
680 | kfree(port->interrupt_out_buffer); | |
191c5f10 | 681 | tty_port_destroy(&port->port); |
1da177e4 LT |
682 | kfree(port); |
683 | } | |
684 | ||
a8d6f0a9 AC |
685 | static struct usb_serial *create_serial(struct usb_device *dev, |
686 | struct usb_interface *interface, | |
687 | struct usb_serial_driver *driver) | |
1da177e4 LT |
688 | { |
689 | struct usb_serial *serial; | |
690 | ||
80b6ca48 | 691 | serial = kzalloc(sizeof(*serial), GFP_KERNEL); |
6b03f7f7 | 692 | if (!serial) |
1da177e4 | 693 | return NULL; |
1da177e4 | 694 | serial->dev = usb_get_dev(dev); |
ea65370d | 695 | serial->type = driver; |
d7971051 | 696 | serial->interface = usb_get_intf(interface); |
1da177e4 | 697 | kref_init(&serial->kref); |
a1cd7e99 | 698 | mutex_init(&serial->disc_mutex); |
e5b1e206 | 699 | serial->minors_reserved = 0; |
1da177e4 LT |
700 | |
701 | return serial; | |
702 | } | |
703 | ||
93bacefc | 704 | static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf, |
a8d6f0a9 | 705 | struct usb_serial_driver *drv) |
93bacefc GKH |
706 | { |
707 | struct usb_dynid *dynid; | |
708 | ||
0b3144da | 709 | guard(mutex)(&usb_dynids_lock); |
93bacefc GKH |
710 | list_for_each_entry(dynid, &drv->dynids.list, node) { |
711 | if (usb_match_one_id(intf, &dynid->id)) { | |
93bacefc GKH |
712 | return &dynid->id; |
713 | } | |
714 | } | |
93bacefc GKH |
715 | return NULL; |
716 | } | |
717 | ||
718 | static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv, | |
719 | struct usb_interface *intf) | |
720 | { | |
721 | const struct usb_device_id *id; | |
722 | ||
723 | id = usb_match_id(intf, drv->id_table); | |
724 | if (id) { | |
92931d24 | 725 | dev_dbg(&intf->dev, "static descriptor matches\n"); |
93bacefc GKH |
726 | goto exit; |
727 | } | |
728 | id = match_dynamic_id(intf, drv); | |
729 | if (id) | |
92931d24 | 730 | dev_dbg(&intf->dev, "dynamic descriptor matches\n"); |
93bacefc GKH |
731 | exit: |
732 | return id; | |
733 | } | |
734 | ||
0daeed38 | 735 | /* Caller must hold table_lock */ |
a8d6f0a9 AC |
736 | static struct usb_serial_driver *search_serial_device( |
737 | struct usb_interface *iface) | |
1da177e4 | 738 | { |
954c3f8a | 739 | const struct usb_device_id *id = NULL; |
063a2da8 | 740 | struct usb_serial_driver *drv; |
954c3f8a | 741 | struct usb_driver *driver = to_usb_driver(iface->dev.driver); |
1da177e4 | 742 | |
93b1fae4 | 743 | /* Check if the usb id matches a known device */ |
063a2da8 | 744 | list_for_each_entry(drv, &usb_serial_driver_list, driver_list) { |
954c3f8a BM |
745 | if (drv->usb_driver == driver) |
746 | id = get_iface_id(drv, iface); | |
93bacefc | 747 | if (id) |
063a2da8 | 748 | return drv; |
1da177e4 LT |
749 | } |
750 | ||
751 | return NULL; | |
752 | } | |
753 | ||
b300fb26 | 754 | static bool serial_port_carrier_raised(struct tty_port *port) |
335f8514 AC |
755 | { |
756 | struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); | |
757 | struct usb_serial_driver *drv = p->serial->type; | |
3e1f4901 | 758 | |
335f8514 AC |
759 | if (drv->carrier_raised) |
760 | return drv->carrier_raised(p); | |
761 | /* No carrier control - don't block */ | |
b300fb26 | 762 | return true; |
335f8514 AC |
763 | } |
764 | ||
5d420399 | 765 | static void serial_port_dtr_rts(struct tty_port *port, bool on) |
335f8514 AC |
766 | { |
767 | struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); | |
f5f45304 | 768 | struct usb_serial_driver *drv = p->serial->type; |
3e1f4901 | 769 | |
f5f45304 | 770 | if (drv->dtr_rts) |
335f8514 AC |
771 | drv->dtr_rts(p, on); |
772 | } | |
773 | ||
2deb96b5 JH |
774 | static ssize_t port_number_show(struct device *dev, |
775 | struct device_attribute *attr, char *buf) | |
776 | { | |
777 | struct usb_serial_port *port = to_usb_serial_port(dev); | |
778 | ||
779 | return sprintf(buf, "%u\n", port->port_number); | |
780 | } | |
781 | static DEVICE_ATTR_RO(port_number); | |
782 | ||
783 | static struct attribute *usb_serial_port_attrs[] = { | |
784 | &dev_attr_port_number.attr, | |
785 | NULL | |
786 | }; | |
787 | ATTRIBUTE_GROUPS(usb_serial_port); | |
788 | ||
335f8514 | 789 | static const struct tty_port_operations serial_port_ops = { |
395e08da JH |
790 | .carrier_raised = serial_port_carrier_raised, |
791 | .dtr_rts = serial_port_dtr_rts, | |
792 | .activate = serial_port_activate, | |
793 | .shutdown = serial_port_shutdown, | |
335f8514 AC |
794 | }; |
795 | ||
b3431093 JH |
796 | static void store_endpoint(struct usb_serial *serial, |
797 | struct usb_serial_endpoints *epds, | |
798 | struct usb_endpoint_descriptor *epd) | |
799 | { | |
800 | struct device *dev = &serial->interface->dev; | |
801 | u8 addr = epd->bEndpointAddress; | |
802 | ||
803 | if (usb_endpoint_is_bulk_in(epd)) { | |
804 | if (epds->num_bulk_in == ARRAY_SIZE(epds->bulk_in)) | |
805 | return; | |
806 | dev_dbg(dev, "found bulk in endpoint %02x\n", addr); | |
807 | epds->bulk_in[epds->num_bulk_in++] = epd; | |
808 | } else if (usb_endpoint_is_bulk_out(epd)) { | |
809 | if (epds->num_bulk_out == ARRAY_SIZE(epds->bulk_out)) | |
810 | return; | |
811 | dev_dbg(dev, "found bulk out endpoint %02x\n", addr); | |
812 | epds->bulk_out[epds->num_bulk_out++] = epd; | |
813 | } else if (usb_endpoint_is_int_in(epd)) { | |
814 | if (epds->num_interrupt_in == ARRAY_SIZE(epds->interrupt_in)) | |
815 | return; | |
816 | dev_dbg(dev, "found interrupt in endpoint %02x\n", addr); | |
817 | epds->interrupt_in[epds->num_interrupt_in++] = epd; | |
818 | } else if (usb_endpoint_is_int_out(epd)) { | |
819 | if (epds->num_interrupt_out == ARRAY_SIZE(epds->interrupt_out)) | |
820 | return; | |
821 | dev_dbg(dev, "found interrupt out endpoint %02x\n", addr); | |
822 | epds->interrupt_out[epds->num_interrupt_out++] = epd; | |
823 | } | |
824 | } | |
825 | ||
1546e6ae | 826 | static void find_endpoints(struct usb_serial *serial, |
5de03c99 JH |
827 | struct usb_serial_endpoints *epds, |
828 | struct usb_interface *intf) | |
1546e6ae | 829 | { |
1546e6ae JH |
830 | struct usb_host_interface *iface_desc; |
831 | struct usb_endpoint_descriptor *epd; | |
832 | unsigned int i; | |
833 | ||
5de03c99 | 834 | iface_desc = intf->cur_altsetting; |
1546e6ae JH |
835 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { |
836 | epd = &iface_desc->endpoint[i].desc; | |
b3431093 | 837 | store_endpoint(serial, epds, epd); |
1546e6ae JH |
838 | } |
839 | } | |
840 | ||
45e5d4d4 JH |
841 | static int setup_port_bulk_in(struct usb_serial_port *port, |
842 | struct usb_endpoint_descriptor *epd) | |
843 | { | |
844 | struct usb_serial_driver *type = port->serial->type; | |
845 | struct usb_device *udev = port->serial->dev; | |
846 | int buffer_size; | |
847 | int i; | |
848 | ||
849 | buffer_size = max_t(int, type->bulk_in_size, usb_endpoint_maxp(epd)); | |
850 | port->bulk_in_size = buffer_size; | |
851 | port->bulk_in_endpointAddress = epd->bEndpointAddress; | |
852 | ||
853 | for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) { | |
854 | set_bit(i, &port->read_urbs_free); | |
855 | port->read_urbs[i] = usb_alloc_urb(0, GFP_KERNEL); | |
856 | if (!port->read_urbs[i]) | |
857 | return -ENOMEM; | |
858 | port->bulk_in_buffers[i] = kmalloc(buffer_size, GFP_KERNEL); | |
859 | if (!port->bulk_in_buffers[i]) | |
860 | return -ENOMEM; | |
861 | usb_fill_bulk_urb(port->read_urbs[i], udev, | |
862 | usb_rcvbulkpipe(udev, epd->bEndpointAddress), | |
863 | port->bulk_in_buffers[i], buffer_size, | |
864 | type->read_bulk_callback, port); | |
865 | } | |
866 | ||
867 | port->read_urb = port->read_urbs[0]; | |
868 | port->bulk_in_buffer = port->bulk_in_buffers[0]; | |
869 | ||
870 | return 0; | |
871 | } | |
872 | ||
873 | static int setup_port_bulk_out(struct usb_serial_port *port, | |
874 | struct usb_endpoint_descriptor *epd) | |
875 | { | |
876 | struct usb_serial_driver *type = port->serial->type; | |
877 | struct usb_device *udev = port->serial->dev; | |
878 | int buffer_size; | |
879 | int i; | |
880 | ||
881 | if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL)) | |
882 | return -ENOMEM; | |
883 | if (type->bulk_out_size) | |
884 | buffer_size = type->bulk_out_size; | |
885 | else | |
886 | buffer_size = usb_endpoint_maxp(epd); | |
887 | port->bulk_out_size = buffer_size; | |
888 | port->bulk_out_endpointAddress = epd->bEndpointAddress; | |
889 | ||
890 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) { | |
891 | set_bit(i, &port->write_urbs_free); | |
892 | port->write_urbs[i] = usb_alloc_urb(0, GFP_KERNEL); | |
893 | if (!port->write_urbs[i]) | |
894 | return -ENOMEM; | |
895 | port->bulk_out_buffers[i] = kmalloc(buffer_size, GFP_KERNEL); | |
896 | if (!port->bulk_out_buffers[i]) | |
897 | return -ENOMEM; | |
898 | usb_fill_bulk_urb(port->write_urbs[i], udev, | |
899 | usb_sndbulkpipe(udev, epd->bEndpointAddress), | |
900 | port->bulk_out_buffers[i], buffer_size, | |
901 | type->write_bulk_callback, port); | |
902 | } | |
903 | ||
904 | port->write_urb = port->write_urbs[0]; | |
905 | port->bulk_out_buffer = port->bulk_out_buffers[0]; | |
906 | ||
907 | return 0; | |
908 | } | |
909 | ||
910 | static int setup_port_interrupt_in(struct usb_serial_port *port, | |
911 | struct usb_endpoint_descriptor *epd) | |
912 | { | |
913 | struct usb_serial_driver *type = port->serial->type; | |
914 | struct usb_device *udev = port->serial->dev; | |
915 | int buffer_size; | |
916 | ||
917 | port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); | |
918 | if (!port->interrupt_in_urb) | |
919 | return -ENOMEM; | |
920 | buffer_size = usb_endpoint_maxp(epd); | |
921 | port->interrupt_in_endpointAddress = epd->bEndpointAddress; | |
922 | port->interrupt_in_buffer = kmalloc(buffer_size, GFP_KERNEL); | |
923 | if (!port->interrupt_in_buffer) | |
924 | return -ENOMEM; | |
925 | usb_fill_int_urb(port->interrupt_in_urb, udev, | |
926 | usb_rcvintpipe(udev, epd->bEndpointAddress), | |
927 | port->interrupt_in_buffer, buffer_size, | |
928 | type->read_int_callback, port, | |
929 | epd->bInterval); | |
930 | ||
931 | return 0; | |
932 | } | |
933 | ||
934 | static int setup_port_interrupt_out(struct usb_serial_port *port, | |
935 | struct usb_endpoint_descriptor *epd) | |
936 | { | |
937 | struct usb_serial_driver *type = port->serial->type; | |
938 | struct usb_device *udev = port->serial->dev; | |
939 | int buffer_size; | |
940 | ||
941 | port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); | |
942 | if (!port->interrupt_out_urb) | |
943 | return -ENOMEM; | |
944 | buffer_size = usb_endpoint_maxp(epd); | |
945 | port->interrupt_out_size = buffer_size; | |
946 | port->interrupt_out_endpointAddress = epd->bEndpointAddress; | |
947 | port->interrupt_out_buffer = kmalloc(buffer_size, GFP_KERNEL); | |
948 | if (!port->interrupt_out_buffer) | |
949 | return -ENOMEM; | |
950 | usb_fill_int_urb(port->interrupt_out_urb, udev, | |
951 | usb_sndintpipe(udev, epd->bEndpointAddress), | |
952 | port->interrupt_out_buffer, buffer_size, | |
953 | type->write_int_callback, port, | |
954 | epd->bInterval); | |
955 | ||
956 | return 0; | |
957 | } | |
958 | ||
2edd284b | 959 | static int usb_serial_probe(struct usb_interface *interface, |
1da177e4 LT |
960 | const struct usb_device_id *id) |
961 | { | |
92931d24 | 962 | struct device *ddev = &interface->dev; |
a8d6f0a9 | 963 | struct usb_device *dev = interface_to_usbdev(interface); |
1da177e4 LT |
964 | struct usb_serial *serial = NULL; |
965 | struct usb_serial_port *port; | |
1546e6ae | 966 | struct usb_serial_endpoints *epds; |
ea65370d | 967 | struct usb_serial_driver *type = NULL; |
1da177e4 | 968 | int retval; |
1da177e4 | 969 | int i; |
1da177e4 | 970 | int num_ports = 0; |
ef88f33f | 971 | unsigned char max_endpoints; |
1da177e4 | 972 | |
0daeed38 | 973 | mutex_lock(&table_lock); |
1da177e4 LT |
974 | type = search_serial_device(interface); |
975 | if (!type) { | |
0daeed38 | 976 | mutex_unlock(&table_lock); |
92931d24 | 977 | dev_dbg(ddev, "none matched\n"); |
1da177e4 LT |
978 | return -ENODEV; |
979 | } | |
980 | ||
0daeed38 AK |
981 | if (!try_module_get(type->driver.owner)) { |
982 | mutex_unlock(&table_lock); | |
92931d24 | 983 | dev_err(ddev, "module get failed, exiting\n"); |
0daeed38 AK |
984 | return -EIO; |
985 | } | |
986 | mutex_unlock(&table_lock); | |
987 | ||
a8d6f0a9 | 988 | serial = create_serial(dev, interface, type); |
1da177e4 | 989 | if (!serial) { |
c2fef456 JH |
990 | retval = -ENOMEM; |
991 | goto err_put_module; | |
1da177e4 LT |
992 | } |
993 | ||
994 | /* if this device type has a probe function, call it */ | |
995 | if (type->probe) { | |
996 | const struct usb_device_id *id; | |
997 | ||
93bacefc | 998 | id = get_iface_id(type, interface); |
1da177e4 | 999 | retval = type->probe(serial, id); |
1da177e4 LT |
1000 | |
1001 | if (retval) { | |
92931d24 | 1002 | dev_dbg(ddev, "sub driver rejected device\n"); |
5de03c99 | 1003 | goto err_release_sibling; |
1da177e4 LT |
1004 | } |
1005 | } | |
1006 | ||
1007 | /* descriptor matches, let's find the endpoints needed */ | |
1546e6ae JH |
1008 | epds = kzalloc(sizeof(*epds), GFP_KERNEL); |
1009 | if (!epds) { | |
1010 | retval = -ENOMEM; | |
5de03c99 | 1011 | goto err_release_sibling; |
1da177e4 LT |
1012 | } |
1013 | ||
5de03c99 JH |
1014 | find_endpoints(serial, epds, interface); |
1015 | if (serial->sibling) | |
1016 | find_endpoints(serial, epds, serial->sibling); | |
1546e6ae | 1017 | |
92e6b2c6 JH |
1018 | if (epds->num_bulk_in < type->num_bulk_in || |
1019 | epds->num_bulk_out < type->num_bulk_out || | |
1020 | epds->num_interrupt_in < type->num_interrupt_in || | |
1021 | epds->num_interrupt_out < type->num_interrupt_out) { | |
1022 | dev_err(ddev, "required endpoints missing\n"); | |
1023 | retval = -ENODEV; | |
1024 | goto err_free_epds; | |
1025 | } | |
a794499b JH |
1026 | |
1027 | if (type->calc_num_ports) { | |
1028 | retval = type->calc_num_ports(serial, epds); | |
1029 | if (retval < 0) | |
92e6b2c6 | 1030 | goto err_free_epds; |
a794499b | 1031 | num_ports = retval; |
1da177e4 LT |
1032 | } |
1033 | ||
a794499b JH |
1034 | if (!num_ports) |
1035 | num_ports = type->num_ports; | |
1036 | ||
5654699f JH |
1037 | if (num_ports > MAX_NUM_PORTS) { |
1038 | dev_warn(ddev, "too many ports requested: %d\n", num_ports); | |
1039 | num_ports = MAX_NUM_PORTS; | |
1040 | } | |
1041 | ||
ef88f33f | 1042 | serial->num_ports = (unsigned char)num_ports; |
1546e6ae JH |
1043 | serial->num_bulk_in = epds->num_bulk_in; |
1044 | serial->num_bulk_out = epds->num_bulk_out; | |
1045 | serial->num_interrupt_in = epds->num_interrupt_in; | |
1046 | serial->num_interrupt_out = epds->num_interrupt_out; | |
1da177e4 | 1047 | |
063a2da8 | 1048 | /* found all that we need */ |
92931d24 | 1049 | dev_info(ddev, "%s converter detected\n", type->description); |
063a2da8 | 1050 | |
1da177e4 | 1051 | /* create our ports, we need as many as the max endpoints */ |
a8d6f0a9 AC |
1052 | /* we don't use num_ports here because some devices have more |
1053 | endpoint pairs than ports */ | |
1546e6ae JH |
1054 | max_endpoints = max(epds->num_bulk_in, epds->num_bulk_out); |
1055 | max_endpoints = max(max_endpoints, epds->num_interrupt_in); | |
1056 | max_endpoints = max(max_endpoints, epds->num_interrupt_out); | |
ef88f33f | 1057 | max_endpoints = max(max_endpoints, serial->num_ports); |
1da177e4 | 1058 | serial->num_port_pointers = max_endpoints; |
4b10f0f3 | 1059 | |
d9a38a87 | 1060 | dev_dbg(ddev, "setting up %d port structure(s)\n", max_endpoints); |
1da177e4 | 1061 | for (i = 0; i < max_endpoints; ++i) { |
80b6ca48 | 1062 | port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); |
c22ac6d2 JH |
1063 | if (!port) { |
1064 | retval = -ENOMEM; | |
1065 | goto err_free_epds; | |
1066 | } | |
4a90f09b | 1067 | tty_port_init(&port->port); |
335f8514 | 1068 | port->port.ops = &serial_port_ops; |
1da177e4 | 1069 | port->serial = serial; |
507ca9bc | 1070 | spin_lock_init(&port->lock); |
e1108a63 AC |
1071 | /* Keep this for private driver use for the moment but |
1072 | should probably go away */ | |
c4028958 | 1073 | INIT_WORK(&port->work, usb_serial_port_work); |
1da177e4 | 1074 | serial->port[i] = port; |
41bd34dd AS |
1075 | port->dev.parent = &interface->dev; |
1076 | port->dev.driver = NULL; | |
1077 | port->dev.bus = &usb_serial_bus_type; | |
69a3d212 | 1078 | port->dev.release = &usb_serial_port_release; |
2deb96b5 | 1079 | port->dev.groups = usb_serial_port_groups; |
41bd34dd | 1080 | device_initialize(&port->dev); |
1da177e4 LT |
1081 | } |
1082 | ||
1083 | /* set up the endpoint information */ | |
1546e6ae | 1084 | for (i = 0; i < epds->num_bulk_in; ++i) { |
45e5d4d4 JH |
1085 | retval = setup_port_bulk_in(serial->port[i], epds->bulk_in[i]); |
1086 | if (retval) | |
c22ac6d2 | 1087 | goto err_free_epds; |
1da177e4 LT |
1088 | } |
1089 | ||
1546e6ae | 1090 | for (i = 0; i < epds->num_bulk_out; ++i) { |
45e5d4d4 JH |
1091 | retval = setup_port_bulk_out(serial->port[i], |
1092 | epds->bulk_out[i]); | |
1093 | if (retval) | |
c22ac6d2 | 1094 | goto err_free_epds; |
1da177e4 LT |
1095 | } |
1096 | ||
1097 | if (serial->type->read_int_callback) { | |
1546e6ae | 1098 | for (i = 0; i < epds->num_interrupt_in; ++i) { |
45e5d4d4 JH |
1099 | retval = setup_port_interrupt_in(serial->port[i], |
1100 | epds->interrupt_in[i]); | |
1101 | if (retval) | |
c22ac6d2 | 1102 | goto err_free_epds; |
1da177e4 | 1103 | } |
1546e6ae | 1104 | } else if (epds->num_interrupt_in) { |
92931d24 | 1105 | dev_dbg(ddev, "The device claims to support interrupt in transfers, but read_int_callback is not defined\n"); |
1da177e4 | 1106 | } |
a8d6f0a9 | 1107 | |
1da177e4 | 1108 | if (serial->type->write_int_callback) { |
1546e6ae | 1109 | for (i = 0; i < epds->num_interrupt_out; ++i) { |
45e5d4d4 JH |
1110 | retval = setup_port_interrupt_out(serial->port[i], |
1111 | epds->interrupt_out[i]); | |
1112 | if (retval) | |
c22ac6d2 | 1113 | goto err_free_epds; |
1da177e4 | 1114 | } |
1546e6ae | 1115 | } else if (epds->num_interrupt_out) { |
92931d24 | 1116 | dev_dbg(ddev, "The device claims to support interrupt out transfers, but write_int_callback is not defined\n"); |
1da177e4 | 1117 | } |
a8d6f0a9 | 1118 | |
bdce6612 JH |
1119 | usb_set_intfdata(interface, serial); |
1120 | ||
1da177e4 LT |
1121 | /* if this device type has an attach function, call it */ |
1122 | if (type->attach) { | |
a8d6f0a9 | 1123 | retval = type->attach(serial); |
1da177e4 | 1124 | if (retval < 0) |
c22ac6d2 | 1125 | goto err_free_epds; |
a4720c65 | 1126 | serial->attached = 1; |
1da177e4 | 1127 | if (retval > 0) { |
a8d6f0a9 AC |
1128 | /* quietly accept this device, but don't bind to a |
1129 | serial port as it's about to disappear */ | |
0a3c8549 | 1130 | serial->num_ports = 0; |
1da177e4 LT |
1131 | goto exit; |
1132 | } | |
a4720c65 AS |
1133 | } else { |
1134 | serial->attached = 1; | |
1da177e4 LT |
1135 | } |
1136 | ||
c22ac6d2 JH |
1137 | retval = allocate_minors(serial, num_ports); |
1138 | if (retval) { | |
e5b1e206 | 1139 | dev_err(ddev, "No more free serial minor numbers\n"); |
c22ac6d2 | 1140 | goto err_free_epds; |
34ef50e5 ON |
1141 | } |
1142 | ||
1da177e4 LT |
1143 | /* register all of the individual ports with the driver core */ |
1144 | for (i = 0; i < num_ports; ++i) { | |
1145 | port = serial->port[i]; | |
1143832e | 1146 | dev_set_name(&port->dev, "ttyUSB%d", port->minor); |
d9a38a87 | 1147 | dev_dbg(ddev, "registering %s\n", dev_name(&port->dev)); |
a7a6b79b ML |
1148 | device_enable_async_suspend(&port->dev); |
1149 | ||
41bd34dd | 1150 | retval = device_add(&port->dev); |
891a3b1f | 1151 | if (retval) |
92931d24 | 1152 | dev_err(ddev, "Error registering port device, continuing\n"); |
1da177e4 LT |
1153 | } |
1154 | ||
126d26f6 JH |
1155 | if (num_ports > 0) |
1156 | usb_serial_console_init(serial->port[0]->minor); | |
1da177e4 | 1157 | exit: |
1546e6ae | 1158 | kfree(epds); |
d92a3ca6 | 1159 | module_put(type->driver.owner); |
1da177e4 LT |
1160 | return 0; |
1161 | ||
92e6b2c6 JH |
1162 | err_free_epds: |
1163 | kfree(epds); | |
5de03c99 JH |
1164 | err_release_sibling: |
1165 | release_sibling(serial, interface); | |
41bd34dd | 1166 | usb_serial_put(serial); |
c2fef456 | 1167 | err_put_module: |
d92a3ca6 | 1168 | module_put(type->driver.owner); |
c2fef456 JH |
1169 | |
1170 | return retval; | |
1da177e4 LT |
1171 | } |
1172 | ||
32078f91 | 1173 | static void usb_serial_disconnect(struct usb_interface *interface) |
1da177e4 LT |
1174 | { |
1175 | int i; | |
a8d6f0a9 | 1176 | struct usb_serial *serial = usb_get_intfdata(interface); |
1da177e4 LT |
1177 | struct device *dev = &interface->dev; |
1178 | struct usb_serial_port *port; | |
3fff3b43 | 1179 | struct tty_struct *tty; |
1da177e4 | 1180 | |
5de03c99 JH |
1181 | /* sibling interface is cleaning up */ |
1182 | if (!serial) | |
1183 | return; | |
1184 | ||
73e487fd | 1185 | usb_serial_console_disconnect(serial); |
1da177e4 | 1186 | |
a1cd7e99 | 1187 | mutex_lock(&serial->disc_mutex); |
a1cd7e99 ON |
1188 | /* must set a flag, to signal subdrivers */ |
1189 | serial->disconnected = 1; | |
2d93148a AS |
1190 | mutex_unlock(&serial->disc_mutex); |
1191 | ||
a1cd7e99 ON |
1192 | for (i = 0; i < serial->num_ports; ++i) { |
1193 | port = serial->port[i]; | |
3fff3b43 JH |
1194 | tty = tty_port_tty_get(&port->port); |
1195 | if (tty) { | |
1196 | tty_vhangup(tty); | |
1197 | tty_kref_put(tty); | |
2d93148a | 1198 | } |
3fff3b43 JH |
1199 | usb_serial_port_poison_urbs(port); |
1200 | wake_up_interruptible(&port->port.delta_msr_wait); | |
1201 | cancel_work_sync(&port->work); | |
1202 | if (device_is_registered(&port->dev)) | |
1203 | device_del(&port->dev); | |
2d93148a | 1204 | } |
0f16cfe3 JH |
1205 | if (serial->type->disconnect) |
1206 | serial->type->disconnect(serial); | |
2d93148a | 1207 | |
5de03c99 JH |
1208 | release_sibling(serial, interface); |
1209 | ||
41bd34dd | 1210 | /* let the last holder of this object cause it to be cleaned up */ |
a1cd7e99 | 1211 | usb_serial_put(serial); |
1da177e4 LT |
1212 | dev_info(dev, "device disconnected\n"); |
1213 | } | |
1214 | ||
ec22559e ON |
1215 | int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) |
1216 | { | |
1217 | struct usb_serial *serial = usb_get_intfdata(intf); | |
5de03c99 JH |
1218 | int i, r; |
1219 | ||
1220 | /* suspend when called for first sibling interface */ | |
1221 | if (serial->suspend_count++) | |
1222 | return 0; | |
ec22559e | 1223 | |
93e4f47f ML |
1224 | /* |
1225 | * serial->type->suspend() MUST return 0 in system sleep context, | |
1226 | * otherwise, the resume callback has to recover device from | |
1227 | * previous suspend failure. | |
1228 | */ | |
81e5b23c ON |
1229 | if (serial->type->suspend) { |
1230 | r = serial->type->suspend(serial, message); | |
5de03c99 JH |
1231 | if (r < 0) { |
1232 | serial->suspend_count--; | |
1233 | return r; | |
1234 | } | |
81e5b23c ON |
1235 | } |
1236 | ||
3fff3b43 JH |
1237 | for (i = 0; i < serial->num_ports; ++i) |
1238 | usb_serial_port_poison_urbs(serial->port[i]); | |
5de03c99 JH |
1239 | |
1240 | return 0; | |
ec22559e ON |
1241 | } |
1242 | EXPORT_SYMBOL(usb_serial_suspend); | |
1243 | ||
6a5c821c JH |
1244 | static void usb_serial_unpoison_port_urbs(struct usb_serial *serial) |
1245 | { | |
6a5c821c JH |
1246 | int i; |
1247 | ||
3fff3b43 JH |
1248 | for (i = 0; i < serial->num_ports; ++i) |
1249 | usb_serial_port_unpoison_urbs(serial->port[i]); | |
6a5c821c JH |
1250 | } |
1251 | ||
ec22559e ON |
1252 | int usb_serial_resume(struct usb_interface *intf) |
1253 | { | |
1254 | struct usb_serial *serial = usb_get_intfdata(intf); | |
c49cfa91 | 1255 | int rv; |
ec22559e | 1256 | |
5de03c99 JH |
1257 | /* resume when called for last sibling interface */ |
1258 | if (--serial->suspend_count) | |
1259 | return 0; | |
1260 | ||
6a5c821c JH |
1261 | usb_serial_unpoison_port_urbs(serial); |
1262 | ||
8abaee23 | 1263 | if (serial->type->resume) |
c49cfa91 ON |
1264 | rv = serial->type->resume(serial); |
1265 | else | |
1266 | rv = usb_serial_generic_resume(serial); | |
f8bece8d | 1267 | |
c49cfa91 | 1268 | return rv; |
ec22559e ON |
1269 | } |
1270 | EXPORT_SYMBOL(usb_serial_resume); | |
1271 | ||
7186364e GKH |
1272 | static int usb_serial_reset_resume(struct usb_interface *intf) |
1273 | { | |
1274 | struct usb_serial *serial = usb_get_intfdata(intf); | |
1275 | int rv; | |
1276 | ||
5de03c99 JH |
1277 | /* resume when called for last sibling interface */ |
1278 | if (--serial->suspend_count) | |
1279 | return 0; | |
1280 | ||
6a5c821c JH |
1281 | usb_serial_unpoison_port_urbs(serial); |
1282 | ||
ca0400d2 | 1283 | if (serial->type->reset_resume) { |
7186364e | 1284 | rv = serial->type->reset_resume(serial); |
ca0400d2 | 1285 | } else { |
dcd82cd1 GKH |
1286 | rv = -EOPNOTSUPP; |
1287 | intf->needs_binding = 1; | |
1288 | } | |
7186364e GKH |
1289 | |
1290 | return rv; | |
1291 | } | |
1292 | ||
b68e31d0 | 1293 | static const struct tty_operations serial_ops = { |
1da177e4 LT |
1294 | .open = serial_open, |
1295 | .close = serial_close, | |
1296 | .write = serial_write, | |
3e1f4901 | 1297 | .hangup = serial_hangup, |
1da177e4 LT |
1298 | .write_room = serial_write_room, |
1299 | .ioctl = serial_ioctl, | |
1300 | .set_termios = serial_set_termios, | |
1301 | .throttle = serial_throttle, | |
1302 | .unthrottle = serial_unthrottle, | |
1303 | .break_ctl = serial_break, | |
1304 | .chars_in_buffer = serial_chars_in_buffer, | |
0693196f | 1305 | .wait_until_sent = serial_wait_until_sent, |
1da177e4 LT |
1306 | .tiocmget = serial_tiocmget, |
1307 | .tiocmset = serial_tiocmset, | |
3e1f4901 | 1308 | .get_icount = serial_get_icount, |
81732b26 AV |
1309 | .set_serial = serial_set_serial, |
1310 | .get_serial = serial_get_serial, | |
3e1f4901 JH |
1311 | .cleanup = serial_cleanup, |
1312 | .install = serial_install, | |
8a8dcabf | 1313 | .proc_show = serial_proc_show, |
1da177e4 LT |
1314 | }; |
1315 | ||
335f8514 | 1316 | |
1da177e4 LT |
1317 | struct tty_driver *usb_serial_tty_driver; |
1318 | ||
1319 | static int __init usb_serial_init(void) | |
1320 | { | |
1da177e4 LT |
1321 | int result; |
1322 | ||
39b7b42b JS |
1323 | usb_serial_tty_driver = tty_alloc_driver(USB_SERIAL_TTY_MINORS, |
1324 | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); | |
1325 | if (IS_ERR(usb_serial_tty_driver)) | |
1326 | return PTR_ERR(usb_serial_tty_driver); | |
1da177e4 LT |
1327 | |
1328 | /* Initialize our global data */ | |
1da177e4 LT |
1329 | result = bus_register(&usb_serial_bus_type); |
1330 | if (result) { | |
92931d24 | 1331 | pr_err("%s - registering bus driver failed\n", __func__); |
96a83c95 | 1332 | goto err_put_driver; |
1da177e4 LT |
1333 | } |
1334 | ||
1da177e4 | 1335 | usb_serial_tty_driver->driver_name = "usbserial"; |
3e1f4901 | 1336 | usb_serial_tty_driver->name = "ttyUSB"; |
455b4f7e | 1337 | usb_serial_tty_driver->major = USB_SERIAL_TTY_MAJOR; |
1da177e4 LT |
1338 | usb_serial_tty_driver->minor_start = 0; |
1339 | usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; | |
1340 | usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL; | |
1da177e4 | 1341 | usb_serial_tty_driver->init_termios = tty_std_termios; |
a8d6f0a9 AC |
1342 | usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD |
1343 | | HUPCL | CLOCAL; | |
a5b6f60c AC |
1344 | usb_serial_tty_driver->init_termios.c_ispeed = 9600; |
1345 | usb_serial_tty_driver->init_termios.c_ospeed = 9600; | |
1da177e4 LT |
1346 | tty_set_operations(usb_serial_tty_driver, &serial_ops); |
1347 | result = tty_register_driver(usb_serial_tty_driver); | |
1348 | if (result) { | |
92931d24 | 1349 | pr_err("%s - tty_register_driver failed\n", __func__); |
96a83c95 | 1350 | goto err_unregister_bus; |
1da177e4 LT |
1351 | } |
1352 | ||
06299db3 | 1353 | /* register the generic driver, if we should */ |
3033bc8d | 1354 | result = usb_serial_generic_register(); |
06299db3 | 1355 | if (result < 0) { |
92931d24 | 1356 | pr_err("%s - registering generic driver failed\n", __func__); |
96a83c95 | 1357 | goto err_unregister_driver; |
06299db3 GKH |
1358 | } |
1359 | ||
1da177e4 LT |
1360 | return result; |
1361 | ||
96a83c95 | 1362 | err_unregister_driver: |
1da177e4 | 1363 | tty_unregister_driver(usb_serial_tty_driver); |
96a83c95 | 1364 | err_unregister_bus: |
1da177e4 | 1365 | bus_unregister(&usb_serial_bus_type); |
96a83c95 | 1366 | err_put_driver: |
92931d24 | 1367 | pr_err("%s - returning with error %d\n", __func__, result); |
9f90a4dd | 1368 | tty_driver_kref_put(usb_serial_tty_driver); |
1da177e4 LT |
1369 | return result; |
1370 | } | |
1371 | ||
1372 | ||
1373 | static void __exit usb_serial_exit(void) | |
1374 | { | |
1375 | usb_serial_console_exit(); | |
1376 | ||
1377 | usb_serial_generic_deregister(); | |
1378 | ||
1da177e4 | 1379 | tty_unregister_driver(usb_serial_tty_driver); |
9f90a4dd | 1380 | tty_driver_kref_put(usb_serial_tty_driver); |
1da177e4 | 1381 | bus_unregister(&usb_serial_bus_type); |
d23f47d4 | 1382 | idr_destroy(&serial_minors); |
1da177e4 LT |
1383 | } |
1384 | ||
1385 | ||
1386 | module_init(usb_serial_init); | |
1387 | module_exit(usb_serial_exit); | |
1388 | ||
1389 | #define set_to_generic_if_null(type, function) \ | |
1390 | do { \ | |
1391 | if (!type->function) { \ | |
1392 | type->function = usb_serial_generic_##function; \ | |
c3452f5e JH |
1393 | pr_debug("%s: using generic " #function "\n", \ |
1394 | type->driver.name); \ | |
1395 | } \ | |
1da177e4 LT |
1396 | } while (0) |
1397 | ||
c3452f5e | 1398 | static void usb_serial_operations_init(struct usb_serial_driver *device) |
1da177e4 LT |
1399 | { |
1400 | set_to_generic_if_null(device, open); | |
1401 | set_to_generic_if_null(device, write); | |
1402 | set_to_generic_if_null(device, close); | |
1403 | set_to_generic_if_null(device, write_room); | |
1404 | set_to_generic_if_null(device, chars_in_buffer); | |
dcf01050 JH |
1405 | if (device->tx_empty) |
1406 | set_to_generic_if_null(device, wait_until_sent); | |
1da177e4 LT |
1407 | set_to_generic_if_null(device, read_bulk_callback); |
1408 | set_to_generic_if_null(device, write_bulk_callback); | |
23154320 | 1409 | set_to_generic_if_null(device, process_read_urb); |
eaa3bcb0 | 1410 | set_to_generic_if_null(device, prepare_write_buffer); |
1da177e4 LT |
1411 | } |
1412 | ||
f799e767 | 1413 | static int usb_serial_register(struct usb_serial_driver *driver) |
1da177e4 LT |
1414 | { |
1415 | int retval; | |
1416 | ||
e4abe665 DY |
1417 | if (usb_disabled()) |
1418 | return -ENODEV; | |
1419 | ||
269bda1c GKH |
1420 | if (!driver->description) |
1421 | driver->description = driver->driver.name; | |
5620b5f7 AS |
1422 | if (!driver->usb_driver) { |
1423 | WARN(1, "Serial driver %s has no usb_driver\n", | |
1424 | driver->description); | |
1425 | return -EINVAL; | |
1426 | } | |
269bda1c | 1427 | |
fdb838ef JH |
1428 | /* Prevent individual ports from being unbound. */ |
1429 | driver->driver.suppress_bind_attrs = true; | |
1430 | ||
c3452f5e JH |
1431 | usb_serial_operations_init(driver); |
1432 | ||
1da177e4 | 1433 | /* Add this device to our list of devices */ |
0daeed38 | 1434 | mutex_lock(&table_lock); |
ea65370d | 1435 | list_add(&driver->driver_list, &usb_serial_driver_list); |
1da177e4 | 1436 | |
ea65370d | 1437 | retval = usb_serial_bus_register(driver); |
1da177e4 | 1438 | if (retval) { |
92931d24 | 1439 | pr_err("problem %d when registering driver %s\n", retval, driver->description); |
ea65370d | 1440 | list_del(&driver->driver_list); |
ca0400d2 | 1441 | } else { |
ee42f6c9 | 1442 | pr_info("USB Serial support registered for %s\n", driver->description); |
ca0400d2 | 1443 | } |
0daeed38 | 1444 | mutex_unlock(&table_lock); |
1da177e4 LT |
1445 | return retval; |
1446 | } | |
1447 | ||
f799e767 | 1448 | static void usb_serial_deregister(struct usb_serial_driver *device) |
1da177e4 | 1449 | { |
ee42f6c9 | 1450 | pr_info("USB Serial deregistering driver %s\n", device->description); |
10164c2a | 1451 | |
0daeed38 | 1452 | mutex_lock(&table_lock); |
1da177e4 | 1453 | list_del(&device->driver_list); |
0daeed38 | 1454 | mutex_unlock(&table_lock); |
10164c2a JH |
1455 | |
1456 | usb_serial_bus_deregister(device); | |
1da177e4 | 1457 | } |
1da177e4 | 1458 | |
765e0ba6 | 1459 | /** |
af8a6e65 | 1460 | * __usb_serial_register_drivers - register drivers for a usb-serial module |
765e0ba6 | 1461 | * @serial_drivers: NULL-terminated array of pointers to drivers to be registered |
af8a6e65 | 1462 | * @owner: owning module |
68e24113 GKH |
1463 | * @name: name of the usb_driver for this set of @serial_drivers |
1464 | * @id_table: list of all devices this @serial_drivers set binds to | |
765e0ba6 | 1465 | * |
68e24113 GKH |
1466 | * Registers all the drivers in the @serial_drivers array, and dynamically |
1467 | * creates a struct usb_driver with the name @name and id_table of @id_table. | |
765e0ba6 | 1468 | */ |
af8a6e65 KK |
1469 | int __usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[], |
1470 | struct module *owner, const char *name, | |
1471 | const struct usb_device_id *id_table) | |
765e0ba6 AS |
1472 | { |
1473 | int rc; | |
68e24113 | 1474 | struct usb_driver *udriver; |
765e0ba6 AS |
1475 | struct usb_serial_driver * const *sd; |
1476 | ||
1477 | /* | |
1478 | * udriver must be registered before any of the serial drivers, | |
1479 | * because the store_new_id() routine for the serial drivers (in | |
1480 | * bus.c) probes udriver. | |
1481 | * | |
1482 | * Performance hack: We don't want udriver to be probed until | |
1483 | * the serial drivers are registered, because the probe would | |
1484 | * simply fail for lack of a matching serial driver. | |
68e24113 | 1485 | * So we leave udriver's id_table set to NULL until we are all set. |
5cbe61c5 AS |
1486 | * |
1487 | * Suspend/resume support is implemented in the usb-serial core, | |
1488 | * so fill in the PM-related fields in udriver. | |
765e0ba6 | 1489 | */ |
68e24113 GKH |
1490 | udriver = kzalloc(sizeof(*udriver), GFP_KERNEL); |
1491 | if (!udriver) | |
1492 | return -ENOMEM; | |
765e0ba6 | 1493 | |
68e24113 | 1494 | udriver->name = name; |
765e0ba6 | 1495 | udriver->no_dynamic_id = 1; |
5cbe61c5 AS |
1496 | udriver->supports_autosuspend = 1; |
1497 | udriver->suspend = usb_serial_suspend; | |
1498 | udriver->resume = usb_serial_resume; | |
5026bb07 | 1499 | udriver->probe = usb_serial_probe; |
32078f91 | 1500 | udriver->disconnect = usb_serial_disconnect; |
7186364e GKH |
1501 | |
1502 | /* we only set the reset_resume field if the serial_driver has one */ | |
1503 | for (sd = serial_drivers; *sd; ++sd) { | |
44b0f083 | 1504 | if ((*sd)->reset_resume) { |
7186364e GKH |
1505 | udriver->reset_resume = usb_serial_reset_resume; |
1506 | break; | |
44b0f083 | 1507 | } |
7186364e GKH |
1508 | } |
1509 | ||
765e0ba6 AS |
1510 | rc = usb_register(udriver); |
1511 | if (rc) | |
96a83c95 | 1512 | goto err_free_driver; |
765e0ba6 AS |
1513 | |
1514 | for (sd = serial_drivers; *sd; ++sd) { | |
1515 | (*sd)->usb_driver = udriver; | |
af8a6e65 | 1516 | (*sd)->driver.owner = owner; |
765e0ba6 AS |
1517 | rc = usb_serial_register(*sd); |
1518 | if (rc) | |
96a83c95 | 1519 | goto err_deregister_drivers; |
765e0ba6 AS |
1520 | } |
1521 | ||
68e24113 GKH |
1522 | /* Now set udriver's id_table and look for matches */ |
1523 | udriver->id_table = id_table; | |
49a78b05 | 1524 | rc = driver_attach(&udriver->driver); |
765e0ba6 AS |
1525 | return 0; |
1526 | ||
96a83c95 | 1527 | err_deregister_drivers: |
765e0ba6 AS |
1528 | while (sd-- > serial_drivers) |
1529 | usb_serial_deregister(*sd); | |
1530 | usb_deregister(udriver); | |
96a83c95 | 1531 | err_free_driver: |
647024a7 | 1532 | kfree(udriver); |
765e0ba6 AS |
1533 | return rc; |
1534 | } | |
af8a6e65 | 1535 | EXPORT_SYMBOL_GPL(__usb_serial_register_drivers); |
765e0ba6 AS |
1536 | |
1537 | /** | |
1538 | * usb_serial_deregister_drivers - deregister drivers for a usb-serial module | |
765e0ba6 AS |
1539 | * @serial_drivers: NULL-terminated array of pointers to drivers to be deregistered |
1540 | * | |
68e24113 GKH |
1541 | * Deregisters all the drivers in the @serial_drivers array and deregisters and |
1542 | * frees the struct usb_driver that was created by the call to | |
1543 | * usb_serial_register_drivers(). | |
765e0ba6 | 1544 | */ |
68e24113 | 1545 | void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[]) |
765e0ba6 | 1546 | { |
68e24113 GKH |
1547 | struct usb_driver *udriver = (*serial_drivers)->usb_driver; |
1548 | ||
765e0ba6 AS |
1549 | for (; *serial_drivers; ++serial_drivers) |
1550 | usb_serial_deregister(*serial_drivers); | |
1551 | usb_deregister(udriver); | |
68e24113 | 1552 | kfree(udriver); |
765e0ba6 AS |
1553 | } |
1554 | EXPORT_SYMBOL_GPL(usb_serial_deregister_drivers); | |
1da177e4 | 1555 | |
a8d6f0a9 AC |
1556 | MODULE_AUTHOR(DRIVER_AUTHOR); |
1557 | MODULE_DESCRIPTION(DRIVER_DESC); | |
627cfa89 | 1558 | MODULE_LICENSE("GPL v2"); |