mirror of https://gitee.com/openkylin/linux.git
USB: serial: cyberjack: fix write-URB completion race
The write-URB busy flag was being cleared before the completion handler
was done with the URB, something which could lead to corrupt transfers
due to a racing write request if the URB is resubmitted.
Fixes: 507ca9bc04
("[PATCH] USB: add ability for usb-serial drivers to determine if their write urb is currently being used.")
Cc: stable <stable@vger.kernel.org> # 2.6.13
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
This commit is contained in:
parent
a46b973bce
commit
985616f045
|
@ -357,11 +357,12 @@ static void cyberjack_write_bulk_callback(struct urb *urb)
|
||||||
struct device *dev = &port->dev;
|
struct device *dev = &port->dev;
|
||||||
int status = urb->status;
|
int status = urb->status;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
bool resubmitted = false;
|
||||||
|
|
||||||
set_bit(0, &port->write_urbs_free);
|
|
||||||
if (status) {
|
if (status) {
|
||||||
dev_dbg(dev, "%s - nonzero write bulk status received: %d\n",
|
dev_dbg(dev, "%s - nonzero write bulk status received: %d\n",
|
||||||
__func__, status);
|
__func__, status);
|
||||||
|
set_bit(0, &port->write_urbs_free);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,6 +395,8 @@ static void cyberjack_write_bulk_callback(struct urb *urb)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resubmitted = true;
|
||||||
|
|
||||||
dev_dbg(dev, "%s - priv->wrsent=%d\n", __func__, priv->wrsent);
|
dev_dbg(dev, "%s - priv->wrsent=%d\n", __func__, priv->wrsent);
|
||||||
dev_dbg(dev, "%s - priv->wrfilled=%d\n", __func__, priv->wrfilled);
|
dev_dbg(dev, "%s - priv->wrfilled=%d\n", __func__, priv->wrfilled);
|
||||||
|
|
||||||
|
@ -410,6 +413,8 @@ static void cyberjack_write_bulk_callback(struct urb *urb)
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
if (!resubmitted)
|
||||||
|
set_bit(0, &port->write_urbs_free);
|
||||||
usb_serial_port_softint(port);
|
usb_serial_port_softint(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue