usb-serial.c 33.4 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 29
 *
 */

#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>
#include <linux/spinlock.h>
30
#include <linux/mutex.h>
L
Linus Torvalds 已提交
31
#include <linux/list.h>
A
Alan Cox 已提交
32
#include <linux/uaccess.h>
L
Linus Torvalds 已提交
33
#include <linux/usb.h>
34
#include <linux/usb/serial.h>
L
Linus Torvalds 已提交
35 36 37 38 39 40 41 42
#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"

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

L
Linus Torvalds 已提交
45 46 47 48 49
/* 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,
50 51
	.suspend =	usb_serial_suspend,
	.resume =	usb_serial_resume,
52
	.no_dynamic_id = 	1,
L
Linus Torvalds 已提交
53 54 55 56 57 58 59 60 61 62
};

/* 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 已提交
63 64
/* initially all NULL */
static struct usb_serial *serial_table[SERIAL_TTY_MINORS];
65
static DEFINE_MUTEX(table_lock);
L
Linus Torvalds 已提交
66 67 68 69
static LIST_HEAD(usb_serial_driver_list);

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

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

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

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

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

	*minor = 0;
90
	mutex_lock(&table_lock);
L
Linus Torvalds 已提交
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
	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;
106
		j = 0;
107
		dbg("%s - minor base = %d", __func__, *minor);
108
		for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) {
L
Linus Torvalds 已提交
109
			serial_table[i] = serial;
110 111
			serial->port[j++]->number = i;
		}
112
		mutex_unlock(&table_lock);
L
Linus Torvalds 已提交
113 114
		return serial;
	}
115
	mutex_unlock(&table_lock);
L
Linus Torvalds 已提交
116 117 118 119 120 121 122
	return NULL;
}

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

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

	if (serial == NULL)
		return;

A
Alan Cox 已提交
128
	for (i = 0; i < serial->num_ports; ++i)
L
Linus Torvalds 已提交
129 130 131 132 133 134 135 136 137 138 139
		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);

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

142 143 144 145 146
	serial->type->shutdown(serial);

	/* return the minor range that this device had */
	return_serial(serial);

L
Linus Torvalds 已提交
147
	for (i = 0; i < serial->num_ports; ++i)
A
Alan Cox 已提交
148
		serial->port[i]->port.count = 0;
L
Linus Torvalds 已提交
149 150 151 152 153 154 155 156 157 158 159 160

	/* the ports are cleaned up and released in port_release() */
	for (i = 0; i < serial->num_ports; ++i)
		if (serial->port[i]->dev.parent != NULL) {
			device_unregister(&serial->port[i]->dev);
			serial->port[i] = NULL;
		}

	/* 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 已提交
161 162
		for (i = serial->num_ports;
					i < serial->num_port_pointers; ++i) {
L
Linus Torvalds 已提交
163 164 165
			port = serial->port[i];
			if (!port)
				continue;
166
			port_free(port);
L
Linus Torvalds 已提交
167 168 169 170 171 172
		}
	}

	usb_put_dev(serial->dev);

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

176 177
void usb_serial_put(struct usb_serial *serial)
{
178
	mutex_lock(&table_lock);
179
	kref_put(&serial->kref, destroy_serial);
180
	mutex_unlock(&table_lock);
181 182
}

L
Linus Torvalds 已提交
183 184 185
/*****************************************************************************
 * Driver tty interface functions
 *****************************************************************************/
A
Alan Cox 已提交
186
static int serial_open (struct tty_struct *tty, struct file *filp)
L
Linus Torvalds 已提交
187 188 189 190 191
{
	struct usb_serial *serial;
	struct usb_serial_port *port;
	unsigned int portNumber;
	int retval;
A
Alan Cox 已提交
192

193
	dbg("%s", __func__);
L
Linus Torvalds 已提交
194 195 196 197 198 199 200 201 202 203

	/* 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;
	}

	portNumber = tty->index - serial->minor;
	port = serial->port[portNumber];
204 205 206 207
	if (!port) {
		retval = -ENODEV;
		goto bailout_kref_put;
	}
208

209 210 211 212
	if (mutex_lock_interruptible(&port->mutex)) {
		retval = -ERESTARTSYS;
		goto bailout_kref_put;
	}
A
Alan Cox 已提交
213

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

216 217 218
	/* set up our port structure making the tty driver
	 * remember our port object, and us it */
	tty->driver_data = port;
A
Alan Cox 已提交
219
	port->port.tty = tty;
L
Linus Torvalds 已提交
220

A
Alan Cox 已提交
221
	if (port->port.count == 1) {
L
Linus Torvalds 已提交
222 223 224 225

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

231 232 233
		retval = usb_autopm_get_interface(serial->interface);
		if (retval)
			goto bailout_module_put;
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;
L
Linus Torvalds 已提交
239 240
	}

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

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

A
Alan Cox 已提交
258
static void serial_close(struct tty_struct *tty, struct file *filp)
L
Linus Torvalds 已提交
259
{
260
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
261 262 263 264

	if (!port)
		return;

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

267
	mutex_lock(&port->mutex);
268

A
Alan Cox 已提交
269
	if (port->port.count == 0) {
270
		mutex_unlock(&port->mutex);
271 272
		return;
	}
L
Linus Torvalds 已提交
273

A
Alan Cox 已提交
274 275
	--port->port.count;
	if (port->port.count == 0)
A
Alan Cox 已提交
276
		/* only call the device specific close if this
L
Linus Torvalds 已提交
277
		 * port is being closed by the last owner */
A
Alan Cox 已提交
278
		port->serial->type->close(tty, port, filp);
L
Linus Torvalds 已提交
279

A
Alan Cox 已提交
280 281 282 283 284
	if (port->port.count == (port->console? 1 : 0)) {
		if (port->port.tty) {
			if (port->port.tty->driver_data)
				port->port.tty->driver_data = NULL;
			port->port.tty = NULL;
L
Linus Torvalds 已提交
285
		}
286
	}
L
Linus Torvalds 已提交
287

A
Alan Cox 已提交
288
	if (port->port.count == 0) {
289 290 291 292
		mutex_lock(&port->serial->disc_mutex);
		if (!port->serial->disconnected)
			usb_autopm_put_interface(port->serial->interface);
		mutex_unlock(&port->serial->disc_mutex);
293
		module_put(port->serial->type->driver.owner);
294
	}
L
Linus Torvalds 已提交
295

296
	mutex_unlock(&port->mutex);
297
	usb_serial_put(port->serial);
L
Linus Torvalds 已提交
298 299
}

A
Alan Cox 已提交
300 301
static int serial_write(struct tty_struct *tty, const unsigned char *buf,
								int count)
L
Linus Torvalds 已提交
302
{
303
	struct usb_serial_port *port = tty->driver_data;
304
	int retval = -ENODEV;
L
Linus Torvalds 已提交
305

A
Alan Cox 已提交
306
	if (port->serial->dev->state == USB_STATE_NOTATTACHED)
307 308
		goto exit;

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

A
Alan Cox 已提交
311
	/* count is managed under the mutex lock for the tty so cannot
A
Alan Cox 已提交
312
	   drop to zero until after the last close completes */
A
Alan Cox 已提交
313
	WARN_ON(!port->port.count);
L
Linus Torvalds 已提交
314 315

	/* pass on to the driver specific version of this function */
A
Alan Cox 已提交
316
	retval = port->serial->type->write(tty, port, buf, count);
L
Linus Torvalds 已提交
317 318 319 320 321

exit:
	return retval;
}

A
Alan Cox 已提交
322
static int serial_write_room(struct tty_struct *tty)
L
Linus Torvalds 已提交
323
{
324
	struct usb_serial_port *port = tty->driver_data;
325
	dbg("%s - port %d", __func__, port->number);
A
Alan Cox 已提交
326
	WARN_ON(!port->port.count);
L
Linus Torvalds 已提交
327
	/* pass on to the driver specific version of this function */
A
Alan Cox 已提交
328
	return port->serial->type->write_room(tty);
L
Linus Torvalds 已提交
329 330
}

A
Alan Cox 已提交
331
static int serial_chars_in_buffer(struct tty_struct *tty)
L
Linus Torvalds 已提交
332
{
333
	struct usb_serial_port *port = tty->driver_data;
334
	dbg("%s = port %d", __func__, port->number);
L
Linus Torvalds 已提交
335

A
Alan Cox 已提交
336
	WARN_ON(!port->port.count);
L
Linus Torvalds 已提交
337
	/* pass on to the driver specific version of this function */
A
Alan Cox 已提交
338
	return port->serial->type->chars_in_buffer(tty);
L
Linus Torvalds 已提交
339 340
}

A
Alan Cox 已提交
341
static void serial_throttle(struct tty_struct *tty)
L
Linus Torvalds 已提交
342
{
343
	struct usb_serial_port *port = tty->driver_data;
344
	dbg("%s - port %d", __func__, port->number);
L
Linus Torvalds 已提交
345

A
Alan Cox 已提交
346
	WARN_ON(!port->port.count);
L
Linus Torvalds 已提交
347 348
	/* pass on to the driver specific version of this function */
	if (port->serial->type->throttle)
A
Alan Cox 已提交
349
		port->serial->type->throttle(tty);
L
Linus Torvalds 已提交
350 351
}

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

A
Alan Cox 已提交
357
	WARN_ON(!port->port.count);
L
Linus Torvalds 已提交
358 359
	/* pass on to the driver specific version of this function */
	if (port->serial->type->unthrottle)
A
Alan Cox 已提交
360
		port->serial->type->unthrottle(tty);
L
Linus Torvalds 已提交
361 362
}

A
Alan Cox 已提交
363 364
static int serial_ioctl(struct tty_struct *tty, struct file *file,
					unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
365
{
366
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
367 368
	int retval = -ENODEV;

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

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

A
Alan Cox 已提交
373 374
	/* pass on to the driver specific version of this function
	   if it is available */
A
Alan Cox 已提交
375 376
	if (port->serial->type->ioctl) {
		lock_kernel();
A
Alan Cox 已提交
377
		retval = port->serial->type->ioctl(tty, file, cmd, arg);
A
Alan Cox 已提交
378
		unlock_kernel();
A
Alan Cox 已提交
379
	} else
L
Linus Torvalds 已提交
380 381 382 383
		retval = -ENOIOCTLCMD;
	return retval;
}

A
Alan Cox 已提交
384
static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
L
Linus Torvalds 已提交
385
{
386
	struct usb_serial_port *port = tty->driver_data;
387
	dbg("%s - port %d", __func__, port->number);
L
Linus Torvalds 已提交
388

A
Alan Cox 已提交
389
	WARN_ON(!port->port.count);
A
Alan Cox 已提交
390 391
	/* pass on to the driver specific version of this function
	   if it is available */
L
Linus Torvalds 已提交
392
	if (port->serial->type->set_termios)
A
Alan Cox 已提交
393
		port->serial->type->set_termios(tty, port, old);
394 395
	else
		tty_termios_copy_hw(tty->termios, old);
L
Linus Torvalds 已提交
396 397
}

A
Alan Cox 已提交
398
static int serial_break(struct tty_struct *tty, int break_state)
L
Linus Torvalds 已提交
399
{
400
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
401

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

A
Alan Cox 已提交
404
	WARN_ON(!port->port.count);
A
Alan Cox 已提交
405 406
	/* pass on to the driver specific version of this function
	   if it is available */
A
Alan Cox 已提交
407 408
	if (port->serial->type->break_ctl) {
		lock_kernel();
A
Alan Cox 已提交
409
		port->serial->type->break_ctl(tty, break_state);
A
Alan Cox 已提交
410 411
		unlock_kernel();
	}
A
Alan Cox 已提交
412
	return 0;
L
Linus Torvalds 已提交
413 414
}

A
Alan Cox 已提交
415 416
static int serial_read_proc(char *page, char **start, off_t off, int count,
							int *eof, void *data)
L
Linus Torvalds 已提交
417 418 419 420 421 422 423
{
	struct usb_serial *serial;
	int length = 0;
	int i;
	off_t begin = 0;
	char tmp[40];

424
	dbg("%s", __func__);
A
Alan Cox 已提交
425
	length += sprintf(page, "usbserinfo:1.0 driver:2.0\n");
L
Linus Torvalds 已提交
426 427 428 429 430
	for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) {
		serial = usb_serial_get_by_index(i);
		if (serial == NULL)
			continue;

A
Alan Cox 已提交
431
		length += sprintf(page+length, "%d:", i);
432
		if (serial->type->driver.owner)
A
Alan Cox 已提交
433 434 435 436 437 438 439 440 441 442 443
			length += sprintf(page+length, " module:%s",
				module_name(serial->type->driver.owner));
		length += sprintf(page+length, " name:\"%s\"",
				serial->type->description);
		length += sprintf(page+length, " vendor:%04x product:%04x",
			le16_to_cpu(serial->dev->descriptor.idVendor),
			le16_to_cpu(serial->dev->descriptor.idProduct));
		length += sprintf(page+length, " num_ports:%d",
							serial->num_ports);
		length += sprintf(page+length, " port:%d",
							i - serial->minor + 1);
L
Linus Torvalds 已提交
444
		usb_make_path(serial->dev, tmp, sizeof(tmp));
A
Alan Cox 已提交
445 446 447
		length += sprintf(page+length, " path:%s", tmp);

		length += sprintf(page+length, "\n");
448 449
		if ((length + begin) > (off + count)) {
			usb_serial_put(serial);
L
Linus Torvalds 已提交
450
			goto done;
451
		}
L
Linus Torvalds 已提交
452 453 454 455
		if ((length + begin) < off) {
			begin += length;
			length = 0;
		}
456
		usb_serial_put(serial);
L
Linus Torvalds 已提交
457 458 459 460 461 462
	}
	*eof = 1;
done:
	if (off >= (length + begin))
		return 0;
	*start = page + (off-begin);
A
Alan Cox 已提交
463
	return (count < begin+length-off) ? count : begin+length-off;
L
Linus Torvalds 已提交
464 465
}

