aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/serial
diff options
context:
space:
mode:
authorAlex Shi <alex.shi@linaro.org>2017-02-27 12:13:50 +0800
committerAlex Shi <alex.shi@linaro.org>2017-02-27 12:13:50 +0800
commit0dbbc74421d25e7d490d7426b38f7942011deb4d (patch)
tree26a9d5968d5d0cd6c8b6fd8dee5cc3fb199e1e6e /drivers/usb/serial
parente2a316c741e51ce220003d49ea30e25468ca3b0f (diff)
parent3737a5f7223464efed3b0a9da2b045dae28d3a53 (diff)
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r--drivers/usb/serial/ark3116.c13
-rw-r--r--drivers/usb/serial/console.c1
-rw-r--r--drivers/usb/serial/cp210x.c2
-rw-r--r--drivers/usb/serial/ftdi_sio.c31
-rw-r--r--drivers/usb/serial/mos7840.c4
-rw-r--r--drivers/usb/serial/opticon.c2
-rw-r--r--drivers/usb/serial/spcp8x5.c8
7 files changed, 43 insertions, 18 deletions
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index 1532cde8a437..7812052dc700 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -99,10 +99,17 @@ static int ark3116_read_reg(struct usb_serial *serial,
usb_rcvctrlpipe(serial->dev, 0),
0xfe, 0xc0, 0, reg,
buf, 1, ARK_TIMEOUT);
- if (result < 0)
+ if (result < 1) {
+ dev_err(&serial->interface->dev,
+ "failed to read register %u: %d\n",
+ reg, result);
+ if (result >= 0)
+ result = -EIO;
+
return result;
- else
- return buf[0];
+ }
+
+ return buf[0];
}
static inline int calc_divisor(int bps)
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 8967715fe6fc..b6f1adefb758 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -143,6 +143,7 @@ static int usb_console_setup(struct console *co, char *options)
tty->driver = usb_serial_tty_driver;
tty->index = co->index;
init_ldsem(&tty->ldisc_sem);
+ spin_lock_init(&tty->files_lock);
INIT_LIST_HEAD(&tty->tty_files);
kref_get(&tty->driver->kref);
__module_get(tty->driver->owner);
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 243ac5ebe46a..8bb48751028c 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -172,6 +172,8 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
{ USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
{ USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */
+ { USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */
+ { USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */
{ USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 6e9fc8bcc285..99a0a5f1b400 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1807,8 +1807,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
mutex_init(&priv->cfg_lock);
- priv->flags = ASYNC_LOW_LATENCY;
-
if (quirk && quirk->port_probe)
quirk->port_probe(priv);
@@ -2072,6 +2070,20 @@ static int ftdi_process_packet(struct usb_serial_port *port,
priv->prev_status = status;
}
+ /* save if the transmitter is empty or not */
+ if (packet[1] & FTDI_RS_TEMT)
+ priv->transmit_empty = 1;
+ else
+ priv->transmit_empty = 0;
+
+ len -= 2;
+ if (!len)
+ return 0; /* status only */
+
+ /*
+ * Break and error status must only be processed for packets with
+ * data payload to avoid over-reporting.
+ */
flag = TTY_NORMAL;
if (packet[1] & FTDI_RS_ERR_MASK) {
/* Break takes precedence over parity, which takes precedence
@@ -2094,15 +2106,6 @@ static int ftdi_process_packet(struct usb_serial_port *port,
}
}
- /* save if the transmitter is empty or not */
- if (packet[1] & FTDI_RS_TEMT)
- priv->transmit_empty = 1;
- else
- priv->transmit_empty = 0;
-
- len -= 2;
- if (!len)
- return 0; /* status only */
port->icount.rx += len;
ch = packet + 2;
@@ -2433,8 +2436,12 @@ static int ftdi_get_modem_status(struct usb_serial_port *port,
FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
0, priv->interface,
buf, len, WDR_TIMEOUT);
- if (ret < 0) {
+
+ /* NOTE: We allow short responses and handle that below. */
+ if (ret < 1) {
dev_err(&port->dev, "failed to get modem status: %d\n", ret);
+ if (ret >= 0)
+ ret = -EIO;
ret = usb_translate_errors(ret);
goto out;
}
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 4f9af47e6a29..5c4fc3abf6a7 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -1024,6 +1024,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
* (can't set it up in mos7840_startup as the structures *
* were not set up at that time.) */
if (port0->open_ports == 1) {
+ /* FIXME: Buffer never NULL, so URB is not submitted. */
if (serial->port[0]->interrupt_in_buffer == NULL) {
/* set up interrupt urb */
usb_fill_int_urb(serial->port[0]->interrupt_in_urb,
@@ -2119,7 +2120,8 @@ static int mos7840_calc_num_ports(struct usb_serial *serial)
static int mos7840_attach(struct usb_serial *serial)
{
if (serial->num_bulk_in < serial->num_ports ||
- serial->num_bulk_out < serial->num_ports) {
+ serial->num_bulk_out < serial->num_ports ||
+ serial->num_interrupt_in < 1) {
dev_err(&serial->interface->dev, "missing endpoints\n");
return -ENODEV;
}
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 4b7bfb394a32..64bf258e7e00 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -142,7 +142,7 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port)
usb_clear_halt(port->serial->dev, port->read_urb->pipe);
res = usb_serial_generic_open(tty, port);
- if (!res)
+ if (res)
return res;
/* Request CTS line state, sometimes during opening the current
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index 475e6c31b266..ddfd787c461c 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -232,11 +232,17 @@ static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status)
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
GET_UART_STATUS, GET_UART_STATUS_TYPE,
0, GET_UART_STATUS_MSR, buf, 1, 100);
- if (ret < 0)
+ if (ret < 1) {
dev_err(&port->dev, "failed to get modem status: %d\n", ret);
+ if (ret >= 0)
+ ret = -EIO;
+ goto out;
+ }
dev_dbg(&port->dev, "0xc0:0x22:0:6 %d - 0x02%x\n", ret, *buf);
*status = *buf;
+ ret = 0;
+out:
kfree(buf);
return ret;