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 /drivers/usb | |
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>
Diffstat (limited to 'drivers/usb')
-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 6a50965e23f2..2d338737219e 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 | } |