A
Alan Cox 已提交
466
static int serial_tiocmget(struct tty_struct *tty, struct file *file)
L
Linus Torvalds 已提交
467
{
468
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
469

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

A
Alan Cox 已提交
472
	WARN_ON(!port->port.count);
L
Linus Torvalds 已提交
473
	if (port->serial->type->tiocmget)
A
Alan Cox 已提交
474
		return port->serial->type->tiocmget(tty, file);
L
Linus Torvalds 已提交
475 476 477
	return -EINVAL;
}

A
Alan Cox 已提交
478
static int serial_tiocmset(struct tty_struct *tty, struct file *file,
L
Linus Torvalds 已提交
479 480
			    unsigned int set, unsigned int clear)
{
481
	struct usb_serial_port *port = tty->driver_data;
L
Linus Torvalds 已提交
482

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

A
Alan Cox 已提交
485
	WARN_ON(!port->port.count);
L
Linus Torvalds 已提交
486
	if (port->serial->type->tiocmset)
A
Alan Cox 已提交
487
		return port->serial->type->tiocmset(tty, file, set, clear);
L
Linus Torvalds 已提交
488 489 490
	return -EINVAL;
}

491 492 493 494 495 496 497 498 499
/*
 * 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 已提交
500
EXPORT_SYMBOL_GPL(usb_serial_port_softint);
501

502
static void usb_serial_port_work(struct work_struct *work)
L
Linus Torvalds 已提交
503
{
504 505
	struct usb_serial_port *port =
		container_of(work, struct usb_serial_port, work);
L
Linus Torvalds 已提交
506 507
	struct tty_struct *tty;

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

L
Linus Torvalds 已提交
510 511 512
	if (!port)
		return;

A
Alan Cox 已提交
513
	tty = port->port.tty;
L
Linus Torvalds 已提交
514 515 516 517 518 519 520 521 522 523
	if (!tty)
		return;

	tty_wakeup(tty);
}

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

524
	dbg ("%s - %s", __func__, dev_name(dev));
525 526 527
	port_free(port);
}

528
static void kill_traffic(struct usb_serial_port *port)
529
{
L
Linus Torvalds 已提交
530 531
	usb_kill_urb(port->read_urb);
	usb_kill_urb(port->write_urb);
532 533 534 535 536 537 538 539 540 541 542
	/*
	 * 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 已提交
543 544
	usb_kill_urb(port->interrupt_in_urb);
	usb_kill_urb(port->interrupt_out_urb);
545 546 547 548 549 550 551 552
}

static void port_free(struct usb_serial_port *port)
{
	kill_traffic(port);
	usb_free_urb(port->read_urb);
	usb_free_urb(port->write_urb);
	usb_free_urb(port->interrupt_in_urb);
L
Linus Torvalds 已提交
553 554 555 556 557
	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);
558
	flush_scheduled_work();		/* port->work */
L
Linus Torvalds 已提交
559 560 561
	kfree(port);
}

A
Alan Cox 已提交
562 563 564
static struct usb_serial *create_serial(struct usb_device *dev,
					struct usb_interface *interface,
					struct usb_serial_driver *driver)
L
Linus Torvalds 已提交
565 566 567
{
	struct usb_serial *serial;

568
	serial = kzalloc(sizeof(*serial), GFP_KERNEL);
L
Linus Torvalds 已提交
569
	if (!serial) {
570
		dev_err(&dev->dev, "%s - out of memory\n", __func__);
L
Linus Torvalds 已提交
571 572 573
		return NULL;
	}
	serial->dev = usb_get_dev(dev);
574
	serial->type = driver;
L
Linus Torvalds 已提交
575 576
	serial->interface = interface;
	kref_init(&serial->kref);
577
	mutex_init(&serial->disc_mutex);
L
Linus Torvalds 已提交
578 579 580 581

	return serial;
}

