Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Johan writes:

USB-serial updates for v4.18-rc1

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

- support for hardware-assisted XON/XOFF output flow control for pl2303
- fix for a long-standing IXON/IXOFF mixup in ftdi_sio
- blacklist of two apparently unused dwm-158 modem interfaces that
confused some user space daemon (option)
- add missing const to a tty helper currently used by USB serial only

Included are also various clean ups.

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

Signed-off-by: Johan Hovold <johan@kernel.org>

+99 -123
+1 -1
drivers/tty/tty_ioctl.c
··· 290 290 * between the two termios structures, or a speed change is needed. 291 291 */ 292 292 293 - int tty_termios_hw_change(struct ktermios *a, struct ktermios *b) 293 + int tty_termios_hw_change(const struct ktermios *a, const struct ktermios *b) 294 294 { 295 295 if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed) 296 296 return 1;
+2 -1
drivers/usb/serial/bus.c
··· 60 60 } 61 61 62 62 minor = port->minor; 63 - tty_dev = tty_register_device(usb_serial_tty_driver, minor, dev); 63 + tty_dev = tty_port_register_device(&port->port, usb_serial_tty_driver, 64 + minor, dev); 64 65 if (IS_ERR(tty_dev)) { 65 66 retval = PTR_ERR(tty_dev); 66 67 goto err_port_remove;
+77 -117
drivers/usb/serial/ftdi_sio.c
··· 54 54 int custom_divisor; /* custom_divisor kludge, this is for 55 55 baud_base (different from what goes to the 56 56 chip!) */ 57 - __u16 last_set_data_urb_value ; 58 - /* the last data state set - needed for doing 59 - * a break 60 - */ 57 + u16 last_set_data_value; /* the last data state set - needed for doing 58 + * a break 59 + */ 61 60 int flags; /* some ASYNC_xxxx flags are supported */ 62 61 unsigned long last_dtr_rts; /* saved modem control outputs */ 63 62 char prev_status; /* Used for TIOCMIWAIT */ 64 63 char transmit_empty; /* If transmitter is empty or not */ 65 - __u16 interface; /* FT2232C, FT2232H or FT4232H port interface 64 + u16 interface; /* FT2232C, FT2232H or FT4232H port interface 66 65 (0 for FT232/245) */ 67 66 68 67 speed_t force_baud; /* if non-zero, force the baud rate to ··· 1062 1063 1063 1064 static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base); 1064 1065 static unsigned short int ftdi_232am_baud_to_divisor(int baud); 1065 - static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base); 1066 - static __u32 ftdi_232bm_baud_to_divisor(int baud); 1067 - static __u32 ftdi_2232h_baud_base_to_divisor(int baud, int base); 1068 - static __u32 ftdi_2232h_baud_to_divisor(int baud); 1066 + static u32 ftdi_232bm_baud_base_to_divisor(int baud, int base); 1067 + static u32 ftdi_232bm_baud_to_divisor(int baud); 1068 + static u32 ftdi_2232h_baud_base_to_divisor(int baud, int base); 1069 + static u32 ftdi_2232h_baud_to_divisor(int baud); 1069 1070 1070 1071 static struct usb_serial_driver ftdi_sio_device = { 1071 1072 .driver = { ··· 1135 1136 return ftdi_232am_baud_base_to_divisor(baud, 48000000); 1136 1137 } 1137 1138 1138 - static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base) 1139 + static u32 ftdi_232bm_baud_base_to_divisor(int baud, int base) 1139 1140 { 1140 1141 static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; 1141 - __u32 divisor; 1142 + u32 divisor; 1142 1143 /* divisor shifted 3 bits to the left */ 1143 1144 int divisor3 = base / 2 / baud; 1144 1145 divisor = divisor3 >> 3; 1145 - divisor |= (__u32)divfrac[divisor3 & 0x7] << 14; 1146 + divisor |= (u32)divfrac[divisor3 & 0x7] << 14; 1146 1147 /* Deal with special cases for highest baud rates. */ 1147 1148 if (divisor == 1) 1148 1149 divisor = 0; ··· 1151 1152 return divisor; 1152 1153 } 1153 1154 1154 - static __u32 ftdi_232bm_baud_to_divisor(int baud) 1155 + static u32 ftdi_232bm_baud_to_divisor(int baud) 1155 1156 { 1156 1157 return ftdi_232bm_baud_base_to_divisor(baud, 48000000); 1157 1158 } 1158 1159 1159 - static __u32 ftdi_2232h_baud_base_to_divisor(int baud, int base) 1160 + static u32 ftdi_2232h_baud_base_to_divisor(int baud, int base) 1160 1161 { 1161 1162 static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; 1162 - __u32 divisor; 1163 + u32 divisor; 1163 1164 int divisor3; 1164 1165 1165 1166 /* hi-speed baud rate is 10-bit sampling instead of 16-bit */ 1166 1167 divisor3 = base * 8 / (baud * 10); 1167 1168 1168 1169 divisor = divisor3 >> 3; 1169 - divisor |= (__u32)divfrac[divisor3 & 0x7] << 14; 1170 + divisor |= (u32)divfrac[divisor3 & 0x7] << 14; 1170 1171 /* Deal with special cases for highest baud rates. */ 1171 1172 if (divisor == 1) 1172 1173 divisor = 0; ··· 1181 1182 return divisor; 1182 1183 } 1183 1184 1184 - static __u32 ftdi_2232h_baud_to_divisor(int baud) 1185 + static u32 ftdi_2232h_baud_to_divisor(int baud) 1185 1186 { 1186 1187 return ftdi_2232h_baud_base_to_divisor(baud, 120000000); 1187 1188 } ··· 1194 1195 { 1195 1196 struct ftdi_private *priv = usb_get_serial_port_data(port); 1196 1197 struct device *dev = &port->dev; 1197 - unsigned urb_value; 1198 + unsigned value; 1198 1199 int rv; 1199 1200 1200 1201 if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) { ··· 1203 1204 } 1204 1205 1205 1206 clear &= ~set; /* 'set' takes precedence over 'clear' */ 1206 - urb_value = 0; 1207 + value = 0; 1207 1208 if (clear & TIOCM_DTR) 1208 - urb_value |= FTDI_SIO_SET_DTR_LOW; 1209 + value |= FTDI_SIO_SET_DTR_LOW; 1209 1210 if (clear & TIOCM_RTS) 1210 - urb_value |= FTDI_SIO_SET_RTS_LOW; 1211 + value |= FTDI_SIO_SET_RTS_LOW; 1211 1212 if (set & TIOCM_DTR) 1212 - urb_value |= FTDI_SIO_SET_DTR_HIGH; 1213 + value |= FTDI_SIO_SET_DTR_HIGH; 1213 1214 if (set & TIOCM_RTS) 1214 - urb_value |= FTDI_SIO_SET_RTS_HIGH; 1215 + value |= FTDI_SIO_SET_RTS_HIGH; 1215 1216 rv = usb_control_msg(port->serial->dev, 1216 1217 usb_sndctrlpipe(port->serial->dev, 0), 1217 1218 FTDI_SIO_SET_MODEM_CTRL_REQUEST, 1218 1219 FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, 1219 - urb_value, priv->interface, 1220 + value, priv->interface, 1220 1221 NULL, 0, WDR_TIMEOUT); 1221 1222 if (rv < 0) { 1222 1223 dev_dbg(dev, "%s Error from MODEM_CTRL urb: DTR %s, RTS %s\n", ··· 1235 1236 } 1236 1237 1237 1238 1238 - static __u32 get_ftdi_divisor(struct tty_struct *tty, 1239 + static u32 get_ftdi_divisor(struct tty_struct *tty, 1239 1240 struct usb_serial_port *port) 1240 1241 { 1241 1242 struct ftdi_private *priv = usb_get_serial_port_data(port); 1242 1243 struct device *dev = &port->dev; 1243 - __u32 div_value = 0; 1244 + u32 div_value = 0; 1244 1245 int div_okay = 1; 1245 1246 int baud; 1246 1247 ··· 1298 1299 case FT232RL: /* FT232RL chip */ 1299 1300 case FTX: /* FT-X series */ 1300 1301 if (baud <= 3000000) { 1301 - __u16 product_id = le16_to_cpu( 1302 + u16 product_id = le16_to_cpu( 1302 1303 port->serial->dev->descriptor.idProduct); 1303 1304 if (((product_id == FTDI_NDI_HUC_PID) || 1304 1305 (product_id == FTDI_NDI_SPECTRA_SCU_PID) || ··· 1345 1346 static int change_speed(struct tty_struct *tty, struct usb_serial_port *port) 1346 1347 { 1347 1348 struct ftdi_private *priv = usb_get_serial_port_data(port); 1348 - __u16 urb_value; 1349 - __u16 urb_index; 1350 - __u32 urb_index_value; 1349 + u16 value; 1350 + u16 index; 1351 + u32 index_value; 1351 1352 int rv; 1352 1353 1353 - urb_index_value = get_ftdi_divisor(tty, port); 1354 - urb_value = (__u16)urb_index_value; 1355 - urb_index = (__u16)(urb_index_value >> 16); 1354 + index_value = get_ftdi_divisor(tty, port); 1355 + value = (u16)index_value; 1356 + index = (u16)(index_value >> 16); 1356 1357 if ((priv->chip_type == FT2232C) || (priv->chip_type == FT2232H) || 1357 1358 (priv->chip_type == FT4232H) || (priv->chip_type == FT232H)) { 1358 1359 /* Probably the BM type needs the MSB of the encoded fractional 1359 1360 * divider also moved like for the chips above. Any infos? */ 1360 - urb_index = (__u16)((urb_index << 8) | priv->interface); 1361 + index = (u16)((index << 8) | priv->interface); 1361 1362 } 1362 1363 1363 1364 rv = usb_control_msg(port->serial->dev, 1364 1365 usb_sndctrlpipe(port->serial->dev, 0), 1365 1366 FTDI_SIO_SET_BAUDRATE_REQUEST, 1366 1367 FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, 1367 - urb_value, urb_index, 1368 + value, index, 1368 1369 NULL, 0, WDR_SHORT_TIMEOUT); 1369 1370 return rv; 1370 1371 } ··· 2139 2140 { 2140 2141 struct usb_serial_port *port = tty->driver_data; 2141 2142 struct ftdi_private *priv = usb_get_serial_port_data(port); 2142 - __u16 urb_value; 2143 + u16 value; 2143 2144 2144 2145 /* break_state = -1 to turn on break, and 0 to turn off break */ 2145 2146 /* see drivers/char/tty_io.c to see it used */ 2146 - /* last_set_data_urb_value NEVER has the break bit set in it */ 2147 + /* last_set_data_value NEVER has the break bit set in it */ 2147 2148 2148 2149 if (break_state) 2149 - urb_value = priv->last_set_data_urb_value | FTDI_SIO_SET_BREAK; 2150 + value = priv->last_set_data_value | FTDI_SIO_SET_BREAK; 2150 2151 else 2151 - urb_value = priv->last_set_data_urb_value; 2152 + value = priv->last_set_data_value; 2152 2153 2153 2154 if (usb_control_msg(port->serial->dev, 2154 2155 usb_sndctrlpipe(port->serial->dev, 0), 2155 2156 FTDI_SIO_SET_DATA_REQUEST, 2156 2157 FTDI_SIO_SET_DATA_REQUEST_TYPE, 2157 - urb_value , priv->interface, 2158 + value , priv->interface, 2158 2159 NULL, 0, WDR_TIMEOUT) < 0) { 2159 2160 dev_err(&port->dev, "%s FAILED to enable/disable break state (state was %d)\n", 2160 2161 __func__, break_state); 2161 2162 } 2162 2163 2163 2164 dev_dbg(&port->dev, "%s break state is %d - urb is %d\n", __func__, 2164 - break_state, urb_value); 2165 + break_state, value); 2165 2166 2166 2167 } 2167 2168 ··· 2191 2192 struct ftdi_private *priv = usb_get_serial_port_data(port); 2192 2193 struct ktermios *termios = &tty->termios; 2193 2194 unsigned int cflag = termios->c_cflag; 2194 - __u16 urb_value; /* will hold the new flags */ 2195 - 2196 - /* Added for xon/xoff support */ 2197 - unsigned int iflag = termios->c_iflag; 2198 - unsigned char vstop; 2199 - unsigned char vstart; 2195 + u16 value, index; 2196 + int ret; 2200 2197 2201 2198 /* Force baud rate if this device requires it, unless it is set to 2202 2199 B0. */ ··· 2253 2258 no_skip: 2254 2259 /* Set number of data bits, parity, stop bits */ 2255 2260 2256 - urb_value = 0; 2257 - urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : 2258 - FTDI_SIO_SET_DATA_STOP_BITS_1); 2261 + value = 0; 2262 + value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : 2263 + FTDI_SIO_SET_DATA_STOP_BITS_1); 2259 2264 if (cflag & PARENB) { 2260 2265 if (cflag & CMSPAR) 2261 - urb_value |= cflag & PARODD ? 2262 - FTDI_SIO_SET_DATA_PARITY_MARK : 2263 - FTDI_SIO_SET_DATA_PARITY_SPACE; 2266 + value |= cflag & PARODD ? 2267 + FTDI_SIO_SET_DATA_PARITY_MARK : 2268 + FTDI_SIO_SET_DATA_PARITY_SPACE; 2264 2269 else 2265 - urb_value |= cflag & PARODD ? 2266 - FTDI_SIO_SET_DATA_PARITY_ODD : 2267 - FTDI_SIO_SET_DATA_PARITY_EVEN; 2270 + value |= cflag & PARODD ? 2271 + FTDI_SIO_SET_DATA_PARITY_ODD : 2272 + FTDI_SIO_SET_DATA_PARITY_EVEN; 2268 2273 } else { 2269 - urb_value |= FTDI_SIO_SET_DATA_PARITY_NONE; 2274 + value |= FTDI_SIO_SET_DATA_PARITY_NONE; 2270 2275 } 2271 2276 switch (cflag & CSIZE) { 2272 2277 case CS5: 2273 2278 dev_dbg(ddev, "Setting CS5 quirk\n"); 2274 2279 break; 2275 2280 case CS7: 2276 - urb_value |= 7; 2281 + value |= 7; 2277 2282 dev_dbg(ddev, "Setting CS7\n"); 2278 2283 break; 2279 2284 default: 2280 2285 case CS8: 2281 - urb_value |= 8; 2286 + value |= 8; 2282 2287 dev_dbg(ddev, "Setting CS8\n"); 2283 2288 break; 2284 2289 } 2285 2290 2286 2291 /* This is needed by the break command since it uses the same command 2287 2292 - but is or'ed with this value */ 2288 - priv->last_set_data_urb_value = urb_value; 2293 + priv->last_set_data_value = value; 2289 2294 2290 2295 if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 2291 2296 FTDI_SIO_SET_DATA_REQUEST, 2292 2297 FTDI_SIO_SET_DATA_REQUEST_TYPE, 2293 - urb_value , priv->interface, 2298 + value , priv->interface, 2294 2299 NULL, 0, WDR_SHORT_TIMEOUT) < 0) { 2295 2300 dev_err(ddev, "%s FAILED to set databits/stopbits/parity\n", 2296 2301 __func__); ··· 2321 2326 set_mctrl(port, TIOCM_DTR | TIOCM_RTS); 2322 2327 } 2323 2328 2324 - /* Set flow control */ 2325 - /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ 2326 2329 no_c_cflag_changes: 2327 - if (cflag & CRTSCTS) { 2328 - dev_dbg(ddev, "%s Setting to CRTSCTS flow control\n", __func__); 2329 - if (usb_control_msg(dev, 2330 - usb_sndctrlpipe(dev, 0), 2331 - FTDI_SIO_SET_FLOW_CTRL_REQUEST, 2332 - FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 2333 - 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), 2334 - NULL, 0, WDR_TIMEOUT) < 0) { 2335 - dev_err(ddev, "urb failed to set to rts/cts flow control\n"); 2336 - } 2337 - } else { 2338 - /* 2339 - * Xon/Xoff code 2340 - * 2341 - * Check the IXOFF status in the iflag component of the 2342 - * termios structure. If IXOFF is not set, the pre-xon/xoff 2343 - * code is executed. 2344 - */ 2345 - if (iflag & IXOFF) { 2346 - dev_dbg(ddev, "%s request to enable xonxoff iflag=%04x\n", 2347 - __func__, iflag); 2348 - /* Try to enable the XON/XOFF on the ftdi_sio 2349 - * Set the vstart and vstop -- could have been done up 2350 - * above where a lot of other dereferencing is done but 2351 - * that would be very inefficient as vstart and vstop 2352 - * are not always needed. 2353 - */ 2354 - vstart = termios->c_cc[VSTART]; 2355 - vstop = termios->c_cc[VSTOP]; 2356 - urb_value = (vstop << 8) | (vstart); 2330 + /* Set hardware-assisted flow control */ 2331 + value = 0; 2357 2332 2358 - if (usb_control_msg(dev, 2359 - usb_sndctrlpipe(dev, 0), 2360 - FTDI_SIO_SET_FLOW_CTRL_REQUEST, 2361 - FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 2362 - urb_value , (FTDI_SIO_XON_XOFF_HS 2363 - | priv->interface), 2364 - NULL, 0, WDR_TIMEOUT) < 0) { 2365 - dev_err(&port->dev, "urb failed to set to " 2366 - "xon/xoff flow control\n"); 2367 - } 2368 - } else { 2369 - /* else clause to only run if cflag ! CRTSCTS and iflag 2370 - * ! XOFF. CHECKME Assuming XON/XOFF handled by tty 2371 - * stack - not by device */ 2372 - dev_dbg(ddev, "%s Turning off hardware flow control\n", __func__); 2373 - if (usb_control_msg(dev, 2374 - usb_sndctrlpipe(dev, 0), 2375 - FTDI_SIO_SET_FLOW_CTRL_REQUEST, 2376 - FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 2377 - 0, priv->interface, 2378 - NULL, 0, WDR_TIMEOUT) < 0) { 2379 - dev_err(ddev, "urb failed to clear flow control\n"); 2380 - } 2381 - } 2333 + if (C_CRTSCTS(tty)) { 2334 + dev_dbg(&port->dev, "enabling rts/cts flow control\n"); 2335 + index = FTDI_SIO_RTS_CTS_HS; 2336 + } else if (I_IXON(tty)) { 2337 + dev_dbg(&port->dev, "enabling xon/xoff flow control\n"); 2338 + index = FTDI_SIO_XON_XOFF_HS; 2339 + value = STOP_CHAR(tty) << 8 | START_CHAR(tty); 2340 + } else { 2341 + dev_dbg(&port->dev, "disabling flow control\n"); 2342 + index = FTDI_SIO_DISABLE_FLOW_CTRL; 2382 2343 } 2344 + 2345 + index |= priv->interface; 2346 + 2347 + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 2348 + FTDI_SIO_SET_FLOW_CTRL_REQUEST, 2349 + FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, 2350 + value, index, NULL, 0, WDR_TIMEOUT); 2351 + if (ret < 0) 2352 + dev_err(&port->dev, "failed to set flow control: %d\n", ret); 2383 2353 } 2384 2354 2385 2355 /*
+2 -1
drivers/usb/serial/option.c
··· 1916 1916 { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d01, 0xff) }, /* D-Link DWM-156 (variant) */ 1917 1917 { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d02, 0xff) }, 1918 1918 { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d03, 0xff) }, 1919 - { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */ 1919 + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff), /* D-Link DWM-158 */ 1920 + .driver_info = RSVD(4) | RSVD(5) }, 1920 1921 { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d0e, 0xff) }, /* D-Link DWM-157 C1 */ 1921 1922 { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */ 1922 1923 .driver_info = RSVD(4) },
+15 -1
drivers/usb/serial/pl2303.c
··· 533 533 return 0; 534 534 } 535 535 536 + static bool pl2303_termios_change(const struct ktermios *a, const struct ktermios *b) 537 + { 538 + bool ixon_change; 539 + 540 + ixon_change = ((a->c_iflag ^ b->c_iflag) & (IXON | IXANY)) || 541 + a->c_cc[VSTART] != b->c_cc[VSTART] || 542 + a->c_cc[VSTOP] != b->c_cc[VSTOP]; 543 + 544 + return tty_termios_hw_change(a, b) || ixon_change; 545 + } 546 + 536 547 static void pl2303_set_termios(struct tty_struct *tty, 537 548 struct usb_serial_port *port, struct ktermios *old_termios) 538 549 { ··· 555 544 int ret; 556 545 u8 control; 557 546 558 - if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios)) 547 + if (old_termios && !pl2303_termios_change(&tty->termios, old_termios)) 559 548 return; 560 549 561 550 buf = kzalloc(7, GFP_KERNEL); ··· 673 662 pl2303_vendor_write(serial, 0x0, 0x41); 674 663 else 675 664 pl2303_vendor_write(serial, 0x0, 0x61); 665 + } else if (I_IXON(tty) && !I_IXANY(tty) && START_CHAR(tty) == 0x11 && 666 + STOP_CHAR(tty) == 0x13) { 667 + pl2303_vendor_write(serial, 0x0, 0xc0); 676 668 } else { 677 669 pl2303_vendor_write(serial, 0x0, 0x0); 678 670 }
+1 -1
drivers/usb/serial/usb-serial.c
··· 192 192 if (retval) 193 193 goto error_get_interface; 194 194 195 - retval = tty_port_install(&port->port, driver, tty); 195 + retval = tty_standard_install(driver, tty); 196 196 if (retval) 197 197 goto error_init_termios; 198 198
+1 -1
include/linux/tty.h
··· 527 527 } 528 528 529 529 extern void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old); 530 - extern int tty_termios_hw_change(struct ktermios *a, struct ktermios *b); 530 + extern int tty_termios_hw_change(const struct ktermios *a, const struct ktermios *b); 531 531 extern int tty_set_termios(struct tty_struct *tty, struct ktermios *kt); 532 532 533 533 extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *);