diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2010-12-16 16:40:42 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-12-16 16:40:42 -0500 |
| commit | c466cd2bb9cee2e576fc9663b828f51e322d7b4b (patch) | |
| tree | 1a760ce38bca5d2451c414725d25939397186004 | |
| parent | 0247a7bcd4273fa10c4aba9b3f567c659bab2d2b (diff) | |
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>
| -rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 6a50965e23f..2d338737219 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -75,6 +75,7 @@ struct ftdi_private { | |||
| 75 | unsigned long last_dtr_rts; /* saved modem control outputs */ | 75 | unsigned long last_dtr_rts; /* saved modem control outputs */ |
| 76 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ | 76 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ |
| 77 | char prev_status, diff_status; /* Used for TIOCMIWAIT */ | 77 | char prev_status, diff_status; /* Used for TIOCMIWAIT */ |
| 78 | char transmit_empty; /* If transmitter is empty or not */ | ||
| 78 | struct usb_serial_port *port; | 79 | struct usb_serial_port *port; |
| 79 | __u16 interface; /* FT2232C, FT2232H or FT4232H port interface | 80 | __u16 interface; /* FT2232C, FT2232H or FT4232H port interface |
| 80 | (0 for FT232/245) */ | 81 | (0 for FT232/245) */ |
| @@ -1322,6 +1323,23 @@ check_and_exit: | |||
| 1322 | return 0; | 1323 | return 0; |
| 1323 | } | 1324 | } |
| 1324 | 1325 | ||
| 1326 | static int get_lsr_info(struct usb_serial_port *port, | ||
| 1327 | struct serial_struct __user *retinfo) | ||
| 1328 | { | ||
| 1329 | struct ftdi_private *priv = usb_get_serial_port_data(port); | ||
| 1330 | unsigned int result = 0; | ||
| 1331 | |||
| 1332 | if (!retinfo) | ||
| 1333 | return -EFAULT; | ||
| 1334 | |||
| 1335 | if (priv->transmit_empty) | ||
| 1336 | result = TIOCSER_TEMT; | ||
| 1337 | |||
| 1338 | if (copy_to_user(retinfo, &result, sizeof(unsigned int))) | ||
| 1339 | return -EFAULT; | ||
| 1340 | return 0; | ||
| 1341 | } | ||
| 1342 | |||
| 1325 | 1343 | ||
| 1326 | /* Determine type of FTDI chip based on USB config and descriptor. */ | 1344 | /* Determine type of FTDI chip based on USB config and descriptor. */ |
| 1327 | static void ftdi_determine_type(struct usb_serial_port *port) | 1345 | static void ftdi_determine_type(struct usb_serial_port *port) |
| @@ -1871,6 +1889,12 @@ static int ftdi_process_packet(struct tty_struct *tty, | |||
| 1871 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 1889 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
| 1872 | } | 1890 | } |
| 1873 | 1891 | ||
| 1892 | /* save if the transmitter is empty or not */ | ||
| 1893 | if (packet[1] & FTDI_RS_TEMT) | ||
| 1894 | priv->transmit_empty = 1; | ||
| 1895 | else | ||
| 1896 | priv->transmit_empty = 0; | ||
| 1897 | |||
| 1874 | len -= 2; | 1898 | len -= 2; |
| 1875 | if (!len) | 1899 | if (!len) |
| 1876 | return 0; /* status only */ | 1900 | return 0; /* status only */ |
| @@ -2234,6 +2258,9 @@ static int ftdi_ioctl(struct tty_struct *tty, struct file *file, | |||
| 2234 | } | 2258 | } |
| 2235 | } | 2259 | } |
| 2236 | return 0; | 2260 | return 0; |
| 2261 | case TIOCSERGETLSR: | ||
| 2262 | return get_lsr_info(port, (struct serial_struct __user *)arg); | ||
| 2263 | break; | ||
| 2237 | default: | 2264 | default: |
| 2238 | break; | 2265 | break; |
| 2239 | } | 2266 | } |
