aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/isp116x-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/isp116x-hcd.c')
-rw-r--r--drivers/usb/host/isp116x-hcd.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 5c851a36de72..d5027dc75a57 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -290,6 +290,7 @@ __releases(isp116x->lock) __acquires(isp116x->lock)
290 290
291 urb_dbg(urb, "Finish"); 291 urb_dbg(urb, "Finish");
292 292
293 usb_hcd_unlink_urb_from_ep(isp116x_to_hcd(isp116x), urb);
293 spin_unlock(&isp116x->lock); 294 spin_unlock(&isp116x->lock);
294 usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb); 295 usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb);
295 spin_lock(&isp116x->lock); 296 spin_lock(&isp116x->lock);
@@ -673,7 +674,7 @@ static int balance(struct isp116x *isp116x, u16 period, u16 load)
673/*-----------------------------------------------------------------*/ 674/*-----------------------------------------------------------------*/
674 675
675static int isp116x_urb_enqueue(struct usb_hcd *hcd, 676static int isp116x_urb_enqueue(struct usb_hcd *hcd,
676 struct usb_host_endpoint *hep, struct urb *urb, 677 struct urb *urb,
677 gfp_t mem_flags) 678 gfp_t mem_flags)
678{ 679{
679 struct isp116x *isp116x = hcd_to_isp116x(hcd); 680 struct isp116x *isp116x = hcd_to_isp116x(hcd);
@@ -682,6 +683,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
682 int is_out = !usb_pipein(pipe); 683 int is_out = !usb_pipein(pipe);
683 int type = usb_pipetype(pipe); 684 int type = usb_pipetype(pipe);
684 int epnum = usb_pipeendpoint(pipe); 685 int epnum = usb_pipeendpoint(pipe);
686 struct usb_host_endpoint *hep = urb->ep;
685 struct isp116x_ep *ep = NULL; 687 struct isp116x_ep *ep = NULL;
686 unsigned long flags; 688 unsigned long flags;
687 int i; 689 int i;
@@ -705,7 +707,12 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
705 if (!HC_IS_RUNNING(hcd->state)) { 707 if (!HC_IS_RUNNING(hcd->state)) {
706 kfree(ep); 708 kfree(ep);
707 ret = -ENODEV; 709 ret = -ENODEV;
708 goto fail; 710 goto fail_not_linked;
711 }
712 ret = usb_hcd_link_urb_to_ep(hcd, urb);
713 if (ret) {
714 kfree(ep);
715 goto fail_not_linked;
709 } 716 }
710 717
711 if (hep->hcpriv) 718 if (hep->hcpriv)
@@ -818,6 +825,9 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
818 start_atl_transfers(isp116x); 825 start_atl_transfers(isp116x);
819 826
820 fail: 827 fail:
828 if (ret)
829 usb_hcd_unlink_urb_from_ep(hcd, urb);
830 fail_not_linked:
821 spin_unlock_irqrestore(&isp116x->lock, flags); 831 spin_unlock_irqrestore(&isp116x->lock, flags);
822 return ret; 832 return ret;
823} 833}
@@ -825,20 +835,21 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
825/* 835/*
826 Dequeue URBs. 836 Dequeue URBs.
827*/ 837*/
828static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) 838static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
839 int status)
829{ 840{
830 struct isp116x *isp116x = hcd_to_isp116x(hcd); 841 struct isp116x *isp116x = hcd_to_isp116x(hcd);
831 struct usb_host_endpoint *hep; 842 struct usb_host_endpoint *hep;
832 struct isp116x_ep *ep, *ep_act; 843 struct isp116x_ep *ep, *ep_act;
833 unsigned long flags; 844 unsigned long flags;
845 int rc;
834 846
835 spin_lock_irqsave(&isp116x->lock, flags); 847 spin_lock_irqsave(&isp116x->lock, flags);
848 rc = usb_hcd_check_unlink_urb(hcd, urb, status);
849 if (rc)
850 goto done;
851
836 hep = urb->hcpriv; 852 hep = urb->hcpriv;
837 /* URB already unlinked (or never linked)? */
838 if (!hep) {
839 spin_unlock_irqrestore(&isp116x->lock, flags);
840 return 0;
841 }
842 ep = hep->hcpriv; 853 ep = hep->hcpriv;
843 WARN_ON(hep != ep->hep); 854 WARN_ON(hep != ep->hep);
844 855
@@ -856,9 +867,9 @@ static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
856 867
857 if (urb) 868 if (urb)
858 finish_request(isp116x, ep, urb); 869 finish_request(isp116x, ep, urb);
859 870 done:
860 spin_unlock_irqrestore(&isp116x->lock, flags); 871 spin_unlock_irqrestore(&isp116x->lock, flags);
861 return 0; 872 return rc;
862} 873}
863 874
864static void isp116x_endpoint_disable(struct usb_hcd *hcd, 875static void isp116x_endpoint_disable(struct usb_hcd *hcd,