usb-serial.c 35.1 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3
/*
 * USB Serial Converter driver
 *
4
 * Copyright (C) 1999 - 2005 Greg Kroah-Hartman (greg@kroah.com)
L
Linus Torvalds 已提交
5 6 7 8 9 10 11
 * Copyright (C) 2000 Peter Berger (pberger@brimson.com)
 * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com)
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License version
 *	2 as published by the Free Software Foundation.
 *
12
 * This driver was originally based on the ACM driver by Armin Fuerst (which was
L
Linus Torvalds 已提交
13 14
 * based on a driver by Brad Keryan)
 *
A
Alan Cox 已提交
15 16
 * See Documentation/usb/usb-serial.txt for more information on using this
 * driver
L
Linus Torvalds 已提交
17 18 19 20 21 22 23 24 25 26 27 28
 *
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
29
#include <linux/seq_file.h>
L
Linus Torvalds 已提交
30
#include <linux/spinlock.h>
31
#include <linux/mutex.h>
L
Linus Torvalds 已提交
32
#include <linux/list.h>
A
Alan Cox 已提交
33
#include <linux/uaccess.h>
L
Linus Torvalds 已提交
34
#include <linux/usb.h>
35
#include <linux/usb/serial.h>
L
Linus Torvalds 已提交
36 37 38 39 40 41 42 43
#include "pl2303.h"

/*
 * Version Information
 */
#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/"
#define DRIVER_DESC "USB Serial Driver core"

44 45
static void port_free(struct usb_serial_port *port);

L
Linus Torvalds 已提交
46 47 48 49 50
/* Driver structure we register with the USB core */
static struct usb_driver usb_serial_driver = {
	.name =		"usbserial",
	.probe =	usb_serial_probe,
	.disconnect =	usb_serial_disconnect,
51 52
	.suspend =	usb_serial_suspend,
	.resume =	usb_serial_resume,
53
	.no_dynamic_id = 	1,
L
Linus Torvalds 已提交
54 55 56 57 58 59 60 61 62 63
};

/* There is no MODULE_DEVICE_TABLE for usbserial.c.  Instead
   the MODULE_DEVICE_TABLE declarations in each serial driver
   cause the "hotplug" program to pull in whatever module is necessary
   via modprobe, and modprobe will load usbserial because the serial
   drivers depend on it.
*/

static int debug;
A
Alan Cox 已提交
64 65
/* initially all NULL */
static struct usb_serial *serial_table[SERIAL_TTY_MINORS];
66
static DEFINE_MUTEX(table_lock);
L
Linus Torvalds 已提交
67 68 69 70
static LIST_HEAD(usb_serial_driver_list);

struct usb_serial *usb_serial_get_by_index(unsigned index)
{
71 72
	struct usb_serial *serial;

73
	mutex_lock(&table_lock);
74
	serial = serial_table[index];
L
Linus Torvalds 已提交
75 76 77

	if (serial)
		kref_get(&serial->kref);
78
	mutex_unlock(&table_lock);
L
Linus Torvalds 已提交
79 80 81
	return serial;
}

A
Alan Cox 已提交
82 83
static struct usb_serial *get_free_serial(struct usb_serial *serial,
					int num_ports, unsigned int *minor)
L
Linus Torvalds 已提交
84 85 86 87
{
	unsigned int i, j;
	int good_spot;

88
	dbg("%s %d", __func__, num_ports);
L
Linus Torvalds 已提交
89 90

	*minor = 0;
91
	mutex_lock(&table_lock);
L
Linus Torvalds 已提交
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
	for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
		if (serial_table[i])
			continue;

		good_spot = 1;
		for (j = 1; j <= num_ports-1; ++j)
			if ((i+j >= SERIAL_TTY_MINORS) || (serial_table[i+j])) {
				good_spot = 0;
				i += j;
				break;
			}
		if (good_spot == 0)
			continue;

		*minor = i;
O
Oliver Neukum 已提交
107
		j = 0;
108
		dbg("%s - minor base = %d", __func__, *minor);
O
Oliver Neukum 已提交
109
		for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) {
L
Linus Torvalds 已提交
110
			serial_table[i] = serial;
O
Oliver Neukum 已提交
111 112
			serial->port[j++]->number = i;
		}
113
		mutex_unlock(&table_lock);
L
Linus Torvalds 已提交
114 115
		return serial;
	}
116
	mutex_unlock(&table_lock);
L
Linus Torvalds 已提交
117 118 119 120 121 122 123
	return NULL;
}

static void return_serial(struct usb_serial *serial)
{
	int i;

124
	dbg("%s", __func__);
L
Linus Torvalds 已提交
125

A
Alan Cox 已提交
126
	for (i = 0; i < serial->num_ports; ++i)
L
Linus Torvalds 已提交
127 128 129 130 131 132 133 134 135 136 137
		serial_table[serial->minor + i] = NULL;
}

static void destroy_serial(struct kref *kref)
{
	struct usb_serial *serial;
	struct usb_serial_port *port;
	int i;

	serial = to_usb_serial(kref);

138
	dbg("%s - %s", __func__, serial->type->description);
L
Linus Torvalds 已提交
139

J
Jim Radford 已提交
140
	/* return the minor range that this device had */
141 142
	if (serial->minor != SERIAL_TTY_NO_MINOR)
		return_serial(serial);
J
Jim Radford 已提交
143

L
Linus Torvalds 已提交
144 145 146 147
	/* If this is a "fake" port, we have to clean it up here, as it will
	 * not get cleaned up in port_release() as it was never registered with
	 * the driver core */
	if (serial->num_ports < serial->num_port_pointers) {
A
Alan Cox 已提交
148 149
		for (i = serial->num_ports;
					i < serial->num_port_pointers; ++i) {
L
Linus Torvalds 已提交
150 151 152
			port = serial->port[i];
			if (!port)
				continue;
153
			port_free(port);
L
Linus Torvalds 已提交
154 155 156 157 158 159
		}
	}

	usb_put_dev(serial->dev);

	/* free up any memory that we allocated */
A
Alan Cox 已提交
160
	kfree(serial);
L
Linus Torvalds 已提交
161 162
}

163 164
void usb_serial_put(struct usb_serial *serial)
{
165
	mutex_lock(&table_lock);
166
	kref_put(&serial->kref, destroy_serial);
167
	mutex_unlock(&table_lock);
168 169
}

L
Linus Torvalds 已提交
170 171 172
/*****************************************************************************
 * Driver tty interface functions
 *****************************************************************************/
