--- x/drivers/usb/usbip/vhci_hcd.c +++ y/drivers/usb/usbip/vhci_hcd.c @@ -890,6 +890,7 @@ static int vhci_urb_dequeue(struct usb_h spin_unlock_irqrestore(&vhci->lock, flags); return ret; } + usb_hcd_unlink_urb_from_ep(hcd, urb); } /* send unlink request here? */ @@ -910,23 +911,20 @@ static int vhci_urb_dequeue(struct usb_h * vhci_rx will receive RET_UNLINK and give back the URB. * Otherwise, we give back it here. */ - usb_hcd_unlink_urb_from_ep(hcd, urb); - - spin_unlock_irqrestore(&vhci->lock, flags); - usb_hcd_giveback_urb(hcd, urb, urb->status); - spin_lock_irqsave(&vhci->lock, flags); - } else { /* tcp connection is alive */ struct vhci_unlink *unlink; spin_lock(&vdev->priv_lock); + list_del(&priv->list); /* setup CMD_UNLINK pdu */ unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC); if (!unlink) { spin_unlock(&vdev->priv_lock); spin_unlock_irqrestore(&vhci->lock, flags); + usb_hcd_giveback_urb(hcd, urb, urb->status); + kfree(priv); usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); return -ENOMEM; } @@ -943,10 +941,12 @@ static int vhci_urb_dequeue(struct usb_h wake_up(&vdev->waitq_tx); spin_unlock(&vdev->priv_lock); + kfree(priv); } spin_unlock_irqrestore(&vhci->lock, flags); + usb_hcd_giveback_urb(hcd, urb, urb->status); usbip_dbg_vhci_hc("leave\n"); return 0; }