582
static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf,
A
Alan Cox 已提交
583
					    struct usb_serial_driver *drv)
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614
{
	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 已提交
615 616
static struct usb_serial_driver *search_serial_device(
					struct usb_interface *iface)
L
Linus Torvalds 已提交
617 618
{
	const struct usb_device_id *id;
619
	struct usb_serial_driver *drv;
L
Linus Torvalds 已提交
620

A
Adrian Bunk 已提交
621
	/* Check if the usb id matches a known device */
622 623
	list_for_each_entry(drv, &usb_serial_driver_list, driver_list) {
		id = get_iface_id(drv, iface);
624
		if (id)
625
			return drv;
L
Linus Torvalds 已提交
626 627 628 629 630 631 632 633
	}

	return NULL;
}

int usb_serial_probe(struct usb_interface *interface,
			       const struct usb_device_id *id)
{
A
Alan Cox 已提交
634
	struct usb_device *dev = interface_to_usbdev(interface);
L
Linus Torvalds 已提交
635 636 637 638 639 640 641 642
	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];
643
	struct usb_serial_driver *type = NULL;
L
Linus Torvalds 已提交
644
	int retval;
645
	unsigned int minor;
L
Linus Torvalds 已提交
646 647 648 649 650 651 652 653 654
	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;

655
	lock_kernel(); /* guard against unloading a serial driver module */
L
Linus Torvalds 已提交
656 657
	type = search_serial_device(interface);
	if (!type) {
658
		unlock_kernel();
L
Linus Torvalds 已提交
659 660 661 662
		dbg("none matched");
		return -ENODEV;
	}

A
Alan Cox 已提交
663
	serial = create_serial(dev, interface, type);
L
Linus Torvalds 已提交
664
	if (!serial) {
665
		unlock_kernel();
666
		dev_err(&interface->dev, "%s - out of memory\n", __func__);
L
Linus Torvalds 已提交
667 668 669 670 671 672 673
		return -ENOMEM;
	}

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

674
		if (!try_module_get(type->driver.owner)) {
675
			unlock_kernel();
A
Alan Cox 已提交
676 677 678
			dev_err(&interface->dev,
				"module get failed, exiting\n");
			kfree(serial);
L
Linus Torvalds 已提交
679 680 681
			return -EIO;
		}

682
		id = get_iface_id(type, interface);
L
Linus Torvalds 已提交
683
		retval = type->probe(serial, id);
684
		module_put(type->driver.owner);
L
Linus Torvalds 已提交
685 686

		if (retval) {
687
			unlock_kernel();
A
Alan Cox 已提交
688 689
			dbg("sub driver rejected device");
			kfree(serial);
L
Linus Torvalds 已提交
690 691 692 693 694 695 696 697 698
			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;
699 700

		if (usb_endpoint_is_bulk_in(endpoint)) {
L
Linus Torvalds 已提交
701 702 703 704 705 706
			/* we found a bulk in endpoint */
			dbg("found bulk in on endpoint %d", i);
			bulk_in_endpoint[num_bulk_in] = endpoint;
			++num_bulk_in;
		}

707
		if (usb_endpoint_is_bulk_out(endpoint)) {
L
Linus Torvalds 已提交
708 709 710 711 712
			/* we found a bulk out endpoint */
			dbg("found bulk out on endpoint %d", i);
			bulk_out_endpoint[num_bulk_out] = endpoint;
			++num_bulk_out;
		}
713 714

		if (usb_endpoint_is_int_in(endpoint)) {
L
Linus Torvalds 已提交
715 716 717 718 719 720
			/* we found a interrupt in endpoint */
			dbg("found interrupt in on endpoint %d", i);
			interrupt_in_endpoint[num_interrupt_in] = endpoint;
			++num_interrupt_in;
		}

721
		if (usb_endpoint_is_int_out(endpoint)) {
L
Linus Torvalds 已提交
722 723 724 725 726 727 728 729
			/* 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 已提交
730
	/* BEGIN HORRIBLE HACK FOR PL2303 */
L
Linus Torvalds 已提交
731 732 733 734
	/* 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) &&
735 736 737
	     (le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID)) ||
	    ((le16_to_cpu(dev->descriptor.idVendor) == ALCOR_VENDOR_ID) &&
	     (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID))) {
L
Linus Torvalds 已提交
738 739 740 741 742
		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;
743
				if (usb_endpoint_is_int_in(endpoint)) {
L
Linus Torvalds 已提交
744 745 746 747 748 749 750 751 752 753 754 755 756
					/* 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) {
757
			unlock_kernel();
L
Linus Torvalds 已提交
758
			dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n");
A
Alan Cox 已提交
759
			kfree(serial);
L
Linus Torvalds 已提交
760 761 762 763 764 765 766 767 768 769
			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) {
770
			unlock_kernel();
A
Alan Cox 已提交
771 772 773
			dev_err(&interface->dev,
			    "Generic device with no bulk out, not allowed.\n");
			kfree(serial);
L
Linus Torvalds 已提交
774 775 776 777 778 779 780
			return -EIO;
		}
	}
#endif
	if (!num_ports) {
		/* if this device type has a calc_num_ports function, call it */
		if (type->calc_num_ports) {
781
			if (!try_module_get(type->driver.owner)) {
782
				unlock_kernel();
A
Alan Cox 已提交
783 784 785
				dev_err(&interface->dev,
					"module get failed, exiting\n");
				kfree(serial);
L
Linus Torvalds 已提交
786 787
				return -EIO;
			}
A
Alan Cox 已提交
788
			num_ports = type->calc_num_ports(serial);
789
			module_put(type->driver.owner);
L
Linus Torvalds 已提交
790 791 792 793 794 795 796 797 798 799 800
		}
		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;

801 802 803 804
	/* found all that we need */
	dev_info(&interface->dev, "%s converter detected\n",
			type->description);

L
Linus Torvalds 已提交
805
	/* create our ports, we need as many as the max endpoints */
A
Alan Cox 已提交
806 807
	/* we don't use num_ports here because some devices have more
	   endpoint pairs than ports */
L
Linus Torvalds 已提交
808 809 810 811 812
	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;
813 814
	unlock_kernel();

A
Alan Cox 已提交
815 816
	dbg("%s - setting up %d port structures for this device",
						__func__, max_endpoints);
L
Linus Torvalds 已提交
817
	for (i = 0; i < max_endpoints; ++i) {
818
		port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
L
Linus Torvalds 已提交
819 820 821
		if (!port)
			goto probe_error;
		port->serial = serial;
822
		spin_lock_init(&port->lock);
823
		mutex_init(&port->mutex);
824
		INIT_WORK(&port->work, usb_serial_port_work);
L
Linus Torvalds 已提交
825 826 827 828 829 830 831
		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 已提交
832
		port->read_urb = usb_alloc_urb(0, GFP_KERNEL);
L
Linus Torvalds 已提交
833 834 835 836 837 838 839
		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 已提交
840
		port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
L
Linus Torvalds 已提交
841
		if (!port->bulk_in_buffer) {
A
Alan Cox 已提交
842 843
			dev_err(&interface->dev,
					"Couldn't allocate bulk_in_buffer\n");
L
Linus Torvalds 已提交
844 845
			goto probe_error;
		}
A
Alan Cox 已提交
846 847 848 849 850
		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 已提交
851 852 853 854 855 856 857 858 859 860 861 862 863
	}

	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 已提交
864
		port->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
L
Linus Torvalds 已提交
865
		if (!port->bulk_out_buffer) {
A
Alan Cox 已提交
866 867
			dev_err(&interface->dev,
					"Couldn't allocate bulk_out_buffer\n");
L
Linus Torvalds 已提交
868 869
			goto probe_error;
		}
A
Alan Cox 已提交
870 871 872 873 874
		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 已提交
875 876 877 878 879 880 881 882
	}

	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 已提交
883 884
				dev_err(&interface->dev,
						"No free urbs available\n");
L
Linus Torvalds 已提交
885 886 887
				goto probe_error;
			}
			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
A
Alan Cox 已提交
888 889 890 891
			port->interrupt_in_endpointAddress =
						endpoint->bEndpointAddress;
			port->interrupt_in_buffer = kmalloc(buffer_size,
								GFP_KERNEL);
L
Linus Torvalds 已提交
892
			if (!port->interrupt_in_buffer) {
A
Alan Cox 已提交
893 894
				dev_err(&interface->dev,
				    "Couldn't allocate interrupt_in_buffer\n");
L
Linus Torvalds 已提交
895 896
				goto probe_error;
			}
A
Alan Cox 已提交
897 898 899 900 901 902
			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 已提交
903 904 905 906
		}
	} else if (num_interrupt_in) {
		dbg("the device claims to support interrupt in transfers, but read_int_callback is not defined");
	}
