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

USB: serial: ftdi_sio: add support for TIOCSERGETLSR

Willem-Jan noticed that the ftdi_sio driver did not support the
TIOCSERGETLSR ioctl, and some userspace programs rely on it. This patch
adds the support.

Reported-by: Willem-Jan de Hoog <wdehoog@exalondelft.nl>
Tested-by: Willem-Jan de Hoog <wdehoog@exalondelft.nl>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

+27
+27
drivers/usb/serial/ftdi_sio.c
··· 75 75 unsigned long last_dtr_rts; /* saved modem control outputs */ 76 76 wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ 77 77 char prev_status, diff_status; /* Used for TIOCMIWAIT */ 78 + char transmit_empty; /* If transmitter is empty or not */ 78 79 struct usb_serial_port *port; 79 80 __u16 interface; /* FT2232C, FT2232H or FT4232H port interface 80 81 (0 for FT232/245) */ ··· 1323 1322 return 0; 1324 1323 } 1325 1324 1325 + static int get_lsr_info(struct usb_serial_port *port, 1326 + struct serial_struct __user *retinfo) 1327 + { 1328 + struct ftdi_private *priv = usb_get_serial_port_data(port); 1329 + unsigned int result = 0; 1330 + 1331 + if (!retinfo) 1332 + return -EFAULT; 1333 + 1334 + if (priv->transmit_empty) 1335 + result = TIOCSER_TEMT; 1336 + 1337 + if (copy_to_user(retinfo, &result, sizeof(unsigned int))) 1338 + return -EFAULT; 1339 + return 0; 1340 + } 1341 + 1326 1342 1327 1343 /* Determine type of FTDI chip based on USB config and descriptor. */ 1328 1344 static void ftdi_determine_type(struct usb_serial_port *port) ··· 1889 1871 tty_insert_flip_char(tty, 0, TTY_OVERRUN); 1890 1872 } 1891 1873 1874 + /* save if the transmitter is empty or not */ 1875 + if (packet[1] & FTDI_RS_TEMT) 1876 + priv->transmit_empty = 1; 1877 + else 1878 + priv->transmit_empty = 0; 1879 + 1892 1880 len -= 2; 1893 1881 if (!len) 1894 1882 return 0; /* status only */ ··· 2258 2234 } 2259 2235 } 2260 2236 return 0; 2237 + case TIOCSERGETLSR: 2238 + return get_lsr_info(port, (struct serial_struct __user *)arg); 2239 + break; 2261 2240 default: 2262 2241 break; 2263 2242 }