Commit 7e25c20d authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'usb-serial-5.13-rc1' of...

Merge tag 'usb-serial-5.13-rc1' of https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial into usb-next

Johan writes:

USB-serial updates for 5.13-rc1

Here are the USB-serial updates for 5.13-rc1, including:

 - better type detection for pl2303
 - support for more line speeds for pl2303 (TA/TB)
 - fixed CSIZE handling for the new xr driver
 - core support for multi-interface functions
 - TIOCGSERIAL and TIOCSSERIAL fixes
 - generic TIOCSSERIAL support (e.g. for closing_wait)
 - fixed return value for unsupported ioctls
 - support for gpio valid masks in cp210x
 - drain-delay fixes and improvements
 - support for multi-port devices for xr
 - generalisation of the xr driver to support three new device classes
   (XR21B142X, XR21B1411 and XR2280X)

Included are also various clean ups.

All have been in linux-next with no reported issues.

* tag 'usb-serial-5.13-rc1' of https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial: (72 commits)
  USB: cdc-acm: add more Maxlinear/Exar models to ignore list
  USB: serial: xr: add copyright notice
  USB: serial: xr: reset FIFOs on open
  USB: serial: xr: add support for XR22801, XR22802, XR22804
  USB: serial: xr: add support for XR21B1411
  USB: serial: xr: add support for XR21B1421, XR21B1422 and XR21B1424
  USB: serial: xr: add type abstraction
  USB: serial: xr: drop type prefix from shared defines
  USB: serial: xr: move pin configuration to probe
  USB: serial: xr: rename GPIO-pin defines
  USB: serial: xr: rename GPIO-mode defines
  USB: serial: xr: add support for XR21V1412 and XR21V1414
  USB: serial: ti_usb_3410_5052: clean up termios CSIZE handling
  USB: serial: ti_usb_3410_5052: use kernel types consistently
  USB: serial: ti_usb_3410_5052: add port-command helpers
  USB: serial: ti_usb_3410_5052: clean up vendor-request helpers
  USB: serial: ti_usb_3410_5052: drop unnecessary packed attributes
  USB: serial: io_ti: drop unnecessary packed attributes
  USB: serial: io_ti: use kernel types consistently
  USB: serial: io_ti: add read-port-command helper
  ...
parents 3232a3ce 039b81d5
......@@ -1913,9 +1913,17 @@ static const struct usb_device_id acm_ids[] = {
#endif
#if IS_ENABLED(CONFIG_USB_SERIAL_XR)
{ USB_DEVICE(0x04e2, 0x1410), /* Ignore XR21V141X USB to Serial converter */
.driver_info = IGNORE_DEVICE,
},
{ USB_DEVICE(0x04e2, 0x1400), .driver_info = IGNORE_DEVICE },
{ USB_DEVICE(0x04e2, 0x1401), .driver_info = IGNORE_DEVICE },
{ USB_DEVICE(0x04e2, 0x1402), .driver_info = IGNORE_DEVICE },
{ USB_DEVICE(0x04e2, 0x1403), .driver_info = IGNORE_DEVICE },
{ USB_DEVICE(0x04e2, 0x1410), .driver_info = IGNORE_DEVICE },
{ USB_DEVICE(0x04e2, 0x1411), .driver_info = IGNORE_DEVICE },
{ USB_DEVICE(0x04e2, 0x1412), .driver_info = IGNORE_DEVICE },
{ USB_DEVICE(0x04e2, 0x1414), .driver_info = IGNORE_DEVICE },
{ USB_DEVICE(0x04e2, 0x1420), .driver_info = IGNORE_DEVICE },
{ USB_DEVICE(0x04e2, 0x1422), .driver_info = IGNORE_DEVICE },
{ USB_DEVICE(0x04e2, 0x1424), .driver_info = IGNORE_DEVICE },
#endif
/*Samsung phone in firmware update mode */
......
......@@ -385,18 +385,6 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
return result;
}
static int ark3116_get_serial_info(struct tty_struct *tty,
struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
ss->type = PORT_16654;
ss->line = port->minor;
ss->port = port->port_number;
ss->baud_base = 460800;
return 0;
}
static int ark3116_tiocmget(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
......@@ -633,7 +621,6 @@ static struct usb_serial_driver ark3116_device = {
.port_probe = ark3116_port_probe,
.port_remove = ark3116_port_remove,
.set_termios = ark3116_set_termios,
.get_serial = ark3116_get_serial_info,
.tiocmget = ark3116_tiocmget,
.tiocmset = ark3116_tiocmset,
.tiocmiwait = usb_serial_generic_tiocmiwait,
......
......@@ -1410,17 +1410,6 @@ static void cp210x_break_ctl(struct tty_struct *tty, int break_state)
}
#ifdef CONFIG_GPIOLIB
static int cp210x_gpio_request(struct gpio_chip *gc, unsigned int offset)
{
struct usb_serial *serial = gpiochip_get_data(gc);
struct cp210x_serial_private *priv = usb_get_serial_data(serial);
if (priv->gpio_altfunc & BIT(offset))
return -ENODEV;
return 0;
}
static int cp210x_gpio_get(struct gpio_chip *gc, unsigned int gpio)
{
struct usb_serial *serial = gpiochip_get_data(gc);
......@@ -1549,6 +1538,24 @@ static int cp210x_gpio_set_config(struct gpio_chip *gc, unsigned int gpio,
return -ENOTSUPP;
}
static int cp210x_gpio_init_valid_mask(struct gpio_chip *gc,
unsigned long *valid_mask, unsigned int ngpios)
{
struct usb_serial *serial = gpiochip_get_data(gc);
struct cp210x_serial_private *priv = usb_get_serial_data(serial);
struct device *dev = &serial->interface->dev;
unsigned long altfunc_mask = priv->gpio_altfunc;
bitmap_complement(valid_mask, &altfunc_mask, ngpios);
if (bitmap_empty(valid_mask, ngpios))
dev_dbg(dev, "no pin configured for GPIO\n");
else
dev_dbg(dev, "GPIO.%*pbl configured for GPIO\n", ngpios,
valid_mask);
return 0;
}
/*
* This function is for configuring GPIO using shared pins, where other signals
* are made unavailable by configuring the use of GPIO. This is believed to be
......@@ -1786,13 +1793,13 @@ static int cp210x_gpio_init(struct usb_serial *serial)
return result;
priv->gc.label = "cp210x";
priv->gc.request = cp210x_gpio_request;
priv->gc.get_direction = cp210x_gpio_direction_get;
priv->gc.direction_input = cp210x_gpio_direction_input;
priv->gc.direction_output = cp210x_gpio_direction_output;
priv->gc.get = cp210x_gpio_get;
priv->gc.set = cp210x_gpio_set;
priv->gc.set_config = cp210x_gpio_set_config;
priv->gc.init_valid_mask = cp210x_gpio_init_valid_mask;
priv->gc.owner = THIS_MODULE;
priv->gc.parent = &serial->interface->dev;
priv->gc.base = -1;
......
......@@ -820,17 +820,12 @@ static int f81232_carrier_raised(struct usb_serial_port *port)
return 0;
}
static int f81232_get_serial_info(struct tty_struct *tty,
struct serial_struct *ss)
static void f81232_get_serial(struct tty_struct *tty, struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
struct f81232_private *priv = usb_get_serial_port_data(port);
ss->type = PORT_16550A;
ss->line = port->minor;
ss->port = port->port_number;
ss->baud_base = priv->baud_base;
return 0;
}
static void f81232_interrupt_work(struct work_struct *work)
......@@ -953,7 +948,6 @@ static int f81232_port_probe(struct usb_serial_port *port)
usb_set_serial_port_data(port, priv);
port->port.drain_delay = 256;
priv->port = port;
return 0;
......@@ -1021,7 +1015,7 @@ static struct usb_serial_driver f81232_device = {
.close = f81232_close,
.dtr_rts = f81232_dtr_rts,
.carrier_raised = f81232_carrier_raised,
.get_serial = f81232_get_serial_info,
.get_serial = f81232_get_serial,
.break_ctl = f81232_break_ctl,
.set_termios = f81232_set_termios,
.tiocmget = f81232_tiocmget,
......@@ -1046,7 +1040,7 @@ static struct usb_serial_driver f81534a_device = {
.close = f81232_close,
.dtr_rts = f81232_dtr_rts,
.carrier_raised = f81232_carrier_raised,
.get_serial = f81232_get_serial_info,
.get_serial = f81232_get_serial,
.break_ctl = f81232_break_ctl,
.set_termios = f81232_set_termios,
.tiocmget = f81232_tiocmget,
......
......@@ -1140,19 +1140,14 @@ static void f81534_close(struct usb_serial_port *port)
mutex_unlock(&serial_priv->urb_mutex);
}
static int f81534_get_serial_info(struct tty_struct *tty,
struct serial_struct *ss)
static void f81534_get_serial_info(struct tty_struct *tty, struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
struct f81534_port_private *port_priv;
port_priv = usb_get_serial_port_data(port);
ss->type = PORT_16550A;
ss->port = port->port_number;
ss->line = port->minor;
ss->baud_base = port_priv->baud_base;
return 0;
}
static void f81534_process_per_serial_block(struct usb_serial_port *port,
......
......@@ -1082,8 +1082,7 @@ static int ftdi_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear);
static int ftdi_ioctl(struct tty_struct *tty,
unsigned int cmd, unsigned long arg);
static int get_serial_info(struct tty_struct *tty,
struct serial_struct *ss);
static void get_serial_info(struct tty_struct *tty, struct serial_struct *ss);
static int set_serial_info(struct tty_struct *tty,
struct serial_struct *ss);
static void ftdi_break_ctl(struct tty_struct *tty, int break_state);
......@@ -1477,8 +1476,7 @@ static int read_latency_timer(struct usb_serial_port *port)
return 0;
}
static int get_serial_info(struct tty_struct *tty,
struct serial_struct *ss)
static void get_serial_info(struct tty_struct *tty, struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
struct ftdi_private *priv = usb_get_serial_port_data(port);
......@@ -1486,49 +1484,34 @@ static int get_serial_info(struct tty_struct *tty,
ss->flags = priv->flags;
ss->baud_base = priv->baud_base;
ss->custom_divisor = priv->custom_divisor;
return 0;
}
static int set_serial_info(struct tty_struct *tty,
struct serial_struct *ss)
static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
struct ftdi_private *priv = usb_get_serial_port_data(port);
struct ftdi_private old_priv;
int old_flags, old_divisor;
mutex_lock(&priv->cfg_lock);
old_priv = *priv;
/* Do error checking and permission checking */
if (!capable(CAP_SYS_ADMIN)) {
if ((ss->flags ^ priv->flags) & ~ASYNC_USR_MASK) {
mutex_unlock(&priv->cfg_lock);
return -EPERM;
}
priv->flags = ((priv->flags & ~ASYNC_USR_MASK) |
(ss->flags & ASYNC_USR_MASK));
priv->custom_divisor = ss->custom_divisor;
goto check_and_exit;
}
if (ss->baud_base != priv->baud_base) {
mutex_unlock(&priv->cfg_lock);
return -EINVAL;
}
/* Make the changes - these are privileged changes! */
old_flags = priv->flags;
old_divisor = priv->custom_divisor;
priv->flags = ((priv->flags & ~ASYNC_FLAGS) |
(ss->flags & ASYNC_FLAGS));
priv->flags = ss->flags & ASYNC_FLAGS;
priv->custom_divisor = ss->custom_divisor;
check_and_exit:
write_latency_timer(port);
if ((priv->flags ^ old_priv.flags) & ASYNC_SPD_MASK ||
if ((priv->flags ^ old_flags) & ASYNC_SPD_MASK ||
((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
priv->custom_divisor != old_priv.custom_divisor)) {
priv->custom_divisor != old_divisor)) {
/* warn about deprecation unless clearing */
if (priv->flags & ASYNC_SPD_MASK)
......
......@@ -263,39 +263,9 @@ static const struct divisor_table_entry divisor_table[] = {
static atomic_t CmdUrbs = ATOMIC_INIT(0);
/* local function prototypes */
/* function prototypes */
/* function prototypes for all URB callbacks */
static void edge_interrupt_callback(struct urb *urb);
static void edge_bulk_in_callback(struct urb *urb);
static void edge_bulk_out_data_callback(struct urb *urb);
static void edge_bulk_out_cmd_callback(struct urb *urb);
/* function prototypes for the usbserial callbacks */
static int edge_open(struct tty_struct *tty, struct usb_serial_port *port);
static void edge_close(struct usb_serial_port *port);
static int edge_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
static int edge_write_room(struct tty_struct *tty);
static int edge_chars_in_buffer(struct tty_struct *tty);
static void edge_throttle(struct tty_struct *tty);
static void edge_unthrottle(struct tty_struct *tty);
static void edge_set_termios(struct tty_struct *tty,
struct usb_serial_port *port,
struct ktermios *old_termios);
static int edge_ioctl(struct tty_struct *tty,
unsigned int cmd, unsigned long arg);
static void edge_break(struct tty_struct *tty, int break_state);
static int edge_tiocmget(struct tty_struct *tty);
static int edge_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear);
static int edge_startup(struct usb_serial *serial);
static void edge_disconnect(struct usb_serial *serial);
static void edge_release(struct usb_serial *serial);
static int edge_port_probe(struct usb_serial_port *port);
static void edge_port_remove(struct usb_serial_port *port);
/* function prototypes for all of our local functions */
static void process_rcvd_data(struct edgeport_serial *edge_serial,
unsigned char *buffer, __u16 bufferLength);
......@@ -309,8 +279,6 @@ static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData,
static int send_iosp_ext_cmd(struct edgeport_port *edge_port, __u8 command,
__u8 param);
static int calc_baud_rate_divisor(struct device *dev, int baud_rate, int *divisor);
static int send_cmd_write_baud_rate(struct edgeport_port *edge_port,
int baudRate);
static void change_port_settings(struct tty_struct *tty,
struct edgeport_port *edge_port,
struct ktermios *old_termios);
......@@ -321,19 +289,8 @@ static int write_cmd_usb(struct edgeport_port *edge_port,
static void send_more_port_data(struct edgeport_serial *edge_serial,
struct edgeport_port *edge_port);
static int sram_write(struct usb_serial *serial, __u16 extAddr, __u16 addr,
__u16 length, const __u8 *data);
static int rom_read(struct usb_serial *serial, __u16 extAddr, __u16 addr,
__u16 length, __u8 *data);
static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr,
__u16 length, const __u8 *data);
static void get_manufacturing_desc(struct edgeport_serial *edge_serial);
static void get_boot_desc(struct edgeport_serial *edge_serial);
static void load_application_firmware(struct edgeport_serial *edge_serial);
static void unicode_to_ascii(char *string, int buflen,
__le16 *unicode, int unicode_size);
/* ************************************************************************ */
/* ************************************************************************ */
......@@ -1637,24 +1594,6 @@ static int edge_tiocmget(struct tty_struct *tty)
return result;
}
static int get_serial_info(struct tty_struct *tty,
struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
ss->type = PORT_16550A;
ss->line = edge_port->port->minor;
ss->port = edge_port->port->port_number;
ss->irq = 0;
ss->xmit_fifo_size = edge_port->maxTxCredits;
ss->baud_base = 9600;
ss->close_delay = 5*HZ;
ss->closing_wait = 30*HZ;
return 0;
}
/*****************************************************************************
* SerialIoctl
* this function handles any ioctl calls to the driver
......@@ -3116,7 +3055,6 @@ static struct usb_serial_driver edgeport_2port_device = {
.set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
.tiocmset = edge_tiocmset,
.get_serial = get_serial_info,
.tiocmiwait = usb_serial_generic_tiocmiwait,
.get_icount = usb_serial_generic_get_icount,
.write = edge_write,
......@@ -3152,7 +3090,6 @@ static struct usb_serial_driver edgeport_4port_device = {
.set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
.tiocmset = edge_tiocmset,
.get_serial = get_serial_info,
.tiocmiwait = usb_serial_generic_tiocmiwait,
.get_icount = usb_serial_generic_get_icount,
.write = edge_write,
......@@ -3188,7 +3125,6 @@ static struct usb_serial_driver edgeport_8port_device = {
.set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
.tiocmset = edge_tiocmset,
.get_serial = get_serial_info,
.tiocmiwait = usb_serial_generic_tiocmiwait,
.get_icount = usb_serial_generic_get_icount,
.write = edge_write,
......@@ -3224,7 +3160,6 @@ static struct usb_serial_driver epic_device = {
.set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
.tiocmset = edge_tiocmset,
.get_serial = get_serial_info,
.tiocmiwait = usb_serial_generic_tiocmiwait,
.get_icount = usb_serial_generic_get_icount,
.write = edge_write,
......
......@@ -10,7 +10,6 @@
#if !defined(_IO_EDGEPORT_H_)
#define _IO_EDGEPORT_H_
#define MAX_RS232_PORTS 8 /* Max # of RS-232 ports per device */
/* typedefs that the insideout headers need */
......@@ -21,57 +20,8 @@
#define HIGH8(a) ((unsigned char)((a & 0xff00) >> 8))
#endif
#ifndef __KERNEL__
#define __KERNEL__
#endif
#include "io_usbvend.h"
/* The following table is used to map the USBx port number to
* the device serial number (or physical USB path), */
#define MAX_EDGEPORTS 64
struct comMapper {
char SerialNumber[MAX_SERIALNUMBER_LEN+1]; /* Serial number/usb path */
int numPorts; /* Number of ports */
int Original[MAX_RS232_PORTS]; /* Port numbers set by IOCTL */
int Port[MAX_RS232_PORTS]; /* Actual used port numbers */
};
#define EDGEPORT_CONFIG_DEVICE "/proc/edgeport"
/* /proc/edgeport Interface
* This interface uses read/write/lseek interface to talk to the edgeport driver
* the following read functions are supported: */
#define PROC_GET_MAPPING_TO_PATH 1
#define PROC_GET_COM_ENTRY 2
#define PROC_GET_EDGE_MANUF_DESCRIPTOR 3
#define PROC_GET_BOOT_DESCRIPTOR 4
#define PROC_GET_PRODUCT_INFO 5
#define PROC_GET_STRINGS 6
#define PROC_GET_CURRENT_COM_MAPPING 7
/* The parameters to the lseek() for the read is: */
#define PROC_READ_SETUP(Command, Argument) ((Command) + ((Argument)<<8))
/* the following write functions are supported: */
#define PROC_SET_COM_MAPPING 1
#define PROC_SET_COM_ENTRY 2
/* The following structure is passed to the write */
struct procWrite {
int Command;
union {
struct comMapper Entry;
int ComMappingBasedOnUSBPort; /* Boolean value */
} u;
};
/*
* Product information read from the Edgeport
*/
......@@ -108,22 +58,4 @@ struct edgeport_product_info {
struct edge_compatibility_bits Epic;
};
/*
* Edgeport Stringblock String locations
*/
#define EDGESTRING_MANUFNAME 1 /* Manufacture Name */
#define EDGESTRING_PRODNAME 2 /* Product Name */
#define EDGESTRING_SERIALNUM 3 /* Serial Number */
#define EDGESTRING_ASSEMNUM 4 /* Assembly Number */
#define EDGESTRING_OEMASSEMNUM 5 /* OEM Assembly Number */
#define EDGESTRING_MANUFDATE 6 /* Manufacture Date */
#define EDGESTRING_ORIGSERIALNUM 7 /* Serial Number */
struct string_block {
__u16 NumStrings; /* Number of strings in block */
__u16 Strings[1]; /* Start of string block */
};
#endif
This diff is collapsed.
......@@ -133,15 +133,15 @@
#define UMPD_OEDB2_ADDRESS 0xFF10
struct out_endpoint_desc_block {
__u8 Configuration;
__u8 XBufAddr;
__u8 XByteCount;
__u8 Unused1;
__u8 Unused2;
__u8 YBufAddr;
__u8 YByteCount;
__u8 BufferSize;
} __attribute__((packed));
u8 Configuration;
u8 XBufAddr;
u8 XByteCount;
u8 Unused1;
u8 Unused2;
u8 YBufAddr;
u8 YByteCount;
u8 BufferSize;
};
/*
......@@ -150,16 +150,16 @@ struct out_endpoint_desc_block {
*/
/* UART settings */
struct ump_uart_config {
__u16 wBaudRate; /* Baud rate */
__u16 wFlags; /* Bitmap mask of flags */
__u8 bDataBits; /* 5..8 - data bits per character */
__u8 bParity; /* Parity settings */
__u8 bStopBits; /* Stop bits settings */
u16 wBaudRate; /* Baud rate */
u16 wFlags; /* Bitmap mask of flags */
u8 bDataBits; /* 5..8 - data bits per character */
u8 bParity; /* Parity settings */
u8 bStopBits; /* Stop bits settings */
char cXon; /* XON character */
char cXoff; /* XOFF character */
__u8 bUartMode; /* Will be updated when a user */
u8 bUartMode; /* Will be updated when a user */
/* interface is defined */
} __attribute__((packed));
};
/*
......@@ -168,9 +168,9 @@ struct ump_uart_config {
*/
/* Interrupt packet structure */
struct ump_interrupt {
__u8 bICode; /* Interrupt code (interrupt num) */
__u8 bIInfo; /* Interrupt information */
} __attribute__((packed));
u8 bICode; /* Interrupt code (interrupt num) */
u8 bIInfo; /* Interrupt information */
};
#define TIUMP_GET_PORT_FROM_CODE(c) (((c) >> 6) & 0x01)
......
......@@ -643,7 +643,6 @@ static void iuu_uart_read_callback(struct urb *urb)
struct iuu_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
int status = urb->status;
int error = 0;
int len = 0;
unsigned char *data = urb->transfer_buffer;
priv->poll++;
......@@ -660,12 +659,11 @@ static void iuu_uart_read_callback(struct urb *urb)
if (urb->actual_length > 1) {
dev_dbg(&port->dev, "%s - urb->actual_length = %i\n", __func__,
urb->actual_length);
error = 1;
return;
}
/* if len > 0 call readbuf */
if (len > 0 && error == 0) {
if (len > 0) {
dev_dbg(&port->dev, "%s - call read buf - len to read is %i\n",
__func__, len);
status = iuu_read_buf(port, len);
......
......@@ -41,27 +41,7 @@
#define DRIVER_AUTHOR "Hugh Blemings <hugh@misc.nu"
#define DRIVER_DESC "Keyspan USB to Serial Converter Driver"
/* Function prototypes for Keyspan serial converter */
static int keyspan_open(struct tty_struct *tty, struct usb_serial_port *port);
static void keyspan_close(struct usb_serial_port *port);
static void keyspan_dtr_rts(struct usb_serial_port *port, int on);
static int keyspan_startup(struct usb_serial *serial);
static void keyspan_disconnect(struct usb_serial *serial);
static void keyspan_release(struct usb_serial *serial);
static int keyspan_port_probe(struct usb_serial_port *port);
static void keyspan_port_remove(struct usb_serial_port *port);
static int keyspan_write_room(struct tty_struct *tty);
static int keyspan_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
static void keyspan_send_setup(struct usb_serial_port *port, int reset_port);
static void keyspan_set_termios(struct tty_struct *tty,
struct usb_serial_port *port,
struct ktermios *old);
static void keyspan_break_ctl(struct tty_struct *tty, int break_state);
static int keyspan_tiocmget(struct tty_struct *tty);
static int keyspan_tiocmset(struct tty_struct *tty, unsigned int set,
unsigned int clear);
static int keyspan_fake_startup(struct usb_serial *serial);
static int keyspan_usa19_calc_baud(struct usb_serial_port *port,
u32 baud_rate, u32 baudclk,
......
......@@ -299,7 +299,7 @@ static int metrousb_tiocmset(struct tty_struct *tty,
unsigned long flags = 0;
unsigned long control_state = 0;
dev_dbg(tty->dev, "%s - set=%d, clear=%d\n", __func__, set, clear);
dev_dbg(&port->dev, "%s - set=%d, clear=%d\n", __func__, set, clear);
spin_lock_irqsave(&metro_priv->lock, flags);
control_state = metro_priv->control_state;
......@@ -334,7 +334,7 @@ static void metrousb_unthrottle(struct tty_struct *tty)
/* Submit the urb to read from the port. */
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
if (result)
dev_err(tty->dev,
dev_err(&port->dev,
"failed submitting interrupt in urb error code=%d\n",
result);
}
......
......@@ -1634,23 +1634,6 @@ static int mos7720_tiocmset(struct tty_struct *tty,
return 0;
}
static int get_serial_info(struct tty_struct *tty,
struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
ss->type = PORT_16550A;
ss->line = mos7720_port->port->minor;
ss->port = mos7720_port->port->port_number;
ss->irq = 0;
ss->xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
ss->baud_base = 9600;
ss->close_delay = 5*HZ;
ss->closing_wait = 30*HZ;
return 0;
}
static int mos7720_ioctl(struct tty_struct *tty,
unsigned int cmd, unsigned long arg)
{
......@@ -1790,7 +1773,6 @@ static struct usb_serial_driver moschip7720_2port_driver = {
.ioctl = mos7720_ioctl,
.tiocmget = mos7720_tiocmget,
.tiocmset = mos7720_tiocmset,
.get_serial = get_serial_info,
.set_termios = mos7720_set_termios,
.write = mos7720_write,
.write_room = mos7720_write_room,
......
......@@ -1383,28 +1383,6 @@ static int mos7840_get_lsr_info(struct tty_struct *tty,
return 0;
}
/*****************************************************************************
* mos7840_get_serial_info
* function to get information about serial port
*****************************************************************************/
static int mos7840_get_serial_info(struct tty_struct *tty,
struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
struct moschip_port *mos7840_port = usb_get_serial_port_data(port);
ss->type = PORT_16550A;
ss->line = mos7840_port->port->minor;
ss->port = mos7840_port->port->port_number;
ss->irq = 0;
ss->xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
ss->baud_base = 9600;
ss->close_delay = 5 * HZ;
ss->closing_wait = 30 * HZ;
return 0;
}
/*****************************************************************************
* SerialIoctl
* this function handles any ioctl calls to the driver
......@@ -1783,7 +1761,6 @@ static struct usb_serial_driver moschip7840_4port_device = {
.probe = mos7840_probe,
.attach = mos7840_attach,
.ioctl = mos7840_ioctl,
.get_serial = mos7840_get_serial_info,
.set_termios = mos7840_set_termios,
.break_ctl = mos7840_break,
.tiocmget = mos7840_tiocmget,
......
......@@ -352,23 +352,6 @@ static int opticon_tiocmset(struct tty_struct *tty,
return 0;
}
static int get_serial_info(struct tty_struct *tty,
struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
/* fake emulate a 16550 uart to make userspace code happy */
ss->type = PORT_16550A;
ss->line = port->minor;
ss->port = 0;
ss->irq = 0;
ss->xmit_fifo_size = 1024;
ss->baud_base = 9600;
ss->close_delay = 5*HZ;
ss->closing_wait = 30*HZ;
return 0;
}
static int opticon_port_probe(struct usb_serial_port *port)
{
struct opticon_private *priv;
......@@ -410,7 +393,6 @@ static struct usb_serial_driver opticon_device = {
.chars_in_buffer = opticon_chars_in_buffer,
.throttle = usb_serial_generic_throttle,
.unthrottle = usb_serial_generic_unthrottle,
.get_serial = get_serial_info,
.tiocmget = opticon_tiocmget,
.tiocmset = opticon_tiocmset,
.process_read_urb = opticon_process_read_urb,
......
......@@ -2095,8 +2095,6 @@ static struct usb_serial_driver option_1port_device = {
.chars_in_buffer = usb_wwan_chars_in_buffer,
.tiocmget = usb_wwan_tiocmget,
.tiocmset = usb_wwan_tiocmset,
.get_serial = usb_wwan_get_serial_info,
.set_serial = usb_wwan_set_serial_info,
.attach = option_attach,
.release = option_release,
.port_probe = usb_wwan_port_probe,
......
......@@ -173,17 +173,22 @@ MODULE_DEVICE_TABLE(usb, id_table);
static void pl2303_set_break(struct usb_serial_port *port, bool enable);
enum pl2303_type {
TYPE_01, /* Type 0 and 1 (difference unknown) */
TYPE_HX, /* HX version of the pl2303 chip */
TYPE_HXN, /* HXN version of the pl2303 chip */
TYPE_H,
TYPE_HX,
TYPE_TA,
TYPE_TB,
TYPE_HXD,
TYPE_HXN,
TYPE_COUNT
};
struct pl2303_type_data {
const char *name;
speed_t max_baud_rate;
unsigned long quirks;
unsigned int no_autoxonxoff:1;
unsigned int no_divisors:1;
unsigned int alt_divisors:1;
};
struct pl2303_serial_private {
......@@ -200,15 +205,32 @@ struct pl2303_private {
};
static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = {
[TYPE_01] = {
[TYPE_H] = {
.name = "H",
.max_baud_rate = 1228800,
.quirks = PL2303_QUIRK_LEGACY,
.no_autoxonxoff = true,
},
[TYPE_HX] = {
.name = "HX",
.max_baud_rate = 6000000,
},
[TYPE_TA] = {
.name = "TA",
.max_baud_rate = 6000000,
.alt_divisors = true,
},
[TYPE_TB] = {
.name = "TB",
.max_baud_rate = 12000000,
.alt_divisors = true,
},
[TYPE_HXD] = {
.name = "HXD",
.max_baud_rate = 12000000,
},
[TYPE_HXN] = {
.name = "G",
.max_baud_rate = 12000000,
.no_divisors = true,
},
......@@ -362,42 +384,82 @@ static int pl2303_calc_num_ports(struct usb_serial *serial,
return 1;
}
static bool pl2303_supports_hx_status(struct usb_serial *serial)
{
int ret;
u8 buf;
ret = usb_control_msg_recv(serial->dev, 0, VENDOR_READ_REQUEST,
VENDOR_READ_REQUEST_TYPE, PL2303_READ_TYPE_HX_STATUS,
0, &buf, 1, 100, GFP_KERNEL);
return ret == 0;
}
static int pl2303_detect_type(struct usb_serial *serial)
{
struct usb_device_descriptor *desc = &serial->dev->descriptor;
u16 bcdDevice, bcdUSB;
/*
* Legacy PL2303H, variants 0 and 1 (difference unknown).
*/
if (desc->bDeviceClass == 0x02)
return TYPE_H; /* variant 0 */
if (desc->bMaxPacketSize0 != 0x40) {
if (desc->bDeviceClass == 0x00 || desc->bDeviceClass == 0xff)
return TYPE_H; /* variant 1 */
return TYPE_H; /* variant 0 */
}
bcdDevice = le16_to_cpu(desc->bcdDevice);
bcdUSB = le16_to_cpu(desc->bcdUSB);
switch (bcdDevice) {
case 0x100:
/*
* Assume it's an HXN-type if the device doesn't support the old read
* request value.
*/
if (bcdUSB == 0x200 && !pl2303_supports_hx_status(serial))
return TYPE_HXN;
break;
case 0x300:
if (bcdUSB == 0x200)
return TYPE_TA;
return TYPE_HX;
case 0x400:
return TYPE_HXD;
case 0x500:
return TYPE_TB;
}
dev_err(&serial->interface->dev,
"unknown device type, please report to linux-usb@vger.kernel.org\n");
return -ENODEV;
}
static int pl2303_startup(struct usb_serial *serial)
{
struct pl2303_serial_private *spriv;
enum pl2303_type type = TYPE_01;
enum pl2303_type type;
unsigned char *buf;
int res;
int ret;
ret = pl2303_detect_type(serial);
if (ret < 0)
return ret;
type = ret;
dev_dbg(&serial->interface->dev, "device type: %s\n", pl2303_type_data[type].name);
spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
if (!spriv)
return -ENOMEM;
buf = kmalloc(1, GFP_KERNEL);
if (!buf) {
kfree(spriv);
return -ENOMEM;
}
if (serial->dev->descriptor.bDeviceClass == 0x02)
type = TYPE_01; /* type 0 */
else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40)
type = TYPE_HX;
else if (serial->dev->descriptor.bDeviceClass == 0x00)
type = TYPE_01; /* type 1 */
else if (serial->dev->descriptor.bDeviceClass == 0xFF)
type = TYPE_01; /* type 1 */
dev_dbg(&serial->interface->dev, "device type: %d\n", type);
if (type == TYPE_HX) {
res = usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE,
PL2303_READ_TYPE_HX_STATUS, 0, buf, 1, 100);
if (res != 1)
type = TYPE_HXN;
}
spriv->type = &pl2303_type_data[type];
spriv->quirks = (unsigned long)usb_get_serial_data(serial);
spriv->quirks |= spriv->type->quirks;
......@@ -405,6 +467,12 @@ static int pl2303_startup(struct usb_serial *serial)
usb_set_serial_data(serial, spriv);
if (type != TYPE_HXN) {
buf = kmalloc(1, GFP_KERNEL);
if (!buf) {
kfree(spriv);
return -ENOMEM;
}
pl2303_vendor_read(serial, 0x8484, buf);
pl2303_vendor_write(serial, 0x0404, 0);
pl2303_vendor_read(serial, 0x8484, buf);
......@@ -419,9 +487,9 @@ static int pl2303_startup(struct usb_serial *serial)
pl2303_vendor_write(serial, 2, 0x24);
else
pl2303_vendor_write(serial, 2, 0x44);
}
kfree(buf);
kfree(buf);
}
return 0;
}
......@@ -553,6 +621,45 @@ static speed_t pl2303_encode_baud_rate_divisor(unsigned char buf[4],
return baud;
}
static speed_t pl2303_encode_baud_rate_divisor_alt(unsigned char buf[4],
speed_t baud)
{
unsigned int baseline, mantissa, exponent;
/*
* Apparently, for the TA version the formula is:
* baudrate = 12M * 32 / (mantissa * 2^exponent)
* where
* mantissa = buf[10:0]
* exponent = buf[15:13 16]
*/
baseline = 12000000 * 32;
mantissa = baseline / baud;
if (mantissa == 0)
mantissa = 1; /* Avoid dividing by zero if baud > 32*12M. */
exponent = 0;
while (mantissa >= 2048) {
if (exponent < 15) {
mantissa >>= 1; /* divide by 2 */
exponent++;
} else {
/* Exponent is maxed. Trim mantissa and leave. */
mantissa = 2047;
break;
}
}
buf[3] = 0x80;
buf[2] = exponent & 0x01;
buf[1] = (exponent & ~0x01) << 4 | mantissa >> 8;
buf[0] = mantissa & 0xff;
/* Calculate and return the exact baud rate. */
baud = (baseline / mantissa) >> exponent;
return baud;
}
static void pl2303_encode_baud_rate(struct tty_struct *tty,
struct usb_serial_port *port,
u8 buf[4])
......@@ -580,6 +687,8 @@ static void pl2303_encode_baud_rate(struct tty_struct *tty,
if (baud == baud_sup)
baud = pl2303_encode_baud_rate_direct(buf, baud);
else if (spriv->type->alt_divisors)
baud = pl2303_encode_baud_rate_divisor_alt(buf, baud);
else
baud = pl2303_encode_baud_rate_divisor(buf, baud);
......@@ -939,18 +1048,6 @@ static int pl2303_carrier_raised(struct usb_serial_port *port)
return 0;
}
static int pl2303_get_serial(struct tty_struct *tty,
struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
ss->type = PORT_16654;
ss->line = port->minor;
ss->port = port->port_number;
ss->baud_base = 460800;
return 0;
}
static void pl2303_set_break(struct usb_serial_port *port, bool enable)
{
struct usb_serial *serial = port->serial;
......@@ -1134,7 +1231,6 @@ static struct usb_serial_driver pl2303_device = {
.close = pl2303_close,
.dtr_rts = pl2303_dtr_rts,
.carrier_raised = pl2303_carrier_raised,
.get_serial = pl2303_get_serial,
.break_ctl = pl2303_break_ctl,
.set_termios = pl2303_set_termios,
.tiocmget = pl2303_tiocmget,
......
......@@ -453,21 +453,6 @@ static void qt2_disconnect(struct usb_serial *serial)
usb_kill_urb(serial_priv->read_urb);
}
static int get_serial_info(struct tty_struct *tty,
struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
ss->line = port->minor;
ss->port = 0;
ss->irq = 0;
ss->xmit_fifo_size = port->bulk_out_size;
ss->baud_base = 9600;
ss->close_delay = 5*HZ;
ss->closing_wait = 30*HZ;
return 0;
}
static void qt2_process_status(struct usb_serial_port *port, unsigned char *ch)
{
switch (*ch) {
......@@ -978,7 +963,6 @@ static struct usb_serial_driver qt2_device = {
.tiocmset = qt2_tiocmset,
.tiocmiwait = usb_serial_generic_tiocmiwait,
.get_icount = usb_serial_generic_get_icount,
.get_serial = get_serial_info,
.set_termios = qt2_set_termios,
};
......
......@@ -331,21 +331,6 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port)
return usb_serial_generic_open(tty, port);
}
static int get_serial_info(struct tty_struct *tty,
struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
ss->line = port->minor;
ss->port = 0;
ss->irq = 0;
ss->xmit_fifo_size = port->bulk_out_size;
ss->baud_base = 9600;
ss->close_delay = 5*HZ;
ss->closing_wait = 30*HZ;
return 0;
}
static int ssu100_attach(struct usb_serial *serial)
{
return ssu100_initdevice(serial->dev);
......@@ -545,7 +530,6 @@ static struct usb_serial_driver ssu100_device = {
.tiocmset = ssu100_tiocmset,
.tiocmiwait = usb_serial_generic_tiocmiwait,
.get_icount = usb_serial_generic_get_icount,
.get_serial = get_serial_info,
.set_termios = ssu100_set_termios,
};
......
This diff is collapsed.
......@@ -182,7 +182,6 @@ static void upd78f0730_port_remove(struct usb_serial_port *port)
static int upd78f0730_tiocmget(struct tty_struct *tty)
{
struct device *dev = tty->dev;
struct upd78f0730_port_private *private;
struct usb_serial_port *port = tty->driver_data;
int signals;
......@@ -197,7 +196,7 @@ static int upd78f0730_tiocmget(struct tty_struct *tty)
res = ((signals & UPD78F0730_DTR) ? TIOCM_DTR : 0) |
((signals & UPD78F0730_RTS) ? TIOCM_RTS : 0);
dev_dbg(dev, "%s - res = %x\n", __func__, res);
dev_dbg(&port->dev, "%s - res = %x\n", __func__, res);
return res;
}
......@@ -205,10 +204,10 @@ static int upd78f0730_tiocmget(struct tty_struct *tty)
static int upd78f0730_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear)
{
struct device *dev = tty->dev;
struct usb_serial_port *port = tty->driver_data;
struct upd78f0730_port_private *private;
struct upd78f0730_set_dtr_rts request;
struct device *dev = &port->dev;
int res;
private = usb_get_serial_port_data(port);
......@@ -241,10 +240,10 @@ static int upd78f0730_tiocmset(struct tty_struct *tty,
static void upd78f0730_break_ctl(struct tty_struct *tty, int break_state)
{
struct device *dev = tty->dev;
struct upd78f0730_port_private *private;
struct usb_serial_port *port = tty->driver_data;
struct upd78f0730_set_dtr_rts request;
struct device *dev = &port->dev;
private = usb_get_serial_port_data(port);
......
This diff is collapsed.
......@@ -15,10 +15,6 @@ extern int usb_wwan_write_room(struct tty_struct *tty);
extern int usb_wwan_tiocmget(struct tty_struct *tty);
extern int usb_wwan_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear);
extern int usb_wwan_get_serial_info(struct tty_struct *tty,
struct serial_struct *ss);
extern int usb_wwan_set_serial_info(struct tty_struct *tty,
struct serial_struct *ss);
extern int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
extern int usb_wwan_chars_in_buffer(struct tty_struct *tty);
......
......@@ -132,51 +132,6 @@ int usb_wwan_tiocmset(struct tty_struct *tty,
}
EXPORT_SYMBOL(usb_wwan_tiocmset);
int usb_wwan_get_serial_info(struct tty_struct *tty,
struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
ss->line = port->minor;
ss->port = port->port_number;
ss->baud_base = tty_get_baud_rate(port->port.tty);
ss->close_delay = port->port.close_delay / 10;
ss->closing_wait = port->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
ASYNC_CLOSING_WAIT_NONE :
port->port.closing_wait / 10;
return 0;
}
EXPORT_SYMBOL(usb_wwan_get_serial_info);
int usb_wwan_set_serial_info(struct tty_struct *tty,
struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
unsigned int closing_wait, close_delay;
int retval = 0;
close_delay = ss->close_delay * 10;
closing_wait = ss->closing_wait == ASYNC_CLOSING_WAIT_NONE ?
ASYNC_CLOSING_WAIT_NONE : ss->closing_wait * 10;
mutex_lock(&port->port.mutex);
if (!capable(CAP_SYS_ADMIN)) {
if ((close_delay != port->port.close_delay) ||
(closing_wait != port->port.closing_wait))
retval = -EPERM;
else
retval = -EOPNOTSUPP;
} else {
port->port.close_delay = close_delay;
port->port.closing_wait = closing_wait;
}
mutex_unlock(&port->port.mutex);
return retval;
}
EXPORT_SYMBOL(usb_wwan_set_serial_info);
int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count)
{
......
......@@ -83,7 +83,7 @@ static void whiteheat_port_remove(struct usb_serial_port *port);
static int whiteheat_open(struct tty_struct *tty,
struct usb_serial_port *port);
static void whiteheat_close(struct usb_serial_port *port);
static int whiteheat_get_serial(struct tty_struct *tty,
static void whiteheat_get_serial(struct tty_struct *tty,
struct serial_struct *ss);
static void whiteheat_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old);
......@@ -170,7 +170,6 @@ static int firm_report_tx_done(struct usb_serial_port *port);
#define COMMAND_PORT 4
#define COMMAND_TIMEOUT (2*HZ) /* 2 second timeout for a command */
#define COMMAND_TIMEOUT_MS 2000
#define CLOSING_DELAY (30 * HZ)
/*****************************************************************************
......@@ -440,21 +439,9 @@ static int whiteheat_tiocmset(struct tty_struct *tty,
}
static int whiteheat_get_serial(struct tty_struct *tty,
struct serial_struct *ss)
static void whiteheat_get_serial(struct tty_struct *tty, struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
ss->type = PORT_16654;
ss->line = port->minor;
ss->port = port->port_number;
ss->xmit_fifo_size = kfifo_size(&port->write_fifo);
ss->custom_divisor = 0;
ss->baud_base = 460800;
ss->close_delay = CLOSING_DELAY;
ss->closing_wait = CLOSING_DELAY;
return 0;
}
......
This diff is collapsed.
......@@ -130,6 +130,8 @@ static inline void usb_set_serial_port_data(struct usb_serial_port *port,
* @dev: pointer to the struct usb_device for this device
* @type: pointer to the struct usb_serial_driver for this device
* @interface: pointer to the struct usb_interface for this device
* @sibling: pointer to the struct usb_interface of any sibling interface
* @suspend_count: number of suspended (sibling) interfaces
* @num_ports: the number of ports this device has
* @num_interrupt_in: number of interrupt in endpoints we have
* @num_interrupt_out: number of interrupt out endpoints we have
......@@ -145,8 +147,9 @@ struct usb_serial {
struct usb_device *dev;
struct usb_serial_driver *type;
struct usb_interface *interface;
struct usb_interface *sibling;
unsigned int suspend_count;
unsigned char disconnected:1;
unsigned char suspending:1;
unsigned char attached:1;
unsigned char minors_reserved:1;
unsigned char num_ports;
......@@ -276,7 +279,7 @@ struct usb_serial_driver {
int (*write_room)(struct tty_struct *tty);
int (*ioctl)(struct tty_struct *tty,
unsigned int cmd, unsigned long arg);
int (*get_serial)(struct tty_struct *tty, struct serial_struct *ss);
void (*get_serial)(struct tty_struct *tty, struct serial_struct *ss);
int (*set_serial)(struct tty_struct *tty, struct serial_struct *ss);
void (*set_termios)(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old);
......@@ -335,6 +338,9 @@ static inline void usb_serial_console_disconnect(struct usb_serial *serial) {}
/* Functions needed by other parts of the usbserial core */
struct usb_serial_port *usb_serial_port_get_by_minor(unsigned int minor);
void usb_serial_put(struct usb_serial *serial);
int usb_serial_claim_interface(struct usb_serial *serial, struct usb_interface *intf);
int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port);
int usb_serial_generic_write_start(struct usb_serial_port *port, gfp_t mem_flags);
int usb_serial_generic_write(struct tty_struct *tty, struct usb_serial_port *port,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment