Commit b374487e authored by Thomas Pugliese's avatar Thomas Pugliese Committed by Greg Kroah-Hartman

usb: wusbcore: add calls to usb_hcd_link_urb_to_ep, usb_hcd_unlink_urb_from_ep, and

Add calls to usb_hcd_link_urb_to_ep, usb_hcd_unlink_urb_from_ep, and
usb_hcd_check_unlink_urb in the appropriate locations.
Signed-off-by: default avatarThomas Pugliese <thomas.pugliese@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d2e3d2b3
...@@ -224,7 +224,7 @@ static int hwahc_op_urb_dequeue(struct usb_hcd *usb_hcd, struct urb *urb, ...@@ -224,7 +224,7 @@ static int hwahc_op_urb_dequeue(struct usb_hcd *usb_hcd, struct urb *urb,
struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
return wa_urb_dequeue(&hwahc->wa, urb); return wa_urb_dequeue(&hwahc->wa, urb, status);
} }
/* /*
......
...@@ -332,7 +332,7 @@ static inline int rpipe_avail_inc(struct wa_rpipe *rpipe) ...@@ -332,7 +332,7 @@ static inline int rpipe_avail_inc(struct wa_rpipe *rpipe)
/* Transferring data */ /* Transferring data */
extern int wa_urb_enqueue(struct wahc *, struct usb_host_endpoint *, extern int wa_urb_enqueue(struct wahc *, struct usb_host_endpoint *,
struct urb *, gfp_t); struct urb *, gfp_t);
extern int wa_urb_dequeue(struct wahc *, struct urb *); extern int wa_urb_dequeue(struct wahc *, struct urb *, int);
extern void wa_handle_notif_xfer(struct wahc *, struct wa_notif_hdr *); extern void wa_handle_notif_xfer(struct wahc *, struct wa_notif_hdr *);
......
...@@ -282,6 +282,7 @@ static void wa_xfer_giveback(struct wa_xfer *xfer) ...@@ -282,6 +282,7 @@ static void wa_xfer_giveback(struct wa_xfer *xfer)
spin_lock_irqsave(&xfer->wa->xfer_list_lock, flags); spin_lock_irqsave(&xfer->wa->xfer_list_lock, flags);
list_del_init(&xfer->list_node); list_del_init(&xfer->list_node);
usb_hcd_unlink_urb_from_ep(&(xfer->wa->wusb->usb_hcd), xfer->urb);
spin_unlock_irqrestore(&xfer->wa->xfer_list_lock, flags); spin_unlock_irqrestore(&xfer->wa->xfer_list_lock, flags);
/* FIXME: segmentation broken -- kills DWA */ /* FIXME: segmentation broken -- kills DWA */
wusbhc_giveback_urb(xfer->wa->wusb, xfer->urb, xfer->result); wusbhc_giveback_urb(xfer->wa->wusb, xfer->urb, xfer->result);
...@@ -1730,6 +1731,12 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep, ...@@ -1730,6 +1731,12 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep,
dump_stack(); dump_stack();
} }
spin_lock_irqsave(&wa->xfer_list_lock, my_flags);
result = usb_hcd_link_urb_to_ep(&(wa->wusb->usb_hcd), urb);
spin_unlock_irqrestore(&wa->xfer_list_lock, my_flags);
if (result < 0)
goto error_link_urb;
result = -ENOMEM; result = -ENOMEM;
xfer = kzalloc(sizeof(*xfer), gfp); xfer = kzalloc(sizeof(*xfer), gfp);
if (xfer == NULL) if (xfer == NULL)
...@@ -1769,6 +1776,9 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep, ...@@ -1769,6 +1776,9 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep,
__func__, result); __func__, result);
wa_put(xfer->wa); wa_put(xfer->wa);
wa_xfer_put(xfer); wa_xfer_put(xfer);
spin_lock_irqsave(&wa->xfer_list_lock, my_flags);
usb_hcd_unlink_urb_from_ep(&(wa->wusb->usb_hcd), urb);
spin_unlock_irqrestore(&wa->xfer_list_lock, my_flags);
return result; return result;
} }
} }
...@@ -1777,6 +1787,10 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep, ...@@ -1777,6 +1787,10 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep,
error_dequeued: error_dequeued:
kfree(xfer); kfree(xfer);
error_kmalloc: error_kmalloc:
spin_lock_irqsave(&wa->xfer_list_lock, my_flags);
usb_hcd_unlink_urb_from_ep(&(wa->wusb->usb_hcd), urb);
spin_unlock_irqrestore(&wa->xfer_list_lock, my_flags);
error_link_urb:
return result; return result;
} }
EXPORT_SYMBOL_GPL(wa_urb_enqueue); EXPORT_SYMBOL_GPL(wa_urb_enqueue);
...@@ -1799,7 +1813,7 @@ EXPORT_SYMBOL_GPL(wa_urb_enqueue); ...@@ -1799,7 +1813,7 @@ EXPORT_SYMBOL_GPL(wa_urb_enqueue);
* asynch request] and then make sure we cancel each segment. * asynch request] and then make sure we cancel each segment.
* *
*/ */
int wa_urb_dequeue(struct wahc *wa, struct urb *urb) int wa_urb_dequeue(struct wahc *wa, struct urb *urb, int status)
{ {
unsigned long flags, flags2; unsigned long flags, flags2;
struct wa_xfer *xfer; struct wa_xfer *xfer;
...@@ -1807,6 +1821,14 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb) ...@@ -1807,6 +1821,14 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb)
struct wa_rpipe *rpipe; struct wa_rpipe *rpipe;
unsigned cnt, done = 0, xfer_abort_pending; unsigned cnt, done = 0, xfer_abort_pending;
unsigned rpipe_ready = 0; unsigned rpipe_ready = 0;
int result;
/* check if it is safe to unlink. */
spin_lock_irqsave(&wa->xfer_list_lock, flags);
result = usb_hcd_check_unlink_urb(&(wa->wusb->usb_hcd), urb, status);
spin_unlock_irqrestore(&wa->xfer_list_lock, flags);
if (result)
return result;
xfer = urb->hcpriv; xfer = urb->hcpriv;
if (xfer == NULL) { if (xfer == NULL) {
...@@ -2172,7 +2194,7 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer, ...@@ -2172,7 +2194,7 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer,
error_bad_seg: error_bad_seg:
spin_unlock_irqrestore(&xfer->lock, flags); spin_unlock_irqrestore(&xfer->lock, flags);
wa_urb_dequeue(wa, xfer->urb); wa_urb_dequeue(wa, xfer->urb, -ENOENT);
if (printk_ratelimit()) if (printk_ratelimit())
dev_err(dev, "xfer %p#%u: bad segment\n", xfer, seg_idx); dev_err(dev, "xfer %p#%u: bad segment\n", xfer, seg_idx);
if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment