urb_dbg(urb, "Finish");
+ usb_hcd_unlink_urb_from_ep(isp116x_to_hcd(isp116x), urb);
spin_unlock(&isp116x->lock);
usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb);
spin_lock(&isp116x->lock);
/*-----------------------------------------------------------------*/
static int isp116x_urb_enqueue(struct usb_hcd *hcd,
- struct usb_host_endpoint *hep, struct urb *urb,
+ struct urb *urb,
gfp_t mem_flags)
{
struct isp116x *isp116x = hcd_to_isp116x(hcd);
int is_out = !usb_pipein(pipe);
int type = usb_pipetype(pipe);
int epnum = usb_pipeendpoint(pipe);
+ struct usb_host_endpoint *hep = urb->ep;
struct isp116x_ep *ep = NULL;
unsigned long flags;
int i;
if (!HC_IS_RUNNING(hcd->state)) {
kfree(ep);
ret = -ENODEV;
- goto fail;
+ goto fail_not_linked;
+ }
+ ret = usb_hcd_link_urb_to_ep(hcd, urb);
+ if (ret) {
+ kfree(ep);
+ goto fail_not_linked;
}
if (hep->hcpriv)
start_atl_transfers(isp116x);
fail:
+ if (ret)
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
+ fail_not_linked:
spin_unlock_irqrestore(&isp116x->lock, flags);
return ret;
}
/*
Dequeue URBs.
*/
-static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
+static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
+ int status)
{
struct isp116x *isp116x = hcd_to_isp116x(hcd);
struct usb_host_endpoint *hep;
struct isp116x_ep *ep, *ep_act;
unsigned long flags;
+ int rc;
spin_lock_irqsave(&isp116x->lock, flags);
+ rc = usb_hcd_check_unlink_urb(hcd, urb, status);
+ if (rc)
+ goto done;
+
hep = urb->hcpriv;
- /* URB already unlinked (or never linked)? */
- if (!hep) {
- spin_unlock_irqrestore(&isp116x->lock, flags);
- return 0;
- }
ep = hep->hcpriv;
WARN_ON(hep != ep->hep);
if (urb)
finish_request(isp116x, ep, urb);
-
+ done:
spin_unlock_irqrestore(&isp116x->lock, flags);
- return 0;
+ return rc;
}
static void isp116x_endpoint_disable(struct usb_hcd *hcd,