/*
* USB Serial Converter driver
*
* Copyright (C) 1999 - 2005 Greg Kroah-Hartman (greg@kroah.com)
* 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.
*
* This driver was originally based on the ACM driver by Armin Fuerst (which was
* based on a driver by Brad Keryan)
*
* See Documentation/usb/usb-serial.txt for more information on using this
* driver
*
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/smp_lock.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/seq_file.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/uaccess.h>
#include <linux/serial.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include <linux/kfifo.h>
#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"
/* 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,
.suspend = usb_serial_suspend,
.resume = usb_serial_resume,
.no_dynamic_id = 1,
};
/* 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;
/* initially all NULL */
static struct usb_serial *serial_table[SERIAL_TTY_MINORS];
static DEFINE_MUTEX(table_lock);
static LIST_HEAD(usb_serial_driver_list);
/*
* Look up the serial structure. If it is found and it hasn't been
* disconnected, return with its disc_mutex held and its refcount
* incremented. Otherwise return NULL.
*/
struct usb_serial *usb_serial_get_by_index(unsigned index)
{
struct usb_serial *serial;
mutex_lock(&table_lock);
serial = serial_table[index];
if (serial) {
mutex_lock(&serial->disc_mutex);
if (serial->disconnected) {
mutex_unlock(&serial->disc_mutex);
serial = NULL;
}