A
Alan Cox 已提交
173
static int serial_open (struct tty_struct *tty, struct file *filp)
L
Linus Torvalds 已提交
174 175 176 177
{
	struct usb_serial *serial;
	struct usb_serial_port *port;
	unsigned int portNumber;
178
	int retval = 0;
A
Alan Cox 已提交
179

180
	dbg("%s", __func__);
L
Linus Torvalds 已提交
181 182 183 184 185 186 187 188

	/* get the serial object associated with this tty pointer */
	serial = usb_serial_get_by_index(tty->index);
	if (!serial) {
		tty->driver_data = NULL;
		return -ENODEV;
	}

189
	mutex_lock(&serial->disc_mutex);
L
Linus Torvalds 已提交
190 191
	portNumber = tty->index - serial->minor;
	port = serial->port[portNumber];
192
	if (!port || serial->disconnected)
193
		retval = -ENODEV;
194 195 196 197 198 199 200 201 202
	else
		get_device(&port->dev);
	/*
	 * Note: Our locking order requirement does not allow port->mutex
	 * to be acquired while serial->disc_mutex is held.
	 */
	mutex_unlock(&serial->disc_mutex);
	if (retval)
		goto bailout_serial_put;
203

204 205
	if (mutex_lock_interruptible(&port->mutex)) {
		retval = -ERESTARTSYS;
206
		goto bailout_port_put;
207
	}
A
Alan Cox 已提交
208

A
Alan Cox 已提交
209
	++port->port.count;
L
Linus Torvalds 已提交
210

211 212 213
	/* set up our port structure making the tty driver
	 * remember our port object, and us it */
	tty->driver_data = port;
A
Alan Cox 已提交
214
	tty_port_tty_set(&port->port, tty);
L
Linus Torvalds 已提交
215

A
Alan Cox 已提交
216
	if (port->port.count == 1) {
L
Linus Torvalds 已提交
217 218 219 220

		/* lock this module before we call it
		 * this may fail, which means we must bail out,
		 * safe because we are called with BKL held */
221
		if (!try_module_get(serial->type->driver.owner)) {
L
Linus Torvalds 已提交
222
			retval = -ENODEV;
223
			goto bailout_mutex_unlock;
L
Linus Torvalds 已提交
224 225
		}

226 227 228 229 230
		mutex_lock(&serial->disc_mutex);
		if (serial->disconnected)
			retval = -ENODEV;
		else
			retval = usb_autopm_get_interface(serial->interface);
231 232
		if (retval)
			goto bailout_module_put;
233

A
Alan Cox 已提交
234
		/* only call the device specific open if this
L
Linus Torvalds 已提交
235
		 * is the first time the port is opened */
A
Alan Cox 已提交
236
		retval = serial->type->open(tty, port, filp);
L
Linus Torvalds 已提交
237
		if (retval)
238
			goto bailout_interface_put;
239
		mutex_unlock(&serial->disc_mutex);
L
Linus Torvalds 已提交
240 241
	}

242
	mutex_unlock(&port->mutex);
L
Linus Torvalds 已提交
243 244
	return 0;

245 246
bailout_interface_put:
	usb_autopm_put_interface(serial->interface);
L
Linus Torvalds 已提交
247
bailout_module_put:
248
	mutex_unlock(&serial->disc_mutex);
249
	module_put(serial->type->driver.owner);
250
bailout_mutex_unlock:
A
Alan Cox 已提交
251
	port->port.count = 0;
252
	tty->driver_data = NULL;
A
Alan Cox 已提交
253
	tty_port_tty_set(&port->port, NULL);
254
	mutex_unlock(&port->mutex);
255 256 257
bailout_port_put:
	put_device(&port->dev);
bailout_serial_put:
258
	usb_serial_put(serial);
L
Linus Torvalds 已提交
259 260 261
	return retval;
}

A
Alan Cox 已提交
262
static void serial_close(struct tty_struct *tty, struct file *filp)
L
Linus Torvalds 已提交
263
{
264
	struct usb_serial_port *port = tty->driver_data;
265 266 267
	struct usb_serial *serial;
	struct module *owner;
	int count;
L
Linus Torvalds 已提交
268 269 270 271

	if (!port)
		return;

272
	dbg("%s - port %d", __func__, port->number);
L
Linus Torvalds 已提交
273

274
	mutex_lock(&port->mutex);
275 276
	serial = port->serial;
	owner = serial->type->driver.owner;
277

A
Alan Cox 已提交
278
	if (port->port.count == 0) {
279
		mutex_unlock(&port->mutex);
280 281
		return;
	}
L
Linus Torvalds 已提交
282

A
Alan Cox 已提交
283
	if (port->port.count == 1)
A
Alan Cox 已提交
284
		/* only call the device specific close if this
A
Alan Cox 已提交
285 286 287 288
		 * port is being closed by the last owner. Ensure we do
		 * this before we drop the port count. The call is protected
		 * by the port mutex
		 */
289
		serial->type->close(tty, port, filp);
L
Linus Torvalds 已提交
290

A
Alan Cox 已提交
291
	if (port->port.count == (port->console ? 2 : 1)) {
A
Alan Cox 已提交
292 293
		struct tty_struct *tty = tty_port_tty_get(&port->port);
		if (tty) {
A
Alan Cox 已提交
294 295
			/* We must do this before we drop the port count to
			   zero. */
A
Alan Cox 已提交
296 297 298
			if (tty->driver_data)
				tty->driver_data = NULL;
			tty_port_tty_set(&port->port, NULL);
A
Alan Cox 已提交
299
			tty_kref_put(tty);
L
Linus Torvalds 已提交
300
		}
301
	}
L
Linus Torvalds 已提交
302

A
Alan Cox 已提交
303
	--port->port.count;
304
	count = port->port.count;
305
	mutex_unlock(&port->mutex);
306 307 308 309 310 311 312 313 314 315 316 317 318 319
	put_device(&port->dev);

	/* Mustn't dereference port any more */
	if (count == 0) {
		mutex_lock(&serial->disc_mutex);
		if (!serial->disconnected)
			usb_autopm_put_interface(serial->interface);
		mutex_unlock(&serial->disc_mutex);
	}
	usb_serial_put(serial);

	/* Mustn't dereference serial any more */
	if (count == 0)
		module_put(owner);
L
Linus Torvalds 已提交
320 321
}

A
Alan Cox 已提交
322 323
static int serial_write(struct tty_struct *tty, const unsigned char *buf,
								int count)
L
Linus Torvalds 已提交
324
{
325
	struct usb_serial_port *port = tty->driver_data;
326
	int retval = -ENODEV;
L
Linus Torvalds 已提交
327

A
Alan Cox 已提交
328
	if (port->serial->dev->state == USB_STATE_NOTATTACHED)
329 330
		goto exit;

331
	dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
L
Linus Torvalds 已提交
332

A
Alan Cox 已提交
333
	/* count is managed under the mutex lock for the tty so cannot
A
Alan Cox 已提交
334
	   drop to zero until after the last close completes */
A
Alan Cox 已提交
335
	WARN_ON(!port->port.count);
L
Linus Torvalds 已提交
336 337

	/* pass on to the driver specific version of this function */
A
Alan Cox 已提交
338
	retval = port->serial->type->write(tty, port, buf, count);
L
Linus Torvalds 已提交
339 340 341 342 343

exit:
	return retval;
}

A
Alan Cox 已提交
344
static int serial_write_room(struct tty_struct *tty)
L
Linus Torvalds 已提交
345
{
346
	struct usb_serial_port *port = tty->driver_data;
347
	dbg("%s - port %d", __func__, port->number);
A
Alan Cox 已提交
348
	WARN_ON(!port->port.count);
L
Linus Torvalds 已提交
349
	/* pass on to the driver specific version of this function */
A
Alan Cox 已提交
350
	return port->serial->type->write_room(tty);
L
Linus Torvalds 已提交
351 352
}

