diff options
author | Johan Hovold <johan@kernel.org> | 2021-05-19 11:20:02 +0200 |
---|---|---|
committer | Johan Hovold <johan@kernel.org> | 2021-05-21 15:46:02 +0200 |
commit | dcbc0ae4f8fcdd4c873e7a9bac49ab84b0453813 (patch) | |
tree | d34c5782a7773bbf649ebb00f4129ea8263b6be3 | |
parent | 3aed3af202aa2f8246d07875809b9bc07a02131b (diff) |
USB: serial: digi_acceleport: add chars_in_buffer locking
Both the dp_write_urb_in_use flag and dp_out_buf_len counter should be
accessed while holding the driver port lock. Add the missing locking to
chars_in_buffer and clean up the implementation somewhat by using a
common exit path.
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
-rw-r--r-- | drivers/usb/serial/digi_acceleport.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index a4194b70a6fe..754c66ff0fc1 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -1044,17 +1044,19 @@ static unsigned int digi_chars_in_buffer(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct digi_port *priv = usb_get_serial_port_data(port); + unsigned long flags; + unsigned int chars; - if (priv->dp_write_urb_in_use) { - dev_dbg(&port->dev, "digi_chars_in_buffer: port=%d, chars=%d\n", - priv->dp_port_num, port->bulk_out_size - 2); - return port->bulk_out_size - 2; - } else { - dev_dbg(&port->dev, "digi_chars_in_buffer: port=%d, chars=%d\n", - priv->dp_port_num, priv->dp_out_buf_len); - return priv->dp_out_buf_len; - } + spin_lock_irqsave(&priv->dp_port_lock, flags); + if (priv->dp_write_urb_in_use) + chars = port->bulk_out_size - 2; + else + chars = priv->dp_out_buf_len; + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + dev_dbg(&port->dev, "%s: port=%d, chars=%d\n", __func__, + priv->dp_port_num, chars); + return chars; } static void digi_dtr_rts(struct usb_serial_port *port, int on) |