The driver was lacking calls to usb_hcd_link_urb_to_ep(), usb_hcd_unlink_urb_from_ep(), and usb_hcd_check_unlink_urb(). Add those now. Signed-off-by: Paul Zimmerman <paulz@xxxxxxxxxxxx> --- drivers/staging/dwc2/hcd.c | 52 +++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/drivers/staging/dwc2/hcd.c b/drivers/staging/dwc2/hcd.c index e8fb84f5..d72daf1 100644 --- a/drivers/staging/dwc2/hcd.c +++ b/drivers/staging/dwc2/hcd.c @@ -2153,6 +2153,7 @@ void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, urb); } + usb_hcd_unlink_urb_from_ep(dwc2_hsotg_to_hcd(hsotg), urb); urb->hcpriv = NULL; kfree(qtd->urb); qtd->urb = NULL; @@ -2343,8 +2344,8 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, struct usb_host_endpoint *ep = urb->ep; struct dwc2_hcd_urb *dwc2_urb; int i; + int retval; int alloc_bandwidth = 0; - int retval = 0; u8 ep_type = 0; u32 tflags = 0; void *buf; @@ -2426,21 +2427,36 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, urb->iso_frame_desc[i].length); urb->hcpriv = dwc2_urb; - retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, &ep->hcpriv, - mem_flags); - if (retval) { - urb->hcpriv = NULL; - kfree(dwc2_urb); - } else { - if (alloc_bandwidth) { - spin_lock_irqsave(&hsotg->lock, flags); - dwc2_allocate_bus_bandwidth(hcd, - dwc2_hcd_get_ep_bandwidth(hsotg, ep), - urb); - spin_unlock_irqrestore(&hsotg->lock, flags); - } + + spin_lock_irqsave(&hsotg->lock, flags); + retval = usb_hcd_link_urb_to_ep(hcd, urb); + spin_unlock_irqrestore(&hsotg->lock, flags); + if (retval) + goto fail1; + + retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, &ep->hcpriv, mem_flags); + if (retval) + goto fail2; + + if (alloc_bandwidth) { + spin_lock_irqsave(&hsotg->lock, flags); + dwc2_allocate_bus_bandwidth(hcd, + dwc2_hcd_get_ep_bandwidth(hsotg, ep), + urb); + spin_unlock_irqrestore(&hsotg->lock, flags); } + return 0; + +fail2: + spin_lock_irqsave(&hsotg->lock, flags); + dwc2_urb->priv = NULL; + usb_hcd_unlink_urb_from_ep(hcd, urb); + spin_unlock_irqrestore(&hsotg->lock, flags); +fail1: + urb->hcpriv = NULL; + kfree(dwc2_urb); + return retval; } @@ -2451,7 +2467,7 @@ static int _dwc2_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) { struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); - int rc = 0; + int rc; unsigned long flags; dev_dbg(hsotg->dev, "DWC OTG HCD URB Dequeue\n"); @@ -2459,6 +2475,10 @@ static int _dwc2_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, spin_lock_irqsave(&hsotg->lock, flags); + rc = usb_hcd_check_unlink_urb(hcd, urb, status); + if (rc) + goto out; + if (!urb->hcpriv) { dev_dbg(hsotg->dev, "## urb->hcpriv is NULL ##\n"); goto out; @@ -2466,6 +2486,8 @@ static int _dwc2_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, rc = dwc2_hcd_urb_dequeue(hsotg, urb->hcpriv); + usb_hcd_unlink_urb_from_ep(hcd, urb); + kfree(urb->hcpriv); urb->hcpriv = NULL; -- 1.8.2.rc0.16.g20a599e -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html