summaryrefslogtreecommitdiff
path: root/drivers/staging/usbip/vhci_rx.c
diff options
context:
space:
mode:
authorMax Vozeler <max@vozeler.com>2011-01-12 15:02:01 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2011-03-02 09:47:03 -0500
commitb076e7069f1c8d4c816f88065123f63669f2785e (patch)
tree4058febb90c915878f1b17f792306d6b65aa08ea /drivers/staging/usbip/vhci_rx.c
parent96ea4801d2035f89fc4ec4a67f49a18c35cb6715 (diff)
staging: usbip: vhci: give back URBs from in-flight unlink requests
commit b92a5e23737172c52656a090977408a80d7f06d1 upstream. If we never received a RET_UNLINK because the TCP connection broke the pending URBs still need to be unlinked and given back. Previously processes would be stuck trying to kill the URB even after the device was detached. Signed-off-by: Max Vozeler <max@vozeler.com> Tested-by: Mark Wehby <MWehby@luxotticaRetail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/usbip/vhci_rx.c')
-rw-r--r--drivers/staging/usbip/vhci_rx.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c
index 7636d86c2388..2d989c487f61 100644
--- a/drivers/staging/usbip/vhci_rx.c
+++ b/drivers/staging/usbip/vhci_rx.c
@@ -21,16 +21,14 @@
#include "vhci.h"
-/* get URB from transmitted urb queue */
-static struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
+/* get URB from transmitted urb queue. caller must hold vdev->priv_lock */
+struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
__u32 seqnum)
{
struct vhci_priv *priv, *tmp;
struct urb *urb = NULL;
int status;
- spin_lock(&vdev->priv_lock);
-
list_for_each_entry_safe(priv, tmp, &vdev->priv_rx, list) {
if (priv->seqnum == seqnum) {
urb = priv->urb;
@@ -61,8 +59,6 @@ static struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
}
}
- spin_unlock(&vdev->priv_lock);
-
return urb;
}
@@ -72,9 +68,11 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
struct usbip_device *ud = &vdev->ud;
struct urb *urb;
+ spin_lock(&vdev->priv_lock);
urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum);
+ spin_unlock(&vdev->priv_lock);
if (!urb) {
usbip_uerr("cannot find a urb of seqnum %u\n",
@@ -159,7 +157,12 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
return;
}
+ spin_lock(&vdev->priv_lock);
+
urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
+
+ spin_unlock(&vdev->priv_lock);
+
if (!urb) {
/*
* I get the result of a unlink request. But, it seems that I