| From a37025b5c702aaf87191cd75fcc42c54454f16f5 Mon Sep 17 00:00:00 2001 |
| From: Johan Hovold <jhovold@gmail.com> |
| Date: Sun, 5 May 2013 20:32:30 +0200 |
| Subject: USB: ftdi_sio: fix chars_in_buffer overhead |
| |
| From: Johan Hovold <jhovold@gmail.com> |
| |
| commit a37025b5c702aaf87191cd75fcc42c54454f16f5 upstream. |
| |
| 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> |
| |
| --- |
| drivers/usb/serial/ftdi_sio.c | 19 +++++-------------- |
| 1 file changed, 5 insertions(+), 14 deletions(-) |
| |
| --- a/drivers/usb/serial/ftdi_sio.c |
| +++ b/drivers/usb/serial/ftdi_sio.c |
| @@ -931,7 +931,7 @@ static int ftdi_get_icount(struct tty_st |
| static int ftdi_ioctl(struct tty_struct *tty, |
| unsigned int cmd, unsigned long arg); |
| static void ftdi_break_ctl(struct tty_struct *tty, int break_state); |
| -static int ftdi_chars_in_buffer(struct tty_struct *tty); |
| +static bool ftdi_tx_empty(struct usb_serial_port *port); |
| static int ftdi_get_modem_status(struct usb_serial_port *port, |
| unsigned char status[2]); |
| |
| @@ -968,7 +968,7 @@ static struct usb_serial_driver ftdi_sio |
| .ioctl = ftdi_ioctl, |
| .set_termios = ftdi_set_termios, |
| .break_ctl = ftdi_break_ctl, |
| - .chars_in_buffer = ftdi_chars_in_buffer, |
| + .tx_empty = ftdi_tx_empty, |
| }; |
| |
| static struct usb_serial_driver * const serial_drivers[] = { |
| @@ -2092,27 +2092,18 @@ static void ftdi_break_ctl(struct tty_st |
| |
| } |
| |
| -static int ftdi_chars_in_buffer(struct tty_struct *tty) |
| +static bool ftdi_tx_empty(struct usb_serial_port *port) |
| { |
| - struct usb_serial_port *port = tty->driver_data; |
| - int chars; |
| unsigned char buf[2]; |
| int ret; |
| |
| - chars = usb_serial_generic_chars_in_buffer(tty); |
| - if (chars) |
| - goto out; |
| - |
| - /* Check if hardware buffer is empty. */ |
| ret = ftdi_get_modem_status(port, buf); |
| if (ret == 2) { |
| if (!(buf[1] & FTDI_RS_TEMT)) |
| - chars = 1; |
| + return false; |
| } |
| -out: |
| - dev_dbg(&port->dev, "%s - %d\n", __func__, chars); |
| |
| - return chars; |
| + return true; |
| } |
| |
| /* old_termios contains the original termios settings and tty->termios contains |