diff options
author | Johan Hovold <jhovold@gmail.com> | 2013-05-05 14:32:30 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-05-16 20:32:22 -0400 |
commit | a37025b5c702aaf87191cd75fcc42c54454f16f5 (patch) | |
tree | a8a3c2fd4d441b7827a9912d56a15c3acaa7c105 | |
parent | c4133648bbce9e6b425a74cc890c8e4df51acaa9 (diff) |
USB: ftdi_sio: fix chars_in_buffer overhead
Use the new generic usb-serial wait_until_sent implementation to wait
for hardware buffers to drain.
This removes the need to check the hardware buffers in chars_in_buffer
and thus removes the overhead introduced by commit 6f602912 ("usb:
serial: ftdi_sio: Add missing chars_in_buffer function") without
breaking tty_wait_until_sent (used by, for example, tcdrain, tcsendbreak
and close).
Reported-by: Stas Sergeev <stsp@list.ru>
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 19 |
1 files changed, 5 insertions, 14 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 1159fd4cd94d..a62a75a679cd 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -924,7 +924,7 @@ static int ftdi_tiocmset(struct tty_struct *tty, | |||
924 | static int ftdi_ioctl(struct tty_struct *tty, | 924 | static int ftdi_ioctl(struct tty_struct *tty, |
925 | unsigned int cmd, unsigned long arg); | 925 | unsigned int cmd, unsigned long arg); |
926 | static void ftdi_break_ctl(struct tty_struct *tty, int break_state); | 926 | static void ftdi_break_ctl(struct tty_struct *tty, int break_state); |
927 | static int ftdi_chars_in_buffer(struct tty_struct *tty); | 927 | static bool ftdi_tx_empty(struct usb_serial_port *port); |
928 | static int ftdi_get_modem_status(struct usb_serial_port *port, | 928 | static int ftdi_get_modem_status(struct usb_serial_port *port, |
929 | unsigned char status[2]); | 929 | unsigned char status[2]); |
930 | 930 | ||
@@ -961,7 +961,7 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
961 | .ioctl = ftdi_ioctl, | 961 | .ioctl = ftdi_ioctl, |
962 | .set_termios = ftdi_set_termios, | 962 | .set_termios = ftdi_set_termios, |
963 | .break_ctl = ftdi_break_ctl, | 963 | .break_ctl = ftdi_break_ctl, |
964 | .chars_in_buffer = ftdi_chars_in_buffer, | 964 | .tx_empty = ftdi_tx_empty, |
965 | }; | 965 | }; |
966 | 966 | ||
967 | static struct usb_serial_driver * const serial_drivers[] = { | 967 | static struct usb_serial_driver * const serial_drivers[] = { |
@@ -2056,27 +2056,18 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state) | |||
2056 | 2056 | ||
2057 | } | 2057 | } |
2058 | 2058 | ||
2059 | static int ftdi_chars_in_buffer(struct tty_struct *tty) | 2059 | static bool ftdi_tx_empty(struct usb_serial_port *port) |
2060 | { | 2060 | { |
2061 | struct usb_serial_port *port = tty->driver_data; | ||
2062 | int chars; | ||
2063 | unsigned char buf[2]; | 2061 | unsigned char buf[2]; |
2064 | int ret; | 2062 | int ret; |
2065 | 2063 | ||
2066 | chars = usb_serial_generic_chars_in_buffer(tty); | ||
2067 | if (chars) | ||
2068 | goto out; | ||
2069 | |||
2070 | /* Check if hardware buffer is empty. */ | ||
2071 | ret = ftdi_get_modem_status(port, buf); | 2064 | ret = ftdi_get_modem_status(port, buf); |
2072 | if (ret == 2) { | 2065 | if (ret == 2) { |
2073 | if (!(buf[1] & FTDI_RS_TEMT)) | 2066 | if (!(buf[1] & FTDI_RS_TEMT)) |
2074 | chars = 1; | 2067 | return false; |
2075 | } | 2068 | } |
2076 | out: | ||
2077 | dev_dbg(&port->dev, "%s - %d\n", __func__, chars); | ||
2078 | 2069 | ||
2079 | return chars; | 2070 | return true; |
2080 | } | 2071 | } |
2081 | 2072 | ||
2082 | /* old_termios contains the original termios settings and tty->termios contains | 2073 | /* old_termios contains the original termios settings and tty->termios contains |