aboutsummaryrefslogtreecommitdiff
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-01-20 16:01:49 -0800
commitb92a5e23737172c52656a090977408a80d7f06d1 (patch)
tree1232bd42923d3cc4e31bafb8fa92c5d1d214be55 /drivers/staging/usbip/vhci_rx.c
parent7606ee8aa33287dd3e6eb44c78541b87a413a325 (diff)
staging: usbip: vhci: give back URBs from in-flight unlink requests
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 8147d7202b2..bdbedd25690 100644
--- a/drivers/staging/usbip/vhci_rx.c
+++ b/drivers/staging/usbip/vhci_rx.c
@@ -23,16 +23,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;
@@ -63,8 +61,6 @@ static struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
}
}
- spin_unlock(&vdev->priv_lock);
-
return urb;
}
@@ -74,9 +70,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",
@@ -161,7 +159,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