A
Alan Cox 已提交
907

L
Linus Torvalds 已提交
908 909 910 911 912 913
	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 已提交
914 915
				dev_err(&interface->dev,
						"No free urbs available\n");
L
Linus Torvalds 已提交
916 917 918 919
				goto probe_error;
			}
			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
			port->interrupt_out_size = buffer_size;
A
Alan Cox 已提交
920 921 922 923
			port->interrupt_out_endpointAddress =
						endpoint->bEndpointAddress;
			port->interrupt_out_buffer = kmalloc(buffer_size,
								GFP_KERNEL);
L
Linus Torvalds 已提交
924
			if (!port->interrupt_out_buffer) {
A
Alan Cox 已提交
925 926
				dev_err(&interface->dev,
				  "Couldn't allocate interrupt_out_buffer\n");
L
Linus Torvalds 已提交
927 928
				goto probe_error;
			}
A
Alan Cox 已提交
929 930 931 932 933 934
			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 已提交
935 936 937 938
		}
	} else if (num_interrupt_out) {
		dbg("the device claims to support interrupt out transfers, but write_int_callback is not defined");
	}
A
Alan Cox 已提交
939

L
Linus Torvalds 已提交
940 941
	/* if this device type has an attach function, call it */
	if (type->attach) {
942
		if (!try_module_get(type->driver.owner)) {
A
Alan Cox 已提交
943 944
			dev_err(&interface->dev,
					"module get failed, exiting\n");
L
Linus Torvalds 已提交
945 946
			goto probe_error;
		}
A
Alan Cox 已提交
947
		retval = type->attach(serial);
948
		module_put(type->driver.owner);
L
Linus Torvalds 已提交
949 950 951
		if (retval < 0)
			goto probe_error;
		if (retval > 0) {
A
Alan Cox 已提交
952 953
			/* quietly accept this device, but don't bind to a
			   serial port as it's about to disappear */
L
Linus Torvalds 已提交
954 955 956 957
			goto exit;
		}
	}