A
Alan Cox 已提交
353
static int serial_chars_in_buffer(struct tty_struct *tty)
L
Linus Torvalds 已提交
354
{
355
	struct usb_serial_port *port = tty->driver_data;
356
	dbg("%s = port %d", __func__, port->number);
L
Linus Torvalds 已提交
357

A
Alan Cox 已提交
358
	WARN_ON(!port->port.count);
359 360 361 362
	/* if the device was unplugged then any remaining characters
	   fell out of the connector ;) */
	if (port->serial->disconnected)
		return 0;
L
Linus Torvalds 已提交
363
	/* pass on to the driver specific version of this function */
A
Alan Cox 已提交
364
	return port->serial->type->chars_in_buffer(tty);
L
Linus Torvalds 已提交
365 366
}

A
Alan Cox 已提交
367
static void serial_throttle(struct tty_struct *tty)
L
Linus Torvalds 已提交
368
{
369
	struct usb_serial_port *port = tty->driver_data;
370
	dbg("%s - port %d", __func__, port->number);
L
Linus Torvalds 已提交
371

A
Alan Cox 已提交
372
	WARN_ON(!port->port.count);
L
Linus Torvalds 已提交
373 374
	/* pass on to the driver specific version of this function */
	if (port->serial->type->throttle)
A
Alan Cox 已提交
375
		port->serial->type->throttle(tty);
L
Linus Torvalds 已提交
376 377
}

A
Alan Cox 已提交
378
static void serial_unthrottle(struct tty_struct *tty)
L
Linus Torvalds 已提交
379
{
380
	struct usb_serial_port *port = tty->driver_data;
381
	dbg("%s - port %d", __func__, port->number);
L
Linus Torvalds 已提交
382

A
Alan Cox 已提交
383
	WARN_ON(!port->port.count);
L
Linus Torvalds 已提交
384 385
	/* pass on to the driver specific version of this function */
	if (port->serial->type->unthrottle)
A
Alan Cox 已提交
386
		port->serial->type->unthrottle(tty);
L
Linus Torvalds 已提交
387 388
}

A
Alan Cox 已提交
389 390
static int serial_ioctl(struct tty_struct *tty, struct file *file,
					unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
391
{
392
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
393 394
	int retval = -ENODEV;

395
	dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
L
Linus Torvalds 已提交
396

A
Alan Cox 已提交
397
	WARN_ON(!port->port.count);
L
Linus Torvalds 已提交
398

A
Alan Cox 已提交
399 400
	/* pass on to the driver specific version of this function
	   if it is available */
A
Alan Cox 已提交
401
	if (port->serial->type->ioctl) {
A
Alan Cox 已提交
402
		retval = port->serial->type->ioctl(tty, file, cmd, arg);
A
Alan Cox 已提交
403
	} else
L
Linus Torvalds 已提交
404 405 406 407
		retval = -ENOIOCTLCMD;
	return retval;
}

A
Alan Cox 已提交
408
static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
L
Linus Torvalds 已提交
409
{
410
	struct usb_serial_port *port = tty->driver_data;
411
	dbg("%s - port %d", __func__, port->number);
L
Linus Torvalds 已提交
412

A
Alan Cox 已提交
413
	WARN_ON(!port->port.count);
A
Alan Cox 已提交
414 415
	/* pass on to the driver specific version of this function
	   if it is available */
L
Linus Torvalds 已提交
416
	if (port->serial->type->set_termios)
A
Alan Cox 已提交
417
		port->serial->type->set_termios(tty, port, old);
418 419
	else
		tty_termios_copy_hw(tty->termios, old);
L
Linus Torvalds 已提交
420 421
}

A
Alan Cox 已提交
422
static int serial_break(struct tty_struct *tty, int break_state)
L
Linus Torvalds 已提交
423
{
424
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
425

426
	dbg("%s - port %d", __func__, port->number);
L
Linus Torvalds 已提交
427

A
Alan Cox 已提交
428
	WARN_ON(!port->port.count);
A
Alan Cox 已提交
429 430
	/* pass on to the driver specific version of this function
	   if it is available */
431
	if (port->serial->type->break_ctl)
A
Alan Cox 已提交
432
		port->serial->type->break_ctl(tty, break_state);
A
Alan Cox 已提交
433
	return 0;
L
Linus Torvalds 已提交
434 435
}

436
static int serial_proc_show(struct seq_file *m, void *v)
L
Linus Torvalds 已提交
437 438 439 440 441
{
	struct usb_serial *serial;
	int i;
	char tmp[40];

442
	dbg("%s", __func__);
443 444
	seq_puts(m, "usbserinfo:1.0 driver:2.0\n");
	for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
L
Linus Torvalds 已提交
445 446 447 448
		serial = usb_serial_get_by_index(i);
		if (serial == NULL)
			continue;

449
		seq_printf(m, "%d:", i);
450
		if (serial->type->driver.owner)
451
			seq_printf(m, " module:%s",
A
Alan Cox 已提交
452
				module_name(serial->type->driver.owner));
453
		seq_printf(m, " name:\"%s\"",
A
Alan Cox 已提交
454
				serial->type->description);
455
		seq_printf(m, " vendor:%04x product:%04x",
A
Alan Cox 已提交
456 457
			le16_to_cpu(serial->dev->descriptor.idVendor),
			le16_to_cpu(serial->dev->descriptor.idProduct));
458 459
		seq_printf(m, " num_ports:%d", serial->num_ports);
		seq_printf(m, " port:%d", i - serial->minor + 1);
L
Linus Torvalds 已提交
460
		usb_make_path(serial->dev, tmp, sizeof(tmp));
461
		seq_printf(m, " path:%s", tmp);
A
Alan Cox 已提交
462

463
		seq_putc(m, '\n');
464
		usb_serial_put(serial);
L
Linus Torvalds 已提交
465
	}
466
	return 0;
L
Linus Torvalds 已提交
467 468
}

469 470 471 472 473 474 475 476 477 478 479 480 481
static int serial_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, serial_proc_show, NULL);
}

static const struct file_operations serial_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= serial_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

A
Alan Cox 已提交
482
static int serial_tiocmget(struct tty_struct *tty, struct file *file)
L
Linus Torvalds 已提交
483
{
484
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
485

486
	dbg("%s - port %d", __func__, port->number);
L
Linus Torvalds 已提交
487

A
Alan Cox 已提交
488
	WARN_ON(!port->port.count);
L
Linus Torvalds 已提交
489
	if (port->serial->type->tiocmget)
A
Alan Cox 已提交
490
		return port->serial->type->tiocmget(tty, file);
L
Linus Torvalds 已提交
491 492 493
	return -EINVAL;
}

A
Alan Cox 已提交
494
static int serial_tiocmset(struct tty_struct *tty, struct file *file,
L
Linus Torvalds 已提交
495 496
			    unsigned int set, unsigned int clear)
{
497
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
498

499
	dbg("%s - port %d", __func__, port->number);
L
Linus Torvalds 已提交
500

A
Alan Cox 已提交
501
	WARN_ON(!port->port.count);
L
Linus Torvalds 已提交
502
	if (port->serial->type->tiocmset)
A
Alan Cox 已提交
503
		return port->serial->type->tiocmset(tty, file, set, clear);
L
Linus Torvalds 已提交
504 505 506
	return -EINVAL;
}

507 508 509 510 511 512 513 514 515
/*
 * We would be calling tty_wakeup here, but unfortunately some line
 * disciplines have an annoying habit of calling tty->write from
 * the write wakeup callback (e.g. n_hdlc.c).
 */
void usb_serial_port_softint(struct usb_serial_port *port)
{
	schedule_work(&port->work);
}
A
Alan Cox 已提交
516
EXPORT_SYMBOL_GPL(usb_serial_port_softint);
517

D
David Howells 已提交
518
static void usb_serial_port_work(struct work_struct *work)
L
Linus Torvalds 已提交
519
{
D
David Howells 已提交
520 521
	struct usb_serial_port *port =
		container_of(work, struct usb_serial_port, work);
L
Linus Torvalds 已提交
522 523
	struct tty_struct *tty;

524
	dbg("%s - port %d", __func__, port->number);
A
Alan Cox 已提交
525

A
Alan Cox 已提交
526
	tty = tty_port_tty_get(&port->port);
L
Linus Torvalds 已提交
527 528 529 530
	if (!tty)
		return;

	tty_wakeup(tty);
A
Alan Cox 已提交
531
	tty_kref_put(tty);
L
Linus Torvalds 已提交
532 533 534 535 536 537
}

static void port_release(struct device *dev)
{
	struct usb_serial_port *port = to_usb_serial_port(dev);

538
	dbg ("%s - %s", __func__, dev_name(dev));
539 540 541
	port_free(port);
}

542
static void kill_traffic(struct usb_serial_port *port)
543
{
L
Linus Torvalds 已提交
544 545
	usb_kill_urb(port->read_urb);
	usb_kill_urb(port->write_urb);
546 547 548 549 550 551 552 553 554 555 556
	/*
	 * This is tricky.
	 * Some drivers submit the read_urb in the
	 * handler for the write_urb or vice versa
	 * this order determines the order in which
	 * usb_kill_urb() must be used to reliably
	 * kill the URBs. As it is unknown here,
	 * both orders must be used in turn.
	 * The call below is not redundant.
	 */
	usb_kill_urb(port->read_urb);
L
Linus Torvalds 已提交
557 558
	usb_kill_urb(port->interrupt_in_urb);
	usb_kill_urb(port->interrupt_out_urb);
559 560 561 562
}

static void port_free(struct usb_serial_port *port)
{
563 564 565 566
	/*
	 * Stop all the traffic before cancelling the work, so that
	 * nobody will restart it by calling usb_serial_port_softint.
	 */
567
	kill_traffic(port);
568 569
	cancel_work_sync(&port->work);

570 571 572
	usb_free_urb(port->read_urb);
	usb_free_urb(port->write_urb);
	usb_free_urb(port->interrupt_in_urb);
L
Linus Torvalds 已提交
573 574 575 576 577 578 579 580
	usb_free_urb(port->interrupt_out_urb);
	kfree(port->bulk_in_buffer);
	kfree(port->bulk_out_buffer);
	kfree(port->interrupt_in_buffer);
	kfree(port->interrupt_out_buffer);
	kfree(port);
}

A
Alan Cox 已提交
581 582 583
static struct usb_serial *create_serial(struct usb_device *dev,
					struct usb_interface *interface,
					struct usb_serial_driver *driver)
L
Linus Torvalds 已提交
584 585 586
{
	struct usb_serial *serial;

587
	serial = kzalloc(sizeof(*serial), GFP_KERNEL);
L
Linus Torvalds 已提交
588
	if (!serial) {
589
		dev_err(&dev->dev, "%s - out of memory\n", __func__);
L
Linus Torvalds 已提交
590 591 592
		return NULL;
	}
	serial->dev = usb_get_dev(dev);
593
	serial->type = driver;
L
Linus Torvalds 已提交
594 595
	serial->interface = interface;
	kref_init(&serial->kref);
596
	mutex_init(&serial->disc_mutex);
597
	serial->minor = SERIAL_TTY_NO_MINOR;
L
Linus Torvalds 已提交
598 599 600 601

	return serial;
}

602
static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf,
A
Alan Cox 已提交
603
					    struct usb_serial_driver *drv)
604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634
{
	struct usb_dynid *dynid;

	spin_lock(&drv->dynids.lock);
	list_for_each_entry(dynid, &drv->dynids.list, node) {
		if (usb_match_one_id(intf, &dynid->id)) {
			spin_unlock(&drv->dynids.lock);
			return &dynid->id;
		}
	}
	spin_unlock(&drv->dynids.lock);
	return NULL;
}

static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv,
						struct usb_interface *intf)
{
	const struct usb_device_id *id;

	id = usb_match_id(intf, drv->id_table);
	if (id) {
		dbg("static descriptor matches");
		goto exit;
	}
	id = match_dynamic_id(intf, drv);
	if (id)
		dbg("dynamic descriptor matches");
exit:
	return id;
}

A
Alan Cox 已提交
635 636
static struct usb_serial_driver *search_serial_device(
					struct usb_interface *iface)
L
Linus Torvalds 已提交
637 638
{
	const struct usb_device_id *id;
639
	struct usb_serial_driver *drv;
L
Linus Torvalds 已提交
640

A
Adrian Bunk 已提交
641
	/* Check if the usb id matches a known device */
642 643
	list_for_each_entry(drv, &usb_serial_driver_list, driver_list) {
		id = get_iface_id(drv, iface);
644
		if (id)
645
			return drv;
L
Linus Torvalds 已提交
646 647 648 649 650 651 652 653
	}

	return NULL;
}

int usb_serial_probe(struct usb_interface *interface,
			       const struct usb_device_id *id)
{
A
Alan Cox 已提交
654
	struct usb_device *dev = interface_to_usbdev(interface);
L
Linus Torvalds 已提交
655 656 657 658 659 660 661 662
	struct usb_serial *serial = NULL;
	struct usb_serial_port *port;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
	struct usb_endpoint_descriptor *interrupt_out_endpoint[MAX_NUM_PORTS];
	struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];
	struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];
663
	struct usb_serial_driver *type = NULL;
L
Linus Torvalds 已提交
664
	int retval;
665
	unsigned int minor;
L
Linus Torvalds 已提交
666 667 668 669 670 671 672 673 674
	int buffer_size;
	int i;
	int num_interrupt_in = 0;
	int num_interrupt_out = 0;
	int num_bulk_in = 0;
	int num_bulk_out = 0;
	int num_ports = 0;
	int max_endpoints;

675
	lock_kernel(); /* guard against unloading a serial driver module */
L
Linus Torvalds 已提交
676 677
	type = search_serial_device(interface);
	if (!type) {
678
		unlock_kernel();
L
Linus Torvalds 已提交
679 680 681 682
		dbg("none matched");
		return -ENODEV;
	}

A
Alan Cox 已提交
683
	serial = create_serial(dev, interface, type);
L
Linus Torvalds 已提交
684
	if (!serial) {
685
		unlock_kernel();
686
		dev_err(&interface->dev, "%s - out of memory\n", __func__);
L
Linus Torvalds 已提交
687 688 689 690 691 692 693
		return -ENOMEM;
	}

	/* if this device type has a probe function, call it */
	if (type->probe) {
		const struct usb_device_id *id;

694
		if (!try_module_get(type->driver.owner)) {
695
			unlock_kernel();
A
Alan Cox 已提交
696 697 698
			dev_err(&interface->dev,
				"module get failed, exiting\n");
			kfree(serial);
L
Linus Torvalds 已提交
699 700 701
			return -EIO;
		}

702
		id = get_iface_id(type, interface);
L
Linus Torvalds 已提交
703
		retval = type->probe(serial, id);
704
		module_put(type->driver.owner);
L
Linus Torvalds 已提交
705 706

		if (retval) {
707
			unlock_kernel();
A
Alan Cox 已提交
708 709
			dbg("sub driver rejected device");
			kfree(serial);
L
Linus Torvalds 已提交
710 711 712 713 714 715 716 717 718
			return retval;
		}
	}

	/* descriptor matches, let's find the endpoints needed */
	/* check out the endpoints */
	iface_desc = interface->cur_altsetting;
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;
719 720

		if (usb_endpoint_is_bulk_in(endpoint)) {
L
Linus Torvalds 已提交
721 722 723 724 725 726
			/* we found a bulk in endpoint */
			dbg("found bulk in on endpoint %d", i);
			bulk_in_endpoint[num_bulk_in] = endpoint;
			++num_bulk_in;
		}

727
		if (usb_endpoint_is_bulk_out(endpoint)) {
L
Linus Torvalds 已提交
728 729 730 731 732
			/* we found a bulk out endpoint */
			dbg("found bulk out on endpoint %d", i);
			bulk_out_endpoint[num_bulk_out] = endpoint;
			++num_bulk_out;
		}
733 734

		if (usb_endpoint_is_int_in(endpoint)) {
L
Linus Torvalds 已提交
735 736 737 738 739 740
			/* we found a interrupt in endpoint */
			dbg("found interrupt in on endpoint %d", i);
			interrupt_in_endpoint[num_interrupt_in] = endpoint;
			++num_interrupt_in;
		}

741
		if (usb_endpoint_is_int_out(endpoint)) {
L
Linus Torvalds 已提交
742 743 744 745 746 747 748 749
			/* we found an interrupt out endpoint */
			dbg("found interrupt out on endpoint %d", i);
			interrupt_out_endpoint[num_interrupt_out] = endpoint;
			++num_interrupt_out;
		}
	}

#if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)
A
Alan Cox 已提交
750
	/* BEGIN HORRIBLE HACK FOR PL2303 */
