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.c149
1 files changed, 88 insertions, 61 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index d9fcdaedf389..683304d60615 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -89,6 +89,7 @@ struct ftdi_private {
89 int force_rtscts; /* if non-zero, force RTS-CTS to always 89 int force_rtscts; /* if non-zero, force RTS-CTS to always
90 be enabled */ 90 be enabled */
91 91
92 unsigned int latency; /* latency setting in use */
92 spinlock_t tx_lock; /* spinlock for transmit state */ 93 spinlock_t tx_lock; /* spinlock for transmit state */
93 unsigned long tx_bytes; 94 unsigned long tx_bytes;
94 unsigned long tx_outstanding_bytes; 95 unsigned long tx_outstanding_bytes;
@@ -719,8 +720,8 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port);
719static int ftdi_sio_port_remove(struct usb_serial_port *port); 720static int ftdi_sio_port_remove(struct usb_serial_port *port);
720static int ftdi_open(struct tty_struct *tty, 721static int ftdi_open(struct tty_struct *tty,
721 struct usb_serial_port *port, struct file *filp); 722 struct usb_serial_port *port, struct file *filp);
722static void ftdi_close(struct tty_struct *tty, 723static void ftdi_close(struct usb_serial_port *port);
723 struct usb_serial_port *port, struct file *filp); 724static void ftdi_dtr_rts(struct usb_serial_port *port, int on);
724static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, 725static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port,
725 const unsigned char *buf, int count); 726 const unsigned char *buf, int count);
726static int ftdi_write_room(struct tty_struct *tty); 727static int ftdi_write_room(struct tty_struct *tty);
@@ -758,6 +759,7 @@ static struct usb_serial_driver ftdi_sio_device = {
758 .port_remove = ftdi_sio_port_remove, 759 .port_remove = ftdi_sio_port_remove,
759 .open = ftdi_open, 760 .open = ftdi_open,
760 .close = ftdi_close, 761 .close = ftdi_close,
762 .dtr_rts = ftdi_dtr_rts,
761 .throttle = ftdi_throttle, 763 .throttle = ftdi_throttle,
762 .unthrottle = ftdi_unthrottle, 764 .unthrottle = ftdi_unthrottle,
763 .write = ftdi_write, 765 .write = ftdi_write,
@@ -1037,7 +1039,54 @@ static int change_speed(struct tty_struct *tty, struct usb_serial_port *port)
1037 return rv; 1039 return rv;
1038} 1040}
1039 1041
1042static int write_latency_timer(struct usb_serial_port *port)
1043{
1044 struct ftdi_private *priv = usb_get_serial_port_data(port);
1045 struct usb_device *udev = port->serial->dev;
1046 char buf[1];
1047 int rv = 0;
1048 int l = priv->latency;
1049
1050 if (priv->flags & ASYNC_LOW_LATENCY)
1051 l = 1;
1052
1053 dbg("%s: setting latency timer = %i", __func__, l);
1054
1055 rv = usb_control_msg(udev,
1056 usb_sndctrlpipe(udev, 0),
1057 FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
1058 FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
1059 l, priv->interface,
1060 buf, 0, WDR_TIMEOUT);
1061
1062 if (rv < 0)
1063 dev_err(&port->dev, "Unable to write latency timer: %i\n", rv);
1064 return rv;
1065}
1066
1067static int read_latency_timer(struct usb_serial_port *port)
1068{
1069 struct ftdi_private *priv = usb_get_serial_port_data(port);
1070 struct usb_device *udev = port->serial->dev;
1071 unsigned short latency = 0;
1072 int rv = 0;
1073
1040 1074
1075 dbg("%s", __func__);
1076
1077 rv = usb_control_msg(udev,
1078 usb_rcvctrlpipe(udev, 0),
1079 FTDI_SIO_GET_LATENCY_TIMER_REQUEST,
1080 FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
1081 0, priv->interface,
1082 (char *) &latency, 1, WDR_TIMEOUT);
1083
1084 if (rv < 0) {
1085 dev_err(&port->dev, "Unable to read latency timer: %i\n", rv);
1086 return -EIO;
1087 }
1088 return latency;
1089}
1041 1090
1042static int get_serial_info(struct usb_serial_port *port, 1091static int get_serial_info(struct usb_serial_port *port,
1043 struct serial_struct __user *retinfo) 1092 struct serial_struct __user *retinfo)
@@ -1097,6 +1146,7 @@ static int set_serial_info(struct tty_struct *tty,
1097 priv->custom_divisor = new_serial.custom_divisor; 1146 priv->custom_divisor = new_serial.custom_divisor;
1098 1147
1099 tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 1148 tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1149 write_latency_timer(port);
1100 1150
1101check_and_exit: 1151check_and_exit:
1102 if ((old_priv.flags & ASYNC_SPD_MASK) != 1152 if ((old_priv.flags & ASYNC_SPD_MASK) !=
@@ -1192,27 +1242,13 @@ static ssize_t show_latency_timer(struct device *dev,
1192{ 1242{
1193 struct usb_serial_port *port = to_usb_serial_port(dev); 1243 struct usb_serial_port *port = to_usb_serial_port(dev);
1194 struct ftdi_private *priv = usb_get_serial_port_data(port); 1244 struct ftdi_private *priv = usb_get_serial_port_data(port);
1195 struct usb_device *udev = port->serial->dev; 1245 if (priv->flags & ASYNC_LOW_LATENCY)
1196 unsigned short latency = 0; 1246 return sprintf(buf, "1\n");
1197 int rv = 0; 1247 else
1198 1248 return sprintf(buf, "%i\n", priv->latency);
1199
1200 dbg("%s", __func__);
1201
1202 rv = usb_control_msg(udev,
1203 usb_rcvctrlpipe(udev, 0),
1204 FTDI_SIO_GET_LATENCY_TIMER_REQUEST,
1205 FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
1206 0, priv->interface,
1207 (char *) &latency, 1, WDR_TIMEOUT);
1208
1209 if (rv < 0) {
1210 dev_err(dev, "Unable to read latency timer: %i\n", rv);
1211 return -EIO;
1212 }
1213 return sprintf(buf, "%i\n", latency);
1214} 1249}
1215 1250
1251
1216/* Write a new value of the latency timer, in units of milliseconds. */ 1252/* Write a new value of the latency timer, in units of milliseconds. */
1217static ssize_t store_latency_timer(struct device *dev, 1253static ssize_t store_latency_timer(struct device *dev,
1218 struct device_attribute *attr, const char *valbuf, 1254 struct device_attribute *attr, const char *valbuf,
@@ -1220,25 +1256,13 @@ static ssize_t store_latency_timer(struct device *dev,
1220{ 1256{
1221 struct usb_serial_port *port = to_usb_serial_port(dev); 1257 struct usb_serial_port *port = to_usb_serial_port(dev);
1222 struct ftdi_private *priv = usb_get_serial_port_data(port); 1258 struct ftdi_private *priv = usb_get_serial_port_data(port);
1223 struct usb_device *udev = port->serial->dev;
1224 char buf[1];
1225 int v = simple_strtoul(valbuf, NULL, 10); 1259 int v = simple_strtoul(valbuf, NULL, 10);
1226 int rv = 0; 1260 int rv = 0;
1227 1261
1228 dbg("%s: setting latency timer = %i", __func__, v); 1262 priv->latency = v;
1229 1263 rv = write_latency_timer(port);
1230 rv = usb_control_msg(udev, 1264 if (rv < 0)
1231 usb_sndctrlpipe(udev, 0),
1232 FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
1233 FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
1234 v, priv->interface,
1235 buf, 0, WDR_TIMEOUT);
1236
1237 if (rv < 0) {
1238 dev_err(dev, "Unable to write latency timer: %i\n", rv);
1239 return -EIO; 1265 return -EIO;
1240 }
1241
1242 return count; 1266 return count;
1243} 1267}
1244 1268
@@ -1392,6 +1416,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
1392 usb_set_serial_port_data(port, priv); 1416 usb_set_serial_port_data(port, priv);
1393 1417
1394 ftdi_determine_type(port); 1418 ftdi_determine_type(port);
1419 read_latency_timer(port);
1395 create_sysfs_attrs(port); 1420 create_sysfs_attrs(port);
1396 return 0; 1421 return 0;
1397} 1422}
@@ -1514,6 +1539,8 @@ static int ftdi_open(struct tty_struct *tty,
1514 if (tty) 1539 if (tty)
1515 tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 1540 tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1516 1541
1542 write_latency_timer(port);
1543
1517 /* No error checking for this (will get errors later anyway) */ 1544 /* No error checking for this (will get errors later anyway) */
1518 /* See ftdi_sio.h for description of what is reset */ 1545 /* See ftdi_sio.h for description of what is reset */
1519 usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 1546 usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
@@ -1529,11 +1556,6 @@ static int ftdi_open(struct tty_struct *tty,
1529 if (tty) 1556 if (tty)
1530 ftdi_set_termios(tty, port, tty->termios); 1557 ftdi_set_termios(tty, port, tty->termios);
1531 1558
1532 /* FIXME: Flow control might be enabled, so it should be checked -
1533 we have no control of defaults! */
1534 /* Turn on RTS and DTR since we are not flow controlling by default */
1535 set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
1536
1537 /* Not throttled */ 1559 /* Not throttled */
1538 spin_lock_irqsave(&priv->rx_lock, flags); 1560 spin_lock_irqsave(&priv->rx_lock, flags);
1539 priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); 1561 priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
@@ -1558,6 +1580,30 @@ static int ftdi_open(struct tty_struct *tty,
1558} /* ftdi_open */ 1580} /* ftdi_open */
1559 1581
1560 1582
1583static void ftdi_dtr_rts(struct usb_serial_port *port, int on)
1584{
1585 struct ftdi_private *priv = usb_get_serial_port_data(port);
1586 char buf[1];
1587
1588 mutex_lock(&port->serial->disc_mutex);
1589 if (!port->serial->disconnected) {
1590 /* Disable flow control */
1591 if (!on && usb_control_msg(port->serial->dev,
1592 usb_sndctrlpipe(port->serial->dev, 0),
1593 FTDI_SIO_SET_FLOW_CTRL_REQUEST,
1594 FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
1595 0, priv->interface, buf, 0,
1596 WDR_TIMEOUT) < 0) {
1597 dev_err(&port->dev, "error from flowcontrol urb\n");
1598 }
1599 /* drop RTS and DTR */
1600 if (on)
1601 set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
1602 else
1603 clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
1604 }
1605 mutex_unlock(&port->serial->disc_mutex);
1606}
1561 1607
1562/* 1608/*
1563 * usbserial:__serial_close only calls ftdi_close if the point is open 1609 * usbserial:__serial_close only calls ftdi_close if the point is open
@@ -1567,31 +1613,12 @@ static int ftdi_open(struct tty_struct *tty,
1567 * 1613 *
1568 */ 1614 */
1569 1615
1570static void ftdi_close(struct tty_struct *tty, 1616static void ftdi_close(struct usb_serial_port *port)
1571 struct usb_serial_port *port, struct file *filp)
1572{ /* ftdi_close */ 1617{ /* ftdi_close */
1573 unsigned int c_cflag = tty->termios->c_cflag;
1574 struct ftdi_private *priv = usb_get_serial_port_data(port); 1618 struct ftdi_private *priv = usb_get_serial_port_data(port);
1575 char buf[1];
1576 1619
1577 dbg("%s", __func__); 1620 dbg("%s", __func__);
1578 1621
1579 mutex_lock(&port->serial->disc_mutex);
1580 if (c_cflag & HUPCL && !port->serial->disconnected) {
1581 /* Disable flow control */
1582 if (usb_control_msg(port->serial->dev,
1583 usb_sndctrlpipe(port->serial->dev, 0),
1584 FTDI_SIO_SET_FLOW_CTRL_REQUEST,
1585 FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
1586 0, priv->interface, buf, 0,
1587 WDR_TIMEOUT) < 0) {
1588 dev_err(&port->dev, "error from flowcontrol urb\n");
1589 }
1590
1591 /* drop RTS and DTR */
1592 clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
1593 } /* Note change no line if hupcl is off */
1594 mutex_unlock(&port->serial->disc_mutex);
1595 1622
1596 /* cancel any scheduled reading */ 1623 /* cancel any scheduled reading */
1597 cancel_delayed_work_sync(&priv->rx_work); 1624 cancel_delayed_work_sync(&priv->rx_work);