A
Alan Cox 已提交
958
	if (get_free_serial(serial, num_ports, &minor) == NULL) {
959 960 961
		dev_err(&interface->dev, "No more free serial devices\n");
		goto probe_error;
	}
962
	serial->minor = minor;
963

L
Linus Torvalds 已提交
964 965 966 967 968 969 970 971
	/* 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;

972
		dev_set_name(&port->dev, "ttyUSB%d", port->number);
973
		dbg ("%s - registering %s", __func__, dev_name(&port->dev));
974 975 976 977
		retval = device_register(&port->dev);
		if (retval)
			dev_err(&port->dev, "Error registering port device, "
				"continuing\n");
L
Linus Torvalds 已提交
978 979
	}

A
Alan Cox 已提交
980
	usb_serial_console_init(debug, minor);
L
Linus Torvalds 已提交
981 982 983

exit:
	/* success */
A
Alan Cox 已提交
984
	usb_set_intfdata(interface, serial);
L
Linus Torvalds 已提交
985 986 987 988 989 990 991
	return 0;

probe_error:
	for (i = 0; i < num_bulk_in; ++i) {
		port = serial->port[i];
		if (!port)
			continue;
992
		usb_free_urb(port->read_urb);
L
Linus Torvalds 已提交
993 994 995 996 997 998
		kfree(port->bulk_in_buffer);
	}
	for (i = 0; i < num_bulk_out; ++i) {
		port = serial->port[i];
		if (!port)
			continue;
999
		usb_free_urb(port->write_urb);
L
Linus Torvalds 已提交
1000 1001 1002 1003 1004 1005
		kfree(port->bulk_out_buffer);
	}
	for (i = 0; i < num_interrupt_in; ++i) {
		port = serial->port[i];
		if (!port)
			continue;
1006
		usb_free_urb(port->interrupt_in_urb);
L
Linus Torvalds 已提交
1007 1008 1009 1010 1011 1012
		kfree(port->interrupt_in_buffer);
	}
	for (i = 0; i < num_interrupt_out; ++i) {
		port = serial->port[i];
		if (!port)
			continue;
1013
		usb_free_urb(port->interrupt_out_urb);
L
Linus Torvalds 已提交
1014 1015 1016 1017 1018 1019
		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 已提交
1020
	kfree(serial);
L
Linus Torvalds 已提交
1021 1022
	return -EIO;
}
A
Alan Cox 已提交
1023
EXPORT_SYMBOL_GPL(usb_serial_probe);
L
Linus Torvalds 已提交
1024 1025 1026 1027

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

1032
	usb_serial_console_disconnect(serial);
A
Alan Cox 已提交
1033
	dbg("%s", __func__);
L
Linus Torvalds 已提交
1034

1035
	mutex_lock(&serial->disc_mutex);
A
Alan Cox 已提交
1036
	usb_set_intfdata(interface, NULL);
1037 1038 1039 1040 1041
	/* must set a flag, to signal subdrivers */
	serial->disconnected = 1;
	for (i = 0; i < serial->num_ports; ++i) {
		port = serial->port[i];
		if (port) {
A
Alan Cox 已提交
1042 1043
			if (port->port.tty)
				tty_hangup(port->port.tty);
1044
			kill_traffic(port);
L
Linus Torvalds 已提交
1045 1046
		}
	}
1047 1048 1049 1050
	/* let the last holder of this object
	 * cause it to be cleaned up */
	mutex_unlock(&serial->disc_mutex);
	usb_serial_put(serial);
L
Linus Torvalds 已提交
1051 1052
	dev_info(dev, "device disconnected\n");
}
A
Alan Cox 已提交
1053
EXPORT_SYMBOL_GPL(usb_serial_disconnect);
L
Linus Torvalds 已提交
1054

1055 1056 1057 1058 1059 1060
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;

1061 1062 1063 1064
	for (i = 0; i < serial->num_ports; ++i) {
		port = serial->port[i];
		if (port)
			kill_traffic(port);
1065 1066 1067
	}

	if (serial->type->suspend)
1068
		r = serial->type->suspend(serial, message);
1069 1070 1071 1072 1073 1074 1075 1076 1077

	return r;
}
EXPORT_SYMBOL(usb_serial_suspend);

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

1078 1079 1080
	if (serial->type->resume)
		return serial->type->resume(serial);
	return 0;
1081 1082 1083
}
EXPORT_SYMBOL(usb_serial_resume);

1084
static const struct tty_operations serial_ops = {
L
Linus Torvalds 已提交
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111
	.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,
	.read_proc =		serial_read_proc,
	.tiocmget =		serial_tiocmget,
	.tiocmset =		serial_tiocmset,
};

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 已提交
1112
	for (i = 0; i < SERIAL_TTY_MINORS; ++i)
L
Linus Torvalds 已提交
1113 1114 1115 1116
		serial_table[i] = NULL;

	result = bus_register(&usb_serial_bus_type);
	if (result) {
1117
		err("%s - registering bus driver failed", __func__);
L
Linus Torvalds 已提交
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127
		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 已提交
1128 1129
	usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW |
						TTY_DRIVER_DYNAMIC_DEV;
L
Linus Torvalds 已提交
1130
	usb_serial_tty_driver->init_termios = tty_std_termios;
A
Alan Cox 已提交
1131 1132
	usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD
							| HUPCL | CLOCAL;
1133 1134
	usb_serial_tty_driver->init_termios.c_ispeed = 9600;
	usb_serial_tty_driver->init_termios.c_ospeed = 9600;
L
Linus Torvalds 已提交
1135 1136 1137
	tty_set_operations(usb_serial_tty_driver, &serial_ops);
	result = tty_register_driver(usb_serial_tty_driver);
	if (result) {
1138
		err("%s - tty_register_driver failed", __func__);
L
Linus Torvalds 已提交
1139 1140 1141 1142 1143 1144
		goto exit_reg_driver;
	}

	/* register the USB driver */
	result = usb_register(&usb_serial_driver);
	if (result < 0) {
1145
		err("%s - usb_register failed", __func__);
L
Linus Torvalds 已提交
1146 1147 1148
		goto exit_tty;
	}

1149 1150 1151
	/* register the generic driver, if we should */
	result = usb_serial_generic_register(debug);
	if (result < 0) {
1152
		err("%s - registering generic driver failed", __func__);
1153 1154 1155
		goto exit_generic;
	}

1156
	info(DRIVER_DESC);
L
Linus Torvalds 已提交
1157 1158 1159

	return result;

1160 1161 1162
exit_generic:
	usb_deregister(&usb_serial_driver);

L
Linus Torvalds 已提交
1163 1164 1165 1166 1167 1168 1169
exit_tty:
	tty_unregister_driver(usb_serial_tty_driver);

exit_reg_driver:
	bus_unregister(&usb_serial_bus_type);

exit_bus:
A
Alan Cox 已提交
1170
	err("%s - returning with error %d", __func__, result);
L
Linus Torvalds 已提交
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196
	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 已提交
1197
				" usb serial operation with the generic one.");\
L
Linus Torvalds 已提交
1198 1199 1200
			}						\
	} while (0)

1201
static void fixup_generic(struct usb_serial_driver *device)
L
Linus Torvalds 已提交
1202 1203 1204 1205 1206 1207 1208 1209 1210
{
	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);
1211
	set_to_generic_if_null(device, resume);
L
Linus Torvalds 已提交
1212 1213
}

A
Alan Cox 已提交
1214
int usb_serial_register(struct usb_serial_driver *driver)
L
Linus Torvalds 已提交
1215
{
A
Alan Cox 已提交
1216
	/* must be called with BKL held */
L
Linus Torvalds 已提交
1217 1218
	int retval;

1219
	fixup_generic(driver);
L
Linus Torvalds 已提交
1220

1221 1222 1223
	if (!driver->description)
		driver->description = driver->driver.name;

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

1227
	retval = usb_serial_bus_register(driver);
L
Linus Torvalds 已提交
1228
	if (retval) {
A
Alan Cox 已提交
1229 1230
		err("problem %d when registering driver %s",
						retval, driver->description);
1231
		list_del(&driver->driver_list);
A
Alan Cox 已提交
1232 1233 1234
	} else
		info("USB Serial support registered for %s",
						driver->description);
L
Linus Torvalds 已提交
1235 1236 1237

	return retval;
}
A
Alan Cox 已提交
1238
EXPORT_SYMBOL_GPL(usb_serial_register);
L
Linus Torvalds 已提交
1239 1240


A
Alan Cox 已提交
1241
void usb_serial_deregister(struct usb_serial_driver *device)
L
Linus Torvalds 已提交
1242
{
A
Alan Cox 已提交
1243
	/* must be called with BKL held */
1244
	info("USB Serial deregistering driver %s", device->description);
L
Linus Torvalds 已提交
1245 1246 1247 1248 1249 1250
	list_del(&device->driver_list);
	usb_serial_bus_deregister(device);
}
EXPORT_SYMBOL_GPL(usb_serial_deregister);

/* Module information */
A
Alan Cox 已提交
1251 1252
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
L
Linus Torvalds 已提交
1253 1254 1255 1256
MODULE_LICENSE("GPL");

module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
新手
引导
客服 返回
顶部