L
Linus Torvalds 已提交
751 752 753 754
	/* this is needed due to the looney way its endpoints are set up */
	if (((le16_to_cpu(dev->descriptor.idVendor) == PL2303_VENDOR_ID) &&
	     (le16_to_cpu(dev->descriptor.idProduct) == PL2303_PRODUCT_ID)) ||
	    ((le16_to_cpu(dev->descriptor.idVendor) == ATEN_VENDOR_ID) &&
755 756
	     (le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID)) ||
	    ((le16_to_cpu(dev->descriptor.idVendor) == ALCOR_VENDOR_ID) &&
757 758 759
	     (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID)) ||
	    ((le16_to_cpu(dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) &&
	     (le16_to_cpu(dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_EF81))) {
L
Linus Torvalds 已提交
760 761 762 763 764
		if (interface != dev->actconfig->interface[0]) {
			/* check out the endpoints of the other interface*/
			iface_desc = dev->actconfig->interface[0]->cur_altsetting;
			for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
				endpoint = &iface_desc->endpoint[i].desc;
765
				if (usb_endpoint_is_int_in(endpoint)) {
L
Linus Torvalds 已提交
766 767 768 769 770 771 772 773 774 775 776 777 778
					/* we found a interrupt in endpoint */
					dbg("found interrupt in for Prolific device on separate interface");
					interrupt_in_endpoint[num_interrupt_in] = endpoint;
					++num_interrupt_in;
				}
			}
		}

		/* Now make sure the PL-2303 is configured correctly.
		 * If not, give up now and hope this hack will work
		 * properly during a later invocation of usb_serial_probe
		 */
		if (num_bulk_in == 0 || num_bulk_out == 0) {
779
			unlock_kernel();
L
Linus Torvalds 已提交
780
			dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n");
A
Alan Cox 已提交
781
			kfree(serial);
L
Linus Torvalds 已提交
782 783 784 785 786 787 788 789 790 791
			return -ENODEV;
		}
	}
	/* END HORRIBLE HACK FOR PL2303 */
#endif

#ifdef CONFIG_USB_SERIAL_GENERIC
	if (type == &usb_serial_generic_device) {
		num_ports = num_bulk_out;
		if (num_ports == 0) {
792
			unlock_kernel();
A
Alan Cox 已提交
793 794 795
			dev_err(&interface->dev,
			    "Generic device with no bulk out, not allowed.\n");
			kfree(serial);
L
Linus Torvalds 已提交
796 797 798 799 800 801 802
			return -EIO;
		}
	}
#endif
	if (!num_ports) {
		/* if this device type has a calc_num_ports function, call it */
		if (type->calc_num_ports) {
803
			if (!try_module_get(type->driver.owner)) {
804
				unlock_kernel();
A
Alan Cox 已提交
805 806 807
				dev_err(&interface->dev,
					"module get failed, exiting\n");
				kfree(serial);
L
Linus Torvalds 已提交
808 809
				return -EIO;
			}
A
Alan Cox 已提交
810
			num_ports = type->calc_num_ports(serial);
811
			module_put(type->driver.owner);
L
Linus Torvalds 已提交
812 813 814 815 816 817 818 819 820 821 822
		}
		if (!num_ports)
			num_ports = type->num_ports;
	}

	serial->num_ports = num_ports;
	serial->num_bulk_in = num_bulk_in;
	serial->num_bulk_out = num_bulk_out;
	serial->num_interrupt_in = num_interrupt_in;
	serial->num_interrupt_out = num_interrupt_out;

823 824 825 826
	/* found all that we need */
	dev_info(&interface->dev, "%s converter detected\n",
			type->description);

L
Linus Torvalds 已提交
827
	/* create our ports, we need as many as the max endpoints */
A
Alan Cox 已提交
828 829
	/* we don't use num_ports here because some devices have more
	   endpoint pairs than ports */
L
Linus Torvalds 已提交
830 831 832 833 834
	max_endpoints = max(num_bulk_in, num_bulk_out);
	max_endpoints = max(max_endpoints, num_interrupt_in);
	max_endpoints = max(max_endpoints, num_interrupt_out);
	max_endpoints = max(max_endpoints, (int)serial->num_ports);
	serial->num_port_pointers = max_endpoints;
835 836
	unlock_kernel();

A
Alan Cox 已提交
837 838
	dbg("%s - setting up %d port structures for this device",
						__func__, max_endpoints);
L
Linus Torvalds 已提交
839
	for (i = 0; i < max_endpoints; ++i) {
840
		port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
L
Linus Torvalds 已提交
841 842
		if (!port)
			goto probe_error;
A
Alan Cox 已提交
843
		tty_port_init(&port->port);
L
Linus Torvalds 已提交
844
		port->serial = serial;
845
		spin_lock_init(&port->lock);
846
		mutex_init(&port->mutex);
D
David Howells 已提交
847
		INIT_WORK(&port->work, usb_serial_port_work);
L
Linus Torvalds 已提交
848 849 850 851 852 853 854
		serial->port[i] = port;
	}

	/* set up the endpoint information */
	for (i = 0; i < num_bulk_in; ++i) {
		endpoint = bulk_in_endpoint[i];
		port = serial->port[i];
A
Alan Cox 已提交
855
		port->read_urb = usb_alloc_urb(0, GFP_KERNEL);
L
Linus Torvalds 已提交
856 857 858 859 860 861 862
		if (!port->read_urb) {
			dev_err(&interface->dev, "No free urbs available\n");
			goto probe_error;
		}
		buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
		port->bulk_in_size = buffer_size;
		port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
A
Alan Cox 已提交
863
		port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
L
Linus Torvalds 已提交
864
		if (!port->bulk_in_buffer) {
A
Alan Cox 已提交
865 866
			dev_err(&interface->dev,
					"Couldn't allocate bulk_in_buffer\n");
L
Linus Torvalds 已提交
867 868
			goto probe_error;
		}
A
Alan Cox 已提交
869 870 871 872 873
		usb_fill_bulk_urb(port->read_urb, dev,
				usb_rcvbulkpipe(dev,
						endpoint->bEndpointAddress),
				port->bulk_in_buffer, buffer_size,
				serial->type->read_bulk_callback, port);
L
Linus Torvalds 已提交
874 875 876 877 878 879 880 881 882 883 884 885 886
	}

	for (i = 0; i < num_bulk_out; ++i) {
		endpoint = bulk_out_endpoint[i];
		port = serial->port[i];
		port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
		if (!port->write_urb) {
			dev_err(&interface->dev, "No free urbs available\n");
			goto probe_error;
		}
		buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
		port->bulk_out_size = buffer_size;
		port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
A
Alan Cox 已提交
887
		port->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
L
Linus Torvalds 已提交
888
		if (!port->bulk_out_buffer) {
A
Alan Cox 已提交
889 890
			dev_err(&interface->dev,
					"Couldn't allocate bulk_out_buffer\n");
L
Linus Torvalds 已提交
891 892
			goto probe_error;
		}
A
Alan Cox 已提交
893 894 895 896 897
		usb_fill_bulk_urb(port->write_urb, dev,
				usb_sndbulkpipe(dev,
					endpoint->bEndpointAddress),
				port->bulk_out_buffer, buffer_size,
				serial->type->write_bulk_callback, port);
L
Linus Torvalds 已提交
898 899 900 901 902 903 904 905
	}

	if (serial->type->read_int_callback) {
		for (i = 0; i < num_interrupt_in; ++i) {
			endpoint = interrupt_in_endpoint[i];
			port = serial->port[i];
			port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
			if (!port->interrupt_in_urb) {
A
Alan Cox 已提交
906 907
				dev_err(&interface->dev,
						"No free urbs available\n");
L
Linus Torvalds 已提交
908 909 910
				goto probe_error;
			}
			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
A
Alan Cox 已提交
911 912 913 914
			port->interrupt_in_endpointAddress =
						endpoint->bEndpointAddress;
			port->interrupt_in_buffer = kmalloc(buffer_size,
								GFP_KERNEL);
L
Linus Torvalds 已提交
915
			if (!port->interrupt_in_buffer) {
A
Alan Cox 已提交
916 917
				dev_err(&interface->dev,
				    "Couldn't allocate interrupt_in_buffer\n");
L
Linus Torvalds 已提交
918 919
				goto probe_error;
			}
A
Alan Cox 已提交
920 921 922 923 924 925
			usb_fill_int_urb(port->interrupt_in_urb, dev,
				usb_rcvintpipe(dev,
						endpoint->bEndpointAddress),
				port->interrupt_in_buffer, buffer_size,
				serial->type->read_int_callback, port,
				endpoint->bInterval);
L
Linus Torvalds 已提交
926 927 928 929
		}
	} else if (num_interrupt_in) {
		dbg("the device claims to support interrupt in transfers, but read_int_callback is not defined");
	}
A
Alan Cox 已提交
930

L
Linus Torvalds 已提交
931 932 933 934 935 936
	if (serial->type->write_int_callback) {
		for (i = 0; i < num_interrupt_out; ++i) {
			endpoint = interrupt_out_endpoint[i];
			port = serial->port[i];
			port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
			if (!port->interrupt_out_urb) {
A
Alan Cox 已提交
937 938
				dev_err(&interface->dev,
						"No free urbs available\n");
L
Linus Torvalds 已提交
939 940 941 942
				goto probe_error;
			}
			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
			port->interrupt_out_size = buffer_size;
A
Alan Cox 已提交
943 944 945 946
			port->interrupt_out_endpointAddress =
						endpoint->bEndpointAddress;
			port->interrupt_out_buffer = kmalloc(buffer_size,
								GFP_KERNEL);
L
Linus Torvalds 已提交
947
			if (!port->interrupt_out_buffer) {
A
Alan Cox 已提交
948 949
				dev_err(&interface->dev,
				  "Couldn't allocate interrupt_out_buffer\n");
L
Linus Torvalds 已提交
950 951
				goto probe_error;
			}
A
Alan Cox 已提交
952 953 954 955 956 957
			usb_fill_int_urb(port->interrupt_out_urb, dev,
				usb_sndintpipe(dev,
						  endpoint->bEndpointAddress),
				port->interrupt_out_buffer, buffer_size,
				serial->type->write_int_callback, port,
				endpoint->bInterval);
L
Linus Torvalds 已提交
958 959 960 961
		}
	} else if (num_interrupt_out) {
		dbg("the device claims to support interrupt out transfers, but write_int_callback is not defined");
	}
A
Alan Cox 已提交
962

L
Linus Torvalds 已提交
963 964
	/* if this device type has an attach function, call it */
	if (type->attach) {
965
		if (!try_module_get(type->driver.owner)) {
A
Alan Cox 已提交
966 967
			dev_err(&interface->dev,
					"module get failed, exiting\n");
L
Linus Torvalds 已提交
968 969
			goto probe_error;
		}
A
Alan Cox 已提交
970
		retval = type->attach(serial);
971
		module_put(type->driver.owner);
L
Linus Torvalds 已提交
972 973 974
		if (retval < 0)
			goto probe_error;
		if (retval > 0) {
A
Alan Cox 已提交
975 976
			/* quietly accept this device, but don't bind to a
			   serial port as it's about to disappear */
977
			serial->num_ports = 0;
L
Linus Torvalds 已提交
978 979 980 981
			goto exit;
		}
	}

A
Alan Cox 已提交
982
	if (get_free_serial(serial, num_ports, &minor) == NULL) {
983 984 985
		dev_err(&interface->dev, "No more free serial devices\n");
		goto probe_error;
	}
986
	serial->minor = minor;
987

L
Linus Torvalds 已提交
988 989 990 991 992 993 994 995
	/* register all of the individual ports with the driver core */
	for (i = 0; i < num_ports; ++i) {
		port = serial->port[i];
		port->dev.parent = &interface->dev;
		port->dev.driver = NULL;
		port->dev.bus = &usb_serial_bus_type;
		port->dev.release = &port_release;

996
		dev_set_name(&port->dev, "ttyUSB%d", port->number);
997
		dbg ("%s - registering %s", __func__, dev_name(&port->dev));
998 999 1000 1001
		retval = device_register(&port->dev);
		if (retval)
			dev_err(&port->dev, "Error registering port device, "
				"continuing\n");
L
Linus Torvalds 已提交
1002 1003
	}

A
Alan Cox 已提交
1004
	usb_serial_console_init(debug, minor);
L
Linus Torvalds 已提交
1005 1006 1007

exit:
	/* success */
A
Alan Cox 已提交
1008
	usb_set_intfdata(interface, serial);
L
Linus Torvalds 已提交
1009 1010 1011 1012 1013 1014 1015
	return 0;

probe_error:
	for (i = 0; i < num_bulk_in; ++i) {
		port = serial->port[i];
		if (!port)
			continue;
1016
		usb_free_urb(port->read_urb);
L
Linus Torvalds 已提交
1017 1018 1019 1020 1021 1022
		kfree(port->bulk_in_buffer);
	}
	for (i = 0; i < num_bulk_out; ++i) {
		port = serial->port[i];
		if (!port)
			continue;
1023
		usb_free_urb(port->write_urb);
L
Linus Torvalds 已提交
1024 1025 1026 1027 1028 1029
		kfree(port->bulk_out_buffer);
	}
	for (i = 0; i < num_interrupt_in; ++i) {
		port = serial->port[i];
		if (!port)
			continue;
1030
		usb_free_urb(port->interrupt_in_urb);
L
Linus Torvalds 已提交
1031 1032 1033 1034 1035 1036
		kfree(port->interrupt_in_buffer);
	}
	for (i = 0; i < num_interrupt_out; ++i) {
		port = serial->port[i];
		if (!port)
			continue;
1037
		usb_free_urb(port->interrupt_out_urb);
L
Linus Torvalds 已提交
1038 1039 1040 1041 1042 1043
		kfree(port->interrupt_out_buffer);
	}

	/* free up any memory that we allocated */
	for (i = 0; i < serial->num_port_pointers; ++i)
		kfree(serial->port[i]);
A
Alan Cox 已提交
1044
	kfree(serial);
L
Linus Torvalds 已提交
1045 1046
	return -EIO;
}
A
Alan Cox 已提交
1047
EXPORT_SYMBOL_GPL(usb_serial_probe);
L
Linus Torvalds 已提交
1048 1049 1050 1051

