diff options
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 195 |
1 files changed, 89 insertions, 106 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 7638828e7317..6af0dfa5f5ac 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -33,12 +33,12 @@ | |||
33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/smp_lock.h> | ||
37 | #include <linux/tty.h> | 36 | #include <linux/tty.h> |
38 | #include <linux/tty_driver.h> | 37 | #include <linux/tty_driver.h> |
39 | #include <linux/tty_flip.h> | 38 | #include <linux/tty_flip.h> |
40 | #include <linux/module.h> | 39 | #include <linux/module.h> |
41 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
41 | #include <linux/mutex.h> | ||
42 | #include <linux/uaccess.h> | 42 | #include <linux/uaccess.h> |
43 | #include <linux/usb.h> | 43 | #include <linux/usb.h> |
44 | #include <linux/serial.h> | 44 | #include <linux/serial.h> |
@@ -88,10 +88,10 @@ struct ftdi_private { | |||
88 | 88 | ||
89 | unsigned int latency; /* latency setting in use */ | 89 | unsigned int latency; /* latency setting in use */ |
90 | spinlock_t tx_lock; /* spinlock for transmit state */ | 90 | spinlock_t tx_lock; /* spinlock for transmit state */ |
91 | unsigned long tx_bytes; | ||
92 | unsigned long tx_outstanding_bytes; | 91 | unsigned long tx_outstanding_bytes; |
93 | unsigned long tx_outstanding_urbs; | 92 | unsigned long tx_outstanding_urbs; |
94 | unsigned short max_packet_size; | 93 | unsigned short max_packet_size; |
94 | struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() */ | ||
95 | }; | 95 | }; |
96 | 96 | ||
97 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ | 97 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ |
@@ -614,6 +614,7 @@ static struct usb_device_id id_table_combined [] = { | |||
614 | { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) }, | 614 | { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) }, |
615 | { USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, | 615 | { USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, |
616 | { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, | 616 | { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, |
617 | { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, | ||
617 | { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, | 618 | { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, |
618 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, | 619 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, |
619 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, | 620 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, |
@@ -737,6 +738,10 @@ static struct usb_device_id id_table_combined [] = { | |||
737 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 738 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
738 | { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, | 739 | { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, |
739 | { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) }, | 740 | { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) }, |
741 | { USB_DEVICE(FTDI_VID, MJSG_GENERIC_PID) }, | ||
742 | { USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) }, | ||
743 | { USB_DEVICE(FTDI_VID, MJSG_HD_RADIO_PID) }, | ||
744 | { USB_DEVICE(FTDI_VID, MJSG_XM_RADIO_PID) }, | ||
740 | { }, /* Optional parameter entry */ | 745 | { }, /* Optional parameter entry */ |
741 | { } /* Terminating entry */ | 746 | { } /* Terminating entry */ |
742 | }; | 747 | }; |
@@ -812,7 +817,7 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
812 | .name = "ftdi_sio", | 817 | .name = "ftdi_sio", |
813 | }, | 818 | }, |
814 | .description = "FTDI USB Serial Device", | 819 | .description = "FTDI USB Serial Device", |
815 | .usb_driver = &ftdi_driver , | 820 | .usb_driver = &ftdi_driver, |
816 | .id_table = id_table_combined, | 821 | .id_table = id_table_combined, |
817 | .num_ports = 1, | 822 | .num_ports = 1, |
818 | .probe = ftdi_sio_probe, | 823 | .probe = ftdi_sio_probe, |
@@ -828,8 +833,8 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
828 | .chars_in_buffer = ftdi_chars_in_buffer, | 833 | .chars_in_buffer = ftdi_chars_in_buffer, |
829 | .read_bulk_callback = ftdi_read_bulk_callback, | 834 | .read_bulk_callback = ftdi_read_bulk_callback, |
830 | .write_bulk_callback = ftdi_write_bulk_callback, | 835 | .write_bulk_callback = ftdi_write_bulk_callback, |
831 | .tiocmget = ftdi_tiocmget, | 836 | .tiocmget = ftdi_tiocmget, |
832 | .tiocmset = ftdi_tiocmset, | 837 | .tiocmset = ftdi_tiocmset, |
833 | .ioctl = ftdi_ioctl, | 838 | .ioctl = ftdi_ioctl, |
834 | .set_termios = ftdi_set_termios, | 839 | .set_termios = ftdi_set_termios, |
835 | .break_ctl = ftdi_break_ctl, | 840 | .break_ctl = ftdi_break_ctl, |
@@ -935,7 +940,6 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, | |||
935 | unsigned int clear) | 940 | unsigned int clear) |
936 | { | 941 | { |
937 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 942 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
938 | char *buf; | ||
939 | unsigned urb_value; | 943 | unsigned urb_value; |
940 | int rv; | 944 | int rv; |
941 | 945 | ||
@@ -944,10 +948,6 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, | |||
944 | return 0; /* no change */ | 948 | return 0; /* no change */ |
945 | } | 949 | } |
946 | 950 | ||
947 | buf = kmalloc(1, GFP_NOIO); | ||
948 | if (!buf) | ||
949 | return -ENOMEM; | ||
950 | |||
951 | clear &= ~set; /* 'set' takes precedence over 'clear' */ | 951 | clear &= ~set; /* 'set' takes precedence over 'clear' */ |
952 | urb_value = 0; | 952 | urb_value = 0; |
953 | if (clear & TIOCM_DTR) | 953 | if (clear & TIOCM_DTR) |
@@ -963,9 +963,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, | |||
963 | FTDI_SIO_SET_MODEM_CTRL_REQUEST, | 963 | FTDI_SIO_SET_MODEM_CTRL_REQUEST, |
964 | FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, | 964 | FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, |
965 | urb_value, priv->interface, | 965 | urb_value, priv->interface, |
966 | buf, 0, WDR_TIMEOUT); | 966 | NULL, 0, WDR_TIMEOUT); |
967 | |||
968 | kfree(buf); | ||
969 | if (rv < 0) { | 967 | if (rv < 0) { |
970 | dbg("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", | 968 | dbg("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", |
971 | __func__, | 969 | __func__, |
@@ -1124,16 +1122,11 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, | |||
1124 | static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) | 1122 | static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) |
1125 | { | 1123 | { |
1126 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1124 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1127 | char *buf; | ||
1128 | __u16 urb_value; | 1125 | __u16 urb_value; |
1129 | __u16 urb_index; | 1126 | __u16 urb_index; |
1130 | __u32 urb_index_value; | 1127 | __u32 urb_index_value; |
1131 | int rv; | 1128 | int rv; |
1132 | 1129 | ||
1133 | buf = kmalloc(1, GFP_NOIO); | ||
1134 | if (!buf) | ||
1135 | return -ENOMEM; | ||
1136 | |||
1137 | urb_index_value = get_ftdi_divisor(tty, port); | 1130 | urb_index_value = get_ftdi_divisor(tty, port); |
1138 | urb_value = (__u16)urb_index_value; | 1131 | urb_value = (__u16)urb_index_value; |
1139 | urb_index = (__u16)(urb_index_value >> 16); | 1132 | urb_index = (__u16)(urb_index_value >> 16); |
@@ -1146,9 +1139,7 @@ static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) | |||
1146 | FTDI_SIO_SET_BAUDRATE_REQUEST, | 1139 | FTDI_SIO_SET_BAUDRATE_REQUEST, |
1147 | FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, | 1140 | FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, |
1148 | urb_value, urb_index, | 1141 | urb_value, urb_index, |
1149 | buf, 0, WDR_SHORT_TIMEOUT); | 1142 | NULL, 0, WDR_SHORT_TIMEOUT); |
1150 | |||
1151 | kfree(buf); | ||
1152 | return rv; | 1143 | return rv; |
1153 | } | 1144 | } |
1154 | 1145 | ||
@@ -1156,8 +1147,7 @@ static int write_latency_timer(struct usb_serial_port *port) | |||
1156 | { | 1147 | { |
1157 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1148 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1158 | struct usb_device *udev = port->serial->dev; | 1149 | struct usb_device *udev = port->serial->dev; |
1159 | char buf[1]; | 1150 | int rv; |
1160 | int rv = 0; | ||
1161 | int l = priv->latency; | 1151 | int l = priv->latency; |
1162 | 1152 | ||
1163 | if (priv->flags & ASYNC_LOW_LATENCY) | 1153 | if (priv->flags & ASYNC_LOW_LATENCY) |
@@ -1170,8 +1160,7 @@ static int write_latency_timer(struct usb_serial_port *port) | |||
1170 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | 1160 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, |
1171 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | 1161 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, |
1172 | l, priv->interface, | 1162 | l, priv->interface, |
1173 | buf, 0, WDR_TIMEOUT); | 1163 | NULL, 0, WDR_TIMEOUT); |
1174 | |||
1175 | if (rv < 0) | 1164 | if (rv < 0) |
1176 | dev_err(&port->dev, "Unable to write latency timer: %i\n", rv); | 1165 | dev_err(&port->dev, "Unable to write latency timer: %i\n", rv); |
1177 | return rv; | 1166 | return rv; |
@@ -1181,24 +1170,29 @@ static int read_latency_timer(struct usb_serial_port *port) | |||
1181 | { | 1170 | { |
1182 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1171 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1183 | struct usb_device *udev = port->serial->dev; | 1172 | struct usb_device *udev = port->serial->dev; |
1184 | unsigned short latency = 0; | 1173 | unsigned char *buf; |
1185 | int rv = 0; | 1174 | int rv; |
1186 | |||
1187 | 1175 | ||
1188 | dbg("%s", __func__); | 1176 | dbg("%s", __func__); |
1189 | 1177 | ||
1178 | buf = kmalloc(1, GFP_KERNEL); | ||
1179 | if (!buf) | ||
1180 | return -ENOMEM; | ||
1181 | |||
1190 | rv = usb_control_msg(udev, | 1182 | rv = usb_control_msg(udev, |
1191 | usb_rcvctrlpipe(udev, 0), | 1183 | usb_rcvctrlpipe(udev, 0), |
1192 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST, | 1184 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST, |
1193 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, | 1185 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, |
1194 | 0, priv->interface, | 1186 | 0, priv->interface, |
1195 | (char *) &latency, 1, WDR_TIMEOUT); | 1187 | buf, 1, WDR_TIMEOUT); |
1196 | 1188 | if (rv < 0) | |
1197 | if (rv < 0) { | ||
1198 | dev_err(&port->dev, "Unable to read latency timer: %i\n", rv); | 1189 | dev_err(&port->dev, "Unable to read latency timer: %i\n", rv); |
1199 | return -EIO; | 1190 | else |
1200 | } | 1191 | priv->latency = buf[0]; |
1201 | return latency; | 1192 | |
1193 | kfree(buf); | ||
1194 | |||
1195 | return rv; | ||
1202 | } | 1196 | } |
1203 | 1197 | ||
1204 | static int get_serial_info(struct usb_serial_port *port, | 1198 | static int get_serial_info(struct usb_serial_port *port, |
@@ -1229,7 +1223,7 @@ static int set_serial_info(struct tty_struct *tty, | |||
1229 | if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) | 1223 | if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) |
1230 | return -EFAULT; | 1224 | return -EFAULT; |
1231 | 1225 | ||
1232 | lock_kernel(); | 1226 | mutex_lock(&priv->cfg_lock); |
1233 | old_priv = *priv; | 1227 | old_priv = *priv; |
1234 | 1228 | ||
1235 | /* Do error checking and permission checking */ | 1229 | /* Do error checking and permission checking */ |
@@ -1237,7 +1231,7 @@ static int set_serial_info(struct tty_struct *tty, | |||
1237 | if (!capable(CAP_SYS_ADMIN)) { | 1231 | if (!capable(CAP_SYS_ADMIN)) { |
1238 | if (((new_serial.flags & ~ASYNC_USR_MASK) != | 1232 | if (((new_serial.flags & ~ASYNC_USR_MASK) != |
1239 | (priv->flags & ~ASYNC_USR_MASK))) { | 1233 | (priv->flags & ~ASYNC_USR_MASK))) { |
1240 | unlock_kernel(); | 1234 | mutex_unlock(&priv->cfg_lock); |
1241 | return -EPERM; | 1235 | return -EPERM; |
1242 | } | 1236 | } |
1243 | priv->flags = ((priv->flags & ~ASYNC_USR_MASK) | | 1237 | priv->flags = ((priv->flags & ~ASYNC_USR_MASK) | |
@@ -1248,7 +1242,7 @@ static int set_serial_info(struct tty_struct *tty, | |||
1248 | 1242 | ||
1249 | if ((new_serial.baud_base != priv->baud_base) && | 1243 | if ((new_serial.baud_base != priv->baud_base) && |
1250 | (new_serial.baud_base < 9600)) { | 1244 | (new_serial.baud_base < 9600)) { |
1251 | unlock_kernel(); | 1245 | mutex_unlock(&priv->cfg_lock); |
1252 | return -EINVAL; | 1246 | return -EINVAL; |
1253 | } | 1247 | } |
1254 | 1248 | ||
@@ -1278,11 +1272,11 @@ check_and_exit: | |||
1278 | (priv->flags & ASYNC_SPD_MASK)) || | 1272 | (priv->flags & ASYNC_SPD_MASK)) || |
1279 | (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && | 1273 | (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && |
1280 | (old_priv.custom_divisor != priv->custom_divisor))) { | 1274 | (old_priv.custom_divisor != priv->custom_divisor))) { |
1281 | unlock_kernel(); | 1275 | mutex_unlock(&priv->cfg_lock); |
1282 | change_speed(tty, port); | 1276 | change_speed(tty, port); |
1283 | } | 1277 | } |
1284 | else | 1278 | else |
1285 | unlock_kernel(); | 1279 | mutex_unlock(&priv->cfg_lock); |
1286 | return 0; | 1280 | return 0; |
1287 | 1281 | ||
1288 | } /* set_serial_info */ | 1282 | } /* set_serial_info */ |
@@ -1338,20 +1332,20 @@ static void ftdi_determine_type(struct usb_serial_port *port) | |||
1338 | __func__); | 1332 | __func__); |
1339 | } | 1333 | } |
1340 | } else if (version < 0x200) { | 1334 | } else if (version < 0x200) { |
1341 | /* Old device. Assume its the original SIO. */ | 1335 | /* Old device. Assume it's the original SIO. */ |
1342 | priv->chip_type = SIO; | 1336 | priv->chip_type = SIO; |
1343 | priv->baud_base = 12000000 / 16; | 1337 | priv->baud_base = 12000000 / 16; |
1344 | priv->write_offset = 1; | 1338 | priv->write_offset = 1; |
1345 | } else if (version < 0x400) { | 1339 | } else if (version < 0x400) { |
1346 | /* Assume its an FT8U232AM (or FT8U245AM) */ | 1340 | /* Assume it's an FT8U232AM (or FT8U245AM) */ |
1347 | /* (It might be a BM because of the iSerialNumber bug, | 1341 | /* (It might be a BM because of the iSerialNumber bug, |
1348 | * but it will still work as an AM device.) */ | 1342 | * but it will still work as an AM device.) */ |
1349 | priv->chip_type = FT8U232AM; | 1343 | priv->chip_type = FT8U232AM; |
1350 | } else if (version < 0x600) { | 1344 | } else if (version < 0x600) { |
1351 | /* Assume its an FT232BM (or FT245BM) */ | 1345 | /* Assume it's an FT232BM (or FT245BM) */ |
1352 | priv->chip_type = FT232BM; | 1346 | priv->chip_type = FT232BM; |
1353 | } else { | 1347 | } else { |
1354 | /* Assume its an FT232R */ | 1348 | /* Assume it's an FT232R */ |
1355 | priv->chip_type = FT232RL; | 1349 | priv->chip_type = FT232RL; |
1356 | } | 1350 | } |
1357 | dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]); | 1351 | dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]); |
@@ -1371,7 +1365,7 @@ static void ftdi_set_max_packet_size(struct usb_serial_port *port) | |||
1371 | struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc; | 1365 | struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc; |
1372 | 1366 | ||
1373 | unsigned num_endpoints; | 1367 | unsigned num_endpoints; |
1374 | int i = 0; | 1368 | int i; |
1375 | 1369 | ||
1376 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; | 1370 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; |
1377 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); | 1371 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); |
@@ -1423,7 +1417,7 @@ static ssize_t store_latency_timer(struct device *dev, | |||
1423 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1417 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1424 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1418 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1425 | int v = simple_strtoul(valbuf, NULL, 10); | 1419 | int v = simple_strtoul(valbuf, NULL, 10); |
1426 | int rv = 0; | 1420 | int rv; |
1427 | 1421 | ||
1428 | priv->latency = v; | 1422 | priv->latency = v; |
1429 | rv = write_latency_timer(port); | 1423 | rv = write_latency_timer(port); |
@@ -1440,9 +1434,8 @@ static ssize_t store_event_char(struct device *dev, | |||
1440 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1434 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1441 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1435 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1442 | struct usb_device *udev = port->serial->dev; | 1436 | struct usb_device *udev = port->serial->dev; |
1443 | char buf[1]; | ||
1444 | int v = simple_strtoul(valbuf, NULL, 10); | 1437 | int v = simple_strtoul(valbuf, NULL, 10); |
1445 | int rv = 0; | 1438 | int rv; |
1446 | 1439 | ||
1447 | dbg("%s: setting event char = %i", __func__, v); | 1440 | dbg("%s: setting event char = %i", __func__, v); |
1448 | 1441 | ||
@@ -1451,8 +1444,7 @@ static ssize_t store_event_char(struct device *dev, | |||
1451 | FTDI_SIO_SET_EVENT_CHAR_REQUEST, | 1444 | FTDI_SIO_SET_EVENT_CHAR_REQUEST, |
1452 | FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE, | 1445 | FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE, |
1453 | v, priv->interface, | 1446 | v, priv->interface, |
1454 | buf, 0, WDR_TIMEOUT); | 1447 | NULL, 0, WDR_TIMEOUT); |
1455 | |||
1456 | if (rv < 0) { | 1448 | if (rv < 0) { |
1457 | dbg("Unable to write event character: %i", rv); | 1449 | dbg("Unable to write event character: %i", rv); |
1458 | return -EIO; | 1450 | return -EIO; |
@@ -1551,9 +1543,9 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1551 | 1543 | ||
1552 | kref_init(&priv->kref); | 1544 | kref_init(&priv->kref); |
1553 | spin_lock_init(&priv->tx_lock); | 1545 | spin_lock_init(&priv->tx_lock); |
1546 | mutex_init(&priv->cfg_lock); | ||
1554 | init_waitqueue_head(&priv->delta_msr_wait); | 1547 | init_waitqueue_head(&priv->delta_msr_wait); |
1555 | /* This will push the characters through immediately rather | 1548 | |
1556 | than queue a task to deliver them */ | ||
1557 | priv->flags = ASYNC_LOW_LATENCY; | 1549 | priv->flags = ASYNC_LOW_LATENCY; |
1558 | 1550 | ||
1559 | if (quirk && quirk->port_probe) | 1551 | if (quirk && quirk->port_probe) |
@@ -1585,7 +1577,8 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1585 | 1577 | ||
1586 | ftdi_determine_type(port); | 1578 | ftdi_determine_type(port); |
1587 | ftdi_set_max_packet_size(port); | 1579 | ftdi_set_max_packet_size(port); |
1588 | read_latency_timer(port); | 1580 | if (read_latency_timer(port) < 0) |
1581 | priv->latency = 16; | ||
1589 | create_sysfs_attrs(port); | 1582 | create_sysfs_attrs(port); |
1590 | return 0; | 1583 | return 0; |
1591 | } | 1584 | } |
@@ -1630,8 +1623,6 @@ static int ftdi_NDI_device_setup(struct usb_serial *serial) | |||
1630 | { | 1623 | { |
1631 | struct usb_device *udev = serial->dev; | 1624 | struct usb_device *udev = serial->dev; |
1632 | int latency = ndi_latency_timer; | 1625 | int latency = ndi_latency_timer; |
1633 | int rv = 0; | ||
1634 | char buf[1]; | ||
1635 | 1626 | ||
1636 | if (latency == 0) | 1627 | if (latency == 0) |
1637 | latency = 1; | 1628 | latency = 1; |
@@ -1641,10 +1632,11 @@ static int ftdi_NDI_device_setup(struct usb_serial *serial) | |||
1641 | dbg("%s setting NDI device latency to %d", __func__, latency); | 1632 | dbg("%s setting NDI device latency to %d", __func__, latency); |
1642 | dev_info(&udev->dev, "NDI device with a latency value of %d", latency); | 1633 | dev_info(&udev->dev, "NDI device with a latency value of %d", latency); |
1643 | 1634 | ||
1644 | rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 1635 | /* FIXME: errors are not returned */ |
1636 | usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
1645 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | 1637 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, |
1646 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | 1638 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, |
1647 | latency, 0, buf, 0, WDR_TIMEOUT); | 1639 | latency, 0, NULL, 0, WDR_TIMEOUT); |
1648 | return 0; | 1640 | return 0; |
1649 | } | 1641 | } |
1650 | 1642 | ||
@@ -1720,7 +1712,7 @@ static int ftdi_submit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) | |||
1720 | urb->transfer_buffer_length, | 1712 | urb->transfer_buffer_length, |
1721 | ftdi_read_bulk_callback, port); | 1713 | ftdi_read_bulk_callback, port); |
1722 | result = usb_submit_urb(urb, mem_flags); | 1714 | result = usb_submit_urb(urb, mem_flags); |
1723 | if (result) | 1715 | if (result && result != -EPERM) |
1724 | dev_err(&port->dev, | 1716 | dev_err(&port->dev, |
1725 | "%s - failed submitting read urb, error %d\n", | 1717 | "%s - failed submitting read urb, error %d\n", |
1726 | __func__, result); | 1718 | __func__, result); |
@@ -1732,16 +1724,10 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1732 | struct usb_device *dev = port->serial->dev; | 1724 | struct usb_device *dev = port->serial->dev; |
1733 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1725 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1734 | unsigned long flags; | 1726 | unsigned long flags; |
1735 | 1727 | int result; | |
1736 | int result = 0; | ||
1737 | char buf[1]; /* Needed for the usb_control_msg I think */ | ||
1738 | 1728 | ||
1739 | dbg("%s", __func__); | 1729 | dbg("%s", __func__); |
1740 | 1730 | ||
1741 | spin_lock_irqsave(&priv->tx_lock, flags); | ||
1742 | priv->tx_bytes = 0; | ||
1743 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
1744 | |||
1745 | write_latency_timer(port); | 1731 | write_latency_timer(port); |
1746 | 1732 | ||
1747 | /* No error checking for this (will get errors later anyway) */ | 1733 | /* No error checking for this (will get errors later anyway) */ |
@@ -1749,7 +1735,7 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1749 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1735 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1750 | FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, | 1736 | FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, |
1751 | FTDI_SIO_RESET_SIO, | 1737 | FTDI_SIO_RESET_SIO, |
1752 | priv->interface, buf, 0, WDR_TIMEOUT); | 1738 | priv->interface, NULL, 0, WDR_TIMEOUT); |
1753 | 1739 | ||
1754 | /* Termios defaults are set by usb_serial_init. We don't change | 1740 | /* Termios defaults are set by usb_serial_init. We don't change |
1755 | port->tty->termios - this would lose speed settings, etc. | 1741 | port->tty->termios - this would lose speed settings, etc. |
@@ -1777,7 +1763,6 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1777 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on) | 1763 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on) |
1778 | { | 1764 | { |
1779 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1765 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1780 | char buf[1]; | ||
1781 | 1766 | ||
1782 | mutex_lock(&port->serial->disc_mutex); | 1767 | mutex_lock(&port->serial->disc_mutex); |
1783 | if (!port->serial->disconnected) { | 1768 | if (!port->serial->disconnected) { |
@@ -1786,7 +1771,7 @@ static void ftdi_dtr_rts(struct usb_serial_port *port, int on) | |||
1786 | usb_sndctrlpipe(port->serial->dev, 0), | 1771 | usb_sndctrlpipe(port->serial->dev, 0), |
1787 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 1772 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
1788 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 1773 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
1789 | 0, priv->interface, buf, 0, | 1774 | 0, priv->interface, NULL, 0, |
1790 | WDR_TIMEOUT) < 0) { | 1775 | WDR_TIMEOUT) < 0) { |
1791 | dev_err(&port->dev, "error from flowcontrol urb\n"); | 1776 | dev_err(&port->dev, "error from flowcontrol urb\n"); |
1792 | } | 1777 | } |
@@ -1847,7 +1832,7 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1847 | spin_lock_irqsave(&priv->tx_lock, flags); | 1832 | spin_lock_irqsave(&priv->tx_lock, flags); |
1848 | if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) { | 1833 | if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) { |
1849 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 1834 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
1850 | dbg("%s - write limit hit\n", __func__); | 1835 | dbg("%s - write limit hit", __func__); |
1851 | return 0; | 1836 | return 0; |
1852 | } | 1837 | } |
1853 | priv->tx_outstanding_urbs++; | 1838 | priv->tx_outstanding_urbs++; |
@@ -1927,7 +1912,6 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
1927 | } else { | 1912 | } else { |
1928 | spin_lock_irqsave(&priv->tx_lock, flags); | 1913 | spin_lock_irqsave(&priv->tx_lock, flags); |
1929 | priv->tx_outstanding_bytes += count; | 1914 | priv->tx_outstanding_bytes += count; |
1930 | priv->tx_bytes += count; | ||
1931 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 1915 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
1932 | } | 1916 | } |
1933 | 1917 | ||
@@ -2154,8 +2138,7 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state) | |||
2154 | { | 2138 | { |
2155 | struct usb_serial_port *port = tty->driver_data; | 2139 | struct usb_serial_port *port = tty->driver_data; |
2156 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 2140 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2157 | __u16 urb_value = 0; | 2141 | __u16 urb_value; |
2158 | char buf[1]; | ||
2159 | 2142 | ||
2160 | /* break_state = -1 to turn on break, and 0 to turn off break */ | 2143 | /* break_state = -1 to turn on break, and 0 to turn off break */ |
2161 | /* see drivers/char/tty_io.c to see it used */ | 2144 | /* see drivers/char/tty_io.c to see it used */ |
@@ -2171,7 +2154,7 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state) | |||
2171 | FTDI_SIO_SET_DATA_REQUEST, | 2154 | FTDI_SIO_SET_DATA_REQUEST, |
2172 | FTDI_SIO_SET_DATA_REQUEST_TYPE, | 2155 | FTDI_SIO_SET_DATA_REQUEST_TYPE, |
2173 | urb_value , priv->interface, | 2156 | urb_value , priv->interface, |
2174 | buf, 0, WDR_TIMEOUT) < 0) { | 2157 | NULL, 0, WDR_TIMEOUT) < 0) { |
2175 | dev_err(&port->dev, "%s FAILED to enable/disable break state " | 2158 | dev_err(&port->dev, "%s FAILED to enable/disable break state " |
2176 | "(state was %d)\n", __func__, break_state); | 2159 | "(state was %d)\n", __func__, break_state); |
2177 | } | 2160 | } |
@@ -2195,7 +2178,6 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2195 | struct ktermios *termios = tty->termios; | 2178 | struct ktermios *termios = tty->termios; |
2196 | unsigned int cflag = termios->c_cflag; | 2179 | unsigned int cflag = termios->c_cflag; |
2197 | __u16 urb_value; /* will hold the new flags */ | 2180 | __u16 urb_value; /* will hold the new flags */ |
2198 | char buf[1]; /* Perhaps I should dynamically alloc this? */ | ||
2199 | 2181 | ||
2200 | /* Added for xon/xoff support */ | 2182 | /* Added for xon/xoff support */ |
2201 | unsigned int iflag = termios->c_iflag; | 2183 | unsigned int iflag = termios->c_iflag; |
@@ -2246,12 +2228,10 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2246 | } | 2228 | } |
2247 | if (cflag & CSIZE) { | 2229 | if (cflag & CSIZE) { |
2248 | switch (cflag & CSIZE) { | 2230 | switch (cflag & CSIZE) { |
2249 | case CS5: urb_value |= 5; dbg("Setting CS5"); break; | ||
2250 | case CS6: urb_value |= 6; dbg("Setting CS6"); break; | ||
2251 | case CS7: urb_value |= 7; dbg("Setting CS7"); break; | 2231 | case CS7: urb_value |= 7; dbg("Setting CS7"); break; |
2252 | case CS8: urb_value |= 8; dbg("Setting CS8"); break; | 2232 | case CS8: urb_value |= 8; dbg("Setting CS8"); break; |
2253 | default: | 2233 | default: |
2254 | dev_err(&port->dev, "CSIZE was set but not CS5-CS8\n"); | 2234 | dev_err(&port->dev, "CSIZE was set but not CS7-CS8\n"); |
2255 | } | 2235 | } |
2256 | } | 2236 | } |
2257 | 2237 | ||
@@ -2263,7 +2243,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2263 | FTDI_SIO_SET_DATA_REQUEST, | 2243 | FTDI_SIO_SET_DATA_REQUEST, |
2264 | FTDI_SIO_SET_DATA_REQUEST_TYPE, | 2244 | FTDI_SIO_SET_DATA_REQUEST_TYPE, |
2265 | urb_value , priv->interface, | 2245 | urb_value , priv->interface, |
2266 | buf, 0, WDR_SHORT_TIMEOUT) < 0) { | 2246 | NULL, 0, WDR_SHORT_TIMEOUT) < 0) { |
2267 | dev_err(&port->dev, "%s FAILED to set " | 2247 | dev_err(&port->dev, "%s FAILED to set " |
2268 | "databits/stopbits/parity\n", __func__); | 2248 | "databits/stopbits/parity\n", __func__); |
2269 | } | 2249 | } |
@@ -2275,7 +2255,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2275 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 2255 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
2276 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2256 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2277 | 0, priv->interface, | 2257 | 0, priv->interface, |
2278 | buf, 0, WDR_TIMEOUT) < 0) { | 2258 | NULL, 0, WDR_TIMEOUT) < 0) { |
2279 | dev_err(&port->dev, | 2259 | dev_err(&port->dev, |
2280 | "%s error from disable flowcontrol urb\n", | 2260 | "%s error from disable flowcontrol urb\n", |
2281 | __func__); | 2261 | __func__); |
@@ -2301,7 +2281,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2301 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 2281 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
2302 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2282 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2303 | 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), | 2283 | 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), |
2304 | buf, 0, WDR_TIMEOUT) < 0) { | 2284 | NULL, 0, WDR_TIMEOUT) < 0) { |
2305 | dev_err(&port->dev, | 2285 | dev_err(&port->dev, |
2306 | "urb failed to set to rts/cts flow control\n"); | 2286 | "urb failed to set to rts/cts flow control\n"); |
2307 | } | 2287 | } |
@@ -2333,7 +2313,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2333 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2313 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2334 | urb_value , (FTDI_SIO_XON_XOFF_HS | 2314 | urb_value , (FTDI_SIO_XON_XOFF_HS |
2335 | | priv->interface), | 2315 | | priv->interface), |
2336 | buf, 0, WDR_TIMEOUT) < 0) { | 2316 | NULL, 0, WDR_TIMEOUT) < 0) { |
2337 | dev_err(&port->dev, "urb failed to set to " | 2317 | dev_err(&port->dev, "urb failed to set to " |
2338 | "xon/xoff flow control\n"); | 2318 | "xon/xoff flow control\n"); |
2339 | } | 2319 | } |
@@ -2347,7 +2327,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2347 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 2327 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
2348 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2328 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2349 | 0, priv->interface, | 2329 | 0, priv->interface, |
2350 | buf, 0, WDR_TIMEOUT) < 0) { | 2330 | NULL, 0, WDR_TIMEOUT) < 0) { |
2351 | dev_err(&port->dev, | 2331 | dev_err(&port->dev, |
2352 | "urb failed to clear flow control\n"); | 2332 | "urb failed to clear flow control\n"); |
2353 | } | 2333 | } |
@@ -2361,21 +2341,22 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2361 | { | 2341 | { |
2362 | struct usb_serial_port *port = tty->driver_data; | 2342 | struct usb_serial_port *port = tty->driver_data; |
2363 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 2343 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2364 | unsigned char buf[2]; | 2344 | unsigned char *buf; |
2345 | int len; | ||
2365 | int ret; | 2346 | int ret; |
2366 | 2347 | ||
2367 | dbg("%s TIOCMGET", __func__); | 2348 | dbg("%s TIOCMGET", __func__); |
2349 | |||
2350 | buf = kmalloc(2, GFP_KERNEL); | ||
2351 | if (!buf) | ||
2352 | return -ENOMEM; | ||
2353 | /* | ||
2354 | * The 8U232AM returns a two byte value (the SIO a 1 byte value) in | ||
2355 | * the same format as the data returned from the in point. | ||
2356 | */ | ||
2368 | switch (priv->chip_type) { | 2357 | switch (priv->chip_type) { |
2369 | case SIO: | 2358 | case SIO: |
2370 | /* Request the status from the device */ | 2359 | len = 1; |
2371 | ret = usb_control_msg(port->serial->dev, | ||
2372 | usb_rcvctrlpipe(port->serial->dev, 0), | ||
2373 | FTDI_SIO_GET_MODEM_STATUS_REQUEST, | ||
2374 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | ||
2375 | 0, 0, | ||
2376 | buf, 1, WDR_TIMEOUT); | ||
2377 | if (ret < 0) | ||
2378 | return ret; | ||
2379 | break; | 2360 | break; |
2380 | case FT8U232AM: | 2361 | case FT8U232AM: |
2381 | case FT232BM: | 2362 | case FT232BM: |
@@ -2383,27 +2364,30 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2383 | case FT232RL: | 2364 | case FT232RL: |
2384 | case FT2232H: | 2365 | case FT2232H: |
2385 | case FT4232H: | 2366 | case FT4232H: |
2386 | /* the 8U232AM returns a two byte value (the sio is a 1 byte | 2367 | len = 2; |
2387 | value) - in the same format as the data returned from the in | ||
2388 | point */ | ||
2389 | ret = usb_control_msg(port->serial->dev, | ||
2390 | usb_rcvctrlpipe(port->serial->dev, 0), | ||
2391 | FTDI_SIO_GET_MODEM_STATUS_REQUEST, | ||
2392 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | ||
2393 | 0, priv->interface, | ||
2394 | buf, 2, WDR_TIMEOUT); | ||
2395 | if (ret < 0) | ||
2396 | return ret; | ||
2397 | break; | 2368 | break; |
2398 | default: | 2369 | default: |
2399 | return -EFAULT; | 2370 | ret = -EFAULT; |
2371 | goto out; | ||
2400 | } | 2372 | } |
2401 | 2373 | ||
2402 | return (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | | 2374 | ret = usb_control_msg(port->serial->dev, |
2375 | usb_rcvctrlpipe(port->serial->dev, 0), | ||
2376 | FTDI_SIO_GET_MODEM_STATUS_REQUEST, | ||
2377 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | ||
2378 | 0, priv->interface, | ||
2379 | buf, len, WDR_TIMEOUT); | ||
2380 | if (ret < 0) | ||
2381 | goto out; | ||
2382 | |||
2383 | ret = (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | | ||
2403 | (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | | 2384 | (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | |
2404 | (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | | 2385 | (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | |
2405 | (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | | 2386 | (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | |
2406 | priv->last_dtr_rts; | 2387 | priv->last_dtr_rts; |
2388 | out: | ||
2389 | kfree(buf); | ||
2390 | return ret; | ||
2407 | } | 2391 | } |
2408 | 2392 | ||
2409 | static int ftdi_tiocmset(struct tty_struct *tty, struct file *file, | 2393 | static int ftdi_tiocmset(struct tty_struct *tty, struct file *file, |
@@ -2508,8 +2492,7 @@ void ftdi_unthrottle(struct tty_struct *tty) | |||
2508 | port->throttled = port->throttle_req = 0; | 2492 | port->throttled = port->throttle_req = 0; |
2509 | spin_unlock_irqrestore(&port->lock, flags); | 2493 | spin_unlock_irqrestore(&port->lock, flags); |
2510 | 2494 | ||
2511 | /* Resubmit urb if throttled and open. */ | 2495 | if (was_throttled) |
2512 | if (was_throttled && test_bit(ASYNCB_INITIALIZED, &port->port.flags)) | ||
2513 | ftdi_submit_read_urb(port, GFP_KERNEL); | 2496 | ftdi_submit_read_urb(port, GFP_KERNEL); |
2514 | } | 2497 | } |
2515 | 2498 | ||