@@ -945,7 +945,8 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
return 0;
}
-static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
+static void vhci_cleanup_unlink_list(struct vhci_device *vdev,
+ struct list_head *unlink_list)
{
struct vhci_hcd *vhci_hcd = vdev_to_vhci_hcd(vdev);
struct usb_hcd *hcd = vhci_hcd_to_hcd(vhci_hcd);
@@ -956,46 +957,15 @@ static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
spin_lock_irqsave(&vhci->lock, flags);
spin_lock(&vdev->priv_lock);
- list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
+ list_for_each_entry_safe(unlink, tmp, unlink_list, list) {
struct urb *urb;
- /* give back urb of unsent unlink request */
- pr_info("unlink cleanup tx %lu\n", unlink->unlink_seqnum);
-
- urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
- if (!urb) {
- pr_info("the urb (seqnum %lu) was already given back\n",
- unlink->unlink_seqnum);
- list_del(&unlink->list);
- kfree(unlink);
- continue;
- }
-
- urb->status = -ENODEV;
-
- usb_hcd_unlink_urb_from_ep(hcd, urb);
-
- list_del(&unlink->list);
-
- spin_unlock(&vdev->priv_lock);
- spin_unlock_irqrestore(&vhci->lock, flags);
-
- usb_hcd_giveback_urb(hcd, urb, urb->status);
-
- spin_lock_irqsave(&vhci->lock, flags);
- spin_lock(&vdev->priv_lock);
-
- kfree(unlink);
- }
-
- while (!list_empty(&vdev->unlink_rx)) {
- struct urb *urb;
-
- unlink = list_first_entry(&vdev->unlink_rx, struct vhci_unlink,
- list);
-
- /* give back URB of unanswered unlink request */
- pr_info("unlink cleanup rx %lu\n", unlink->unlink_seqnum);
+ if (unlink_list == &vdev->unlink_tx)
+ pr_info("unlink cleanup tx %lu\n",
+ unlink->unlink_seqnum);
+ else
+ pr_info("unlink_cleanup rx %lu\n",
+ unlink->unlink_seqnum);
urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
if (!urb) {
@@ -1027,6 +997,15 @@ static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
spin_unlock_irqrestore(&vhci->lock, flags);
}
+static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
+{
+ /* give back URB of unsent unlink request */
+ vhci_cleanup_unlink_list(vdev, &vdev->unlink_tx);
+
+ /* give back URB of unanswered unlink request */
+ vhci_cleanup_unlink_list(vdev, &vdev->unlink_rx);
+}
+
/*
* The important thing is that only one context begins cleanup.
* This is why error handling and cleanup become simple.
The cleanup code for unlink_tx and unlink_rx lists is almost the same. So, extract it into a new function and call it for both unlink_rx and unlink_tx. Signed-off-by: Anirudh Rayabharam <mail@anirudhrb.com> --- drivers/usb/usbip/vhci_hcd.c | 57 ++++++++++++------------------------ 1 file changed, 18 insertions(+), 39 deletions(-)