void usb_serial_disconnect(struct usb_interface *interface)
{
	int i;
A
Alan Cox 已提交
1052
	struct usb_serial *serial = usb_get_intfdata(interface);
L
Linus Torvalds 已提交
1053 1054 1055
	struct device *dev = &interface->dev;
	struct usb_serial_port *port;

1056
	usb_serial_console_disconnect(serial);
A
Alan Cox 已提交
1057
	dbg("%s", __func__);
L
Linus Torvalds 已提交
1058

1059
	mutex_lock(&serial->disc_mutex);
A
Alan Cox 已提交
1060
	usb_set_intfdata(interface, NULL);
1061 1062
	/* must set a flag, to signal subdrivers */
	serial->disconnected = 1;
1063 1064 1065 1066 1067 1068
	mutex_unlock(&serial->disc_mutex);

	/* Unfortunately, many of the sub-drivers expect the port structures
	 * to exist when their shutdown method is called, so we have to go
	 * through this awkward two-step unregistration procedure.
	 */
1069 1070 1071
	for (i = 0; i < serial->num_ports; ++i) {
		port = serial->port[i];
		if (port) {
A
Alan Cox 已提交
1072 1073 1074 1075 1076
			struct tty_struct *tty = tty_port_tty_get(&port->port);
			if (tty) {
				tty_hangup(tty);
				tty_kref_put(tty);
			}
1077
			kill_traffic(port);
1078 1079 1080 1081 1082 1083 1084 1085 1086 1087
			cancel_work_sync(&port->work);
			device_del(&port->dev);
		}
	}
	serial->type->shutdown(serial);
	for (i = 0; i < serial->num_ports; ++i) {
		port = serial->port[i];
		if (port) {
			put_device(&port->dev);
			serial->port[i] = NULL;
L
Linus Torvalds 已提交
1088 1089
		}
	}
1090

1091 1092 1093
	/* let the last holder of this object
	 * cause it to be cleaned up */
	usb_serial_put(serial);
L
Linus Torvalds 已提交
1094 1095
	dev_info(dev, "device disconnected\n");
}
A
Alan Cox 已提交
1096
EXPORT_SYMBOL_GPL(usb_serial_disconnect);
L
Linus Torvalds 已提交
1097

1098 1099 1100 1101 1102 1103
int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct usb_serial *serial = usb_get_intfdata(intf);
	struct usb_serial_port *port;
	int i, r = 0;

1104 1105
	serial->suspending = 1;

1106 1107 1108 1109
	for (i = 0; i < serial->num_ports; ++i) {
		port = serial->port[i];
		if (port)
			kill_traffic(port);
1110 1111 1112
	}

	if (serial->type->suspend)
1113
		r = serial->type->suspend(serial, message);
1114 1115 1116 1117 1118 1119 1120 1121

	return r;
}
EXPORT_SYMBOL(usb_serial_suspend);

int usb_serial_resume(struct usb_interface *intf)
{
	struct usb_serial *serial = usb_get_intfdata(intf);
1122
	int rv;
1123

1124
	serial->suspending = 0;
S
Sarah Sharp 已提交
1125
	if (serial->type->resume)
1126 1127 1128
		rv = serial->type->resume(serial);
	else
		rv = usb_serial_generic_resume(serial);
1129

1130
	return rv;
1131 1132 1133
}
EXPORT_SYMBOL(usb_serial_resume);

J
Jeff Dike 已提交
1134
static const struct tty_operations serial_ops = {
L
Linus Torvalds 已提交
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
	.open =			serial_open,
	.close =		serial_close,
	.write =		serial_write,
	.write_room =		serial_write_room,
	.ioctl =		serial_ioctl,
	.set_termios =		serial_set_termios,
	.throttle =		serial_throttle,
	.unthrottle =		serial_unthrottle,
	.break_ctl =		serial_break,
	.chars_in_buffer =	serial_chars_in_buffer,
	.tiocmget =		serial_tiocmget,
	.tiocmset =		serial_tiocmset,
1147
	.proc_fops =		&serial_proc_fops,
L
Linus Torvalds 已提交
1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161
};

