diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index a817ced82835..ca92f67747cc 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -208,18 +208,23 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port) urb->transfer_buffer_length = count; usb_serial_debug_data(debug, &port->dev, __func__, count, urb->transfer_buffer); + spin_lock_irqsave(&port->lock, flags); + port->tx_bytes += count; + spin_unlock_irqrestore(&port->lock, flags); + + clear_bit(i, &port->write_urbs_free); result = usb_submit_urb(urb, GFP_ATOMIC); if (result) { dev_err(&port->dev, "%s - error submitting urb: %d\n", __func__, result); + set_bit(i, &port->write_urbs_free); + spin_lock_irqsave(&port->lock, flags); + port->tx_bytes -= count; + spin_unlock_irqrestore(&port->lock, flags); + clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); return result; } - clear_bit(i, &port->write_urbs_free); - - spin_lock_irqsave(&port->lock, flags); - port->tx_bytes += count; - spin_unlock_irqrestore(&port->lock, flags); /* Try sending off another urb, unless in irq context (in which case * there will be no free urb). */