Messages in this thread Patch in this message | | | From | Peter Hurley <> | Subject | [PATCH 10/11] staging/fwserial: Fix premature unthrottle | Date | Mon, 28 Jan 2013 22:34:44 -0500 |
| |
The unthrottle may restart the writer before the rx push has a chance to start emptying the rx buffer, resulting in an overflowed rx buffer and lost data.
Perform the actual device unthrottle with the rx push instead.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com> --- drivers/staging/fwserial/fwserial.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 912ab77..121beff 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -463,6 +463,14 @@ static void __fwtty_throttle(struct fwtty_port *port, struct tty_struct *tty) __fwtty_write_port_status(port); } +static void __fwtty_unthrottle(struct fwtty_port *port, struct tty_struct *tty) +{ + port->mctrl &= ~OOB_RX_THROTTLE; + if (C_CRTSCTS(tty)) + port->mctrl |= TIOCM_RTS; + __fwtty_write_port_status(port); +} + /** * fwtty_do_hangup - wait for ldisc to deliver all pending rx; only then hangup * @@ -527,14 +535,15 @@ static void fwtty_emit_breaks(struct work_struct *work) port->icount.brk += brk; } -static void fwtty_pushrx(struct work_struct *work) +static void fwtty_pushrx(struct fwtty_port *port, struct tty_struct *tty) { - struct fwtty_port *port = to_port(work, push); - struct tty_struct *tty; struct buffered_rx *buf, *next; int n, c = 0; spin_lock_bh(&port->lock); + + __fwtty_unthrottle(port, tty); + list_for_each_entry_safe(buf, next, &port->buf_list, list) { n = tty_insert_flip_string_fixed_flag(&port->port, buf->data, TTY_NORMAL, buf->n); @@ -545,11 +554,7 @@ static void fwtty_pushrx(struct work_struct *work) memmove(buf->data, buf->data + n, buf->n - n); buf->n -= n; } - tty = tty_port_tty_get(&port->port); - if (tty) { - __fwtty_throttle(port, tty); - tty_kref_put(tty); - } + __fwtty_throttle(port, tty); break; } else { list_del(&buf->list); @@ -1264,14 +1269,7 @@ static void fwtty_unthrottle(struct tty_struct *tty) profile_fifo_avail(port, port->stats.unthrottle); - schedule_work(&port->push); - - spin_lock_bh(&port->lock); - port->mctrl &= ~OOB_RX_THROTTLE; - if (C_CRTSCTS(tty)) - port->mctrl |= TIOCM_RTS; - __fwtty_write_port_status(port); - spin_unlock_bh(&port->lock); + fwtty_pushrx(port, tty); } static int check_msr_delta(struct fwtty_port *port, unsigned long mask, -- 1.8.1.1
| |