aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/ftdi_sio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r--drivers/usb/serial/ftdi_sio.c57
1 files changed, 31 insertions, 26 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 23d14b98ae2a..c540de15aad2 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1439,10 +1439,13 @@ static int read_latency_timer(struct usb_serial_port *port)
1439 FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, 1439 FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
1440 0, priv->interface, 1440 0, priv->interface,
1441 buf, 1, WDR_TIMEOUT); 1441 buf, 1, WDR_TIMEOUT);
1442 if (rv < 0) 1442 if (rv < 1) {
1443 dev_err(&port->dev, "Unable to read latency timer: %i\n", rv); 1443 dev_err(&port->dev, "Unable to read latency timer: %i\n", rv);
1444 else 1444 if (rv >= 0)
1445 rv = -EIO;
1446 } else {
1445 priv->latency = buf[0]; 1447 priv->latency = buf[0];
1448 }
1446 1449
1447 kfree(buf); 1450 kfree(buf);
1448 1451
@@ -1531,7 +1534,7 @@ check_and_exit:
1531} 1534}
1532 1535
1533static int get_lsr_info(struct usb_serial_port *port, 1536static int get_lsr_info(struct usb_serial_port *port,
1534 struct serial_struct __user *retinfo) 1537 unsigned int __user *retinfo)
1535{ 1538{
1536 struct ftdi_private *priv = usb_get_serial_port_data(port); 1539 struct ftdi_private *priv = usb_get_serial_port_data(port);
1537 unsigned int result = 0; 1540 unsigned int result = 0;
@@ -1802,8 +1805,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
1802 1805
1803 mutex_init(&priv->cfg_lock); 1806 mutex_init(&priv->cfg_lock);
1804 1807
1805 priv->flags = ASYNC_LOW_LATENCY;
1806
1807 if (quirk && quirk->port_probe) 1808 if (quirk && quirk->port_probe)
1808 quirk->port_probe(priv); 1809 quirk->port_probe(priv);
1809 1810
@@ -2067,6 +2068,20 @@ static int ftdi_process_packet(struct usb_serial_port *port,
2067 priv->prev_status = status; 2068 priv->prev_status = status;
2068 } 2069 }
2069 2070
2071 /* save if the transmitter is empty or not */
2072 if (packet[1] & FTDI_RS_TEMT)
2073 priv->transmit_empty = 1;
2074 else
2075 priv->transmit_empty = 0;
2076
2077 len -= 2;
2078 if (!len)
2079 return 0; /* status only */
2080
2081 /*
2082 * Break and error status must only be processed for packets with
2083 * data payload to avoid over-reporting.
2084 */
2070 flag = TTY_NORMAL; 2085 flag = TTY_NORMAL;
2071 if (packet[1] & FTDI_RS_ERR_MASK) { 2086 if (packet[1] & FTDI_RS_ERR_MASK) {
2072 /* Break takes precedence over parity, which takes precedence 2087 /* Break takes precedence over parity, which takes precedence
@@ -2089,15 +2104,6 @@ static int ftdi_process_packet(struct usb_serial_port *port,
2089 } 2104 }
2090 } 2105 }
2091 2106
2092 /* save if the transmitter is empty or not */
2093 if (packet[1] & FTDI_RS_TEMT)
2094 priv->transmit_empty = 1;
2095 else
2096 priv->transmit_empty = 0;
2097
2098 len -= 2;
2099 if (!len)
2100 return 0; /* status only */
2101 port->icount.rx += len; 2107 port->icount.rx += len;
2102 ch = packet + 2; 2108 ch = packet + 2;
2103 2109
@@ -2428,8 +2434,12 @@ static int ftdi_get_modem_status(struct usb_serial_port *port,
2428 FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, 2434 FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
2429 0, priv->interface, 2435 0, priv->interface,
2430 buf, len, WDR_TIMEOUT); 2436 buf, len, WDR_TIMEOUT);
2431 if (ret < 0) { 2437
2438 /* NOTE: We allow short responses and handle that below. */
2439 if (ret < 1) {
2432 dev_err(&port->dev, "failed to get modem status: %d\n", ret); 2440 dev_err(&port->dev, "failed to get modem status: %d\n", ret);
2441 if (ret >= 0)
2442 ret = -EIO;
2433 ret = usb_translate_errors(ret); 2443 ret = usb_translate_errors(ret);
2434 goto out; 2444 goto out;
2435 } 2445 }
@@ -2480,20 +2490,15 @@ static int ftdi_ioctl(struct tty_struct *tty,
2480 unsigned int cmd, unsigned long arg) 2490 unsigned int cmd, unsigned long arg)
2481{ 2491{
2482 struct usb_serial_port *port = tty->driver_data; 2492 struct usb_serial_port *port = tty->driver_data;
2493 void __user *argp = (void __user *)arg;
2483 2494
2484 /* Based on code from acm.c and others */
2485 switch (cmd) { 2495 switch (cmd) {
2486 2496 case TIOCGSERIAL:
2487 case TIOCGSERIAL: /* gets serial port data */ 2497 return get_serial_info(port, argp);
2488 return get_serial_info(port, 2498 case TIOCSSERIAL:
2489 (struct serial_struct __user *) arg); 2499 return set_serial_info(tty, port, argp);
2490
2491 case TIOCSSERIAL: /* sets serial port data */
2492 return set_serial_info(tty, port,
2493 (struct serial_struct __user *) arg);
2494 case TIOCSERGETLSR: 2500 case TIOCSERGETLSR:
2495 return get_lsr_info(port, (struct serial_struct __user *)arg); 2501 return get_lsr_info(port, argp);
2496 break;
2497 default: 2502 default:
2498 break; 2503 break;
2499 } 2504 }