struct tty_driver *usb_serial_tty_driver;

static int __init usb_serial_init(void)
{
	int i;
	int result;

	usb_serial_tty_driver = alloc_tty_driver(SERIAL_TTY_MINORS);
	if (!usb_serial_tty_driver)
		return -ENOMEM;

	/* Initialize our global data */
A
Alan Cox 已提交
1162
	for (i = 0; i < SERIAL_TTY_MINORS; ++i)
L
Linus Torvalds 已提交
1163 1164 1165 1166
		serial_table[i] = NULL;

	result = bus_register(&usb_serial_bus_type);
	if (result) {
1167 1168
		printk(KERN_ERR "usb-serial: %s - registering bus driver "
		       "failed\n", __func__);
L
Linus Torvalds 已提交
1169 1170 1171 1172 1173 1174 1175 1176 1177 1178
		goto exit_bus;
	}

	usb_serial_tty_driver->owner = THIS_MODULE;
	usb_serial_tty_driver->driver_name = "usbserial";
	usb_serial_tty_driver->name = 	"ttyUSB";
	usb_serial_tty_driver->major = SERIAL_TTY_MAJOR;
	usb_serial_tty_driver->minor_start = 0;
	usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
	usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL;
A
Alan Cox 已提交
1179 1180
	usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW |
						TTY_DRIVER_DYNAMIC_DEV;
L
Linus Torvalds 已提交
1181
	usb_serial_tty_driver->init_termios = tty_std_termios;
A
Alan Cox 已提交
1182 1183
	usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD
							| HUPCL | CLOCAL;
1184 1185
	usb_serial_tty_driver->init_termios.c_ispeed = 9600;
	usb_serial_tty_driver->init_termios.c_ospeed = 9600;
L
Linus Torvalds 已提交
1186 1187 1188
	tty_set_operations(usb_serial_tty_driver, &serial_ops);
	result = tty_register_driver(usb_serial_tty_driver);
	if (result) {
1189 1190
		printk(KERN_ERR "usb-serial: %s - tty_register_driver failed\n",
		       __func__);
L
Linus Torvalds 已提交
1191 1192 1193 1194 1195 1196
		goto exit_reg_driver;
	}

	/* register the USB driver */
	result = usb_register(&usb_serial_driver);
	if (result < 0) {
1197 1198
		printk(KERN_ERR "usb-serial: %s - usb_register failed\n",
		       __func__);
L
Linus Torvalds 已提交
1199 1200 1201
		goto exit_tty;
	}

1202 1203 1204
	/* register the generic driver, if we should */
	result = usb_serial_generic_register(debug);
	if (result < 0) {
1205 1206
		printk(KERN_ERR "usb-serial: %s - registering generic "
		       "driver failed\n", __func__);
1207 1208 1209
		goto exit_generic;
	}

1210
	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
L
Linus Torvalds 已提交
1211 1212 1213

	return result;

1214 1215 1216
exit_generic:
	usb_deregister(&usb_serial_driver);

L
Linus Torvalds 已提交
1217 1218 1219 1220 1221 1222 1223
exit_tty:
	tty_unregister_driver(usb_serial_tty_driver);

exit_reg_driver:
	bus_unregister(&usb_serial_bus_type);

exit_bus:
1224 1225
	printk(KERN_ERR "usb-serial: %s - returning with error %d\n",
	       __func__, result);
L
Linus Torvalds 已提交
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251
	put_tty_driver(usb_serial_tty_driver);
	return result;
}


static void __exit usb_serial_exit(void)
{
	usb_serial_console_exit();

	usb_serial_generic_deregister();

	usb_deregister(&usb_serial_driver);
	tty_unregister_driver(usb_serial_tty_driver);
	put_tty_driver(usb_serial_tty_driver);
	bus_unregister(&usb_serial_bus_type);
}


module_init(usb_serial_init);
module_exit(usb_serial_exit);

#define set_to_generic_if_null(type, function)				\
	do {								\
		if (!type->function) {					\
			type->function = usb_serial_generic_##function;	\
			dbg("Had to override the " #function		\
A
Alan Cox 已提交
1252
				" usb serial operation with the generic one.");\
L
Linus Torvalds 已提交
1253 1254 1255
			}						\
	} while (0)

1256
static void fixup_generic(struct usb_serial_driver *device)
L
Linus Torvalds 已提交
1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267
{
	set_to_generic_if_null(device, open);
	set_to_generic_if_null(device, write);
	set_to_generic_if_null(device, close);
	set_to_generic_if_null(device, write_room);
	set_to_generic_if_null(device, chars_in_buffer);
	set_to_generic_if_null(device, read_bulk_callback);
	set_to_generic_if_null(device, write_bulk_callback);
	set_to_generic_if_null(device, shutdown);
}

A
Alan Cox 已提交
1268
int usb_serial_register(struct usb_serial_driver *driver)
L
Linus Torvalds 已提交
1269
{
A
Alan Cox 已提交
1270
	/* must be called with BKL held */
L
Linus Torvalds 已提交
1271 1272
	int retval;

1273 1274 1275
	if (usb_disabled())
		return -ENODEV;

1276
	fixup_generic(driver);
L
Linus Torvalds 已提交
1277

1278 1279 1280
	if (!driver->description)
		driver->description = driver->driver.name;

L
Linus Torvalds 已提交
1281
	/* Add this device to our list of devices */
1282
	list_add(&driver->driver_list, &usb_serial_driver_list);
L
Linus Torvalds 已提交
1283

1284
	retval = usb_serial_bus_register(driver);
L
Linus Torvalds 已提交
1285
	if (retval) {
1286 1287
		printk(KERN_ERR "usb-serial: problem %d when registering "
		       "driver %s\n", retval, driver->description);
1288
		list_del(&driver->driver_list);
A
Alan Cox 已提交
1289
	} else
1290
		printk(KERN_INFO "USB Serial support registered for %s\n",
A
Alan Cox 已提交
1291
						driver->description);
L
Linus Torvalds 已提交
1292 1293 1294

	return retval;
}
A
Alan Cox 已提交
1295
EXPORT_SYMBOL_GPL(usb_serial_register);
L
Linus Torvalds 已提交
1296 1297


A
Alan Cox 已提交
1298
void usb_serial_deregister(struct usb_serial_driver *device)
L
Linus Torvalds 已提交
1299
{
A
Alan Cox 已提交
1300
	/* must be called with BKL held */
1301 1302
	printk(KERN_INFO "USB Serial deregistering driver %s\n",
	       device->description);
L
Linus Torvalds 已提交
1303 1304 1305 1306 1307 1308
	list_del(&device->driver_list);
	usb_serial_bus_deregister(device);
}
EXPORT_SYMBOL_GPL(usb_serial_deregister);

/* Module information */
A
Alan Cox 已提交
1309 1310
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
L
Linus Torvalds 已提交
1311 1312 1313 1314
MODULE_LICENSE("GPL");

module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");