aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0019-musb_host-simplify-check-for-active-URB.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0019-musb_host-simplify-check-for-active-URB.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0019-musb_host-simplify-check-for-active-URB.patch158
1 files changed, 158 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0019-musb_host-simplify-check-for-active-URB.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0019-musb_host-simplify-check-for-active-URB.patch
new file mode 100644
index 0000000000..c0e57155c8
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0019-musb_host-simplify-check-for-active-URB.patch
@@ -0,0 +1,158 @@
+From 69242ddd26151d45f46011cf7abc581b14699fb2 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
+Date: Fri, 27 Mar 2009 12:56:26 -0700
+Subject: [PATCH] musb_host: simplify check for active URB
+
+The existance of the scheduling list shouldn't matter in
+determining whether there's currectly an URB executing on a
+hardware endpoint. What should actually matter is the 'in_qh'
+or 'out_qh' fields of the 'struct musb_hw_ep' -- those are
+set in musb_start_urb() and cleared in musb_giveback() when
+the endpoint's URB list drains. Hence we should be able to
+replace the big *switch* statements in musb_urb_dequeue()
+and musb_h_disable() with mere musb_ep_get_qh() calls...
+
+While at it, do some more changes:
+
+ - add 'is_in' variable to musb_urb_dequeue();
+
+ - remove the unnecessary 'epnum' variable from musb_h_disable();
+
+ - fix the comment style in the vicinity.
+
+This is a minor shrink of source and object code.
+
+Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
+Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
+---
+ drivers/usb/musb/musb_host.c | 72 ++++++++---------------------------------
+ 1 files changed, 14 insertions(+), 58 deletions(-)
+
+diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
+index e833959..e121e0e 100644
+--- a/drivers/usb/musb/musb_host.c
++++ b/drivers/usb/musb/musb_host.c
+@@ -2008,14 +2008,14 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+ {
+ struct musb *musb = hcd_to_musb(hcd);
+ struct musb_qh *qh;
+- struct list_head *sched;
+ unsigned long flags;
++ int is_in = usb_pipein(urb->pipe);
+ int ret;
+
+ DBG(4, "urb=%p, dev%d ep%d%s\n", urb,
+ usb_pipedevice(urb->pipe),
+ usb_pipeendpoint(urb->pipe),
+- usb_pipein(urb->pipe) ? "in" : "out");
++ is_in ? "in" : "out");
+
+ spin_lock_irqsave(&musb->lock, flags);
+ ret = usb_hcd_check_unlink_urb(hcd, urb, status);
+@@ -2026,45 +2026,23 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+ if (!qh)
+ goto done;
+
+- /* Any URB not actively programmed into endpoint hardware can be
++ /*
++ * Any URB not actively programmed into endpoint hardware can be
+ * immediately given back; that's any URB not at the head of an
+ * endpoint queue, unless someday we get real DMA queues. And even
+ * if it's at the head, it might not be known to the hardware...
+ *
+- * Otherwise abort current transfer, pending dma, etc.; urb->status
++ * Otherwise abort current transfer, pending DMA, etc.; urb->status
+ * has already been updated. This is a synchronous abort; it'd be
+ * OK to hold off until after some IRQ, though.
++ *
++ * NOTE: qh is invalid unless !list_empty(&hep->urb_list)
+ */
+- if (!qh->is_ready || urb->urb_list.prev != &qh->hep->urb_list)
+- ret = -EINPROGRESS;
+- else {
+- switch (qh->type) {
+- case USB_ENDPOINT_XFER_CONTROL:
+- sched = &musb->control;
+- break;
+- case USB_ENDPOINT_XFER_BULK:
+- if (qh->mux == 1) {
+- if (usb_pipein(urb->pipe))
+- sched = &musb->in_bulk;
+- else
+- sched = &musb->out_bulk;
+- break;
+- }
+- default:
+- /* REVISIT when we get a schedule tree, periodic
+- * transfers won't always be at the head of a
+- * singleton queue...
+- */
+- sched = NULL;
+- break;
+- }
+- }
+-
+- /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */
+- if (ret < 0 || (sched && qh != first_qh(sched))) {
++ if (!qh->is_ready
++ || urb->urb_list.prev != &qh->hep->urb_list
++ || musb_ep_get_qh(qh->hw_ep, is_in) != qh) {
+ int ready = qh->is_ready;
+
+- ret = 0;
+ qh->is_ready = 0;
+ musb_giveback(musb, urb, 0);
+ qh->is_ready = ready;
+@@ -2088,13 +2066,11 @@ done:
+ static void
+ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
+ {
+- u8 epnum = hep->desc.bEndpointAddress;
++ u8 is_in = hep->desc.bEndpointAddress & USB_DIR_IN;
+ unsigned long flags;
+ struct musb *musb = hcd_to_musb(hcd);
+- u8 is_in = epnum & USB_DIR_IN;
+ struct musb_qh *qh;
+ struct urb *urb;
+- struct list_head *sched;
+
+ spin_lock_irqsave(&musb->lock, flags);
+
+@@ -2102,31 +2078,11 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
+ if (qh == NULL)
+ goto exit;
+
+- switch (qh->type) {
+- case USB_ENDPOINT_XFER_CONTROL:
+- sched = &musb->control;
+- break;
+- case USB_ENDPOINT_XFER_BULK:
+- if (qh->mux == 1) {
+- if (is_in)
+- sched = &musb->in_bulk;
+- else
+- sched = &musb->out_bulk;
+- break;
+- }
+- default:
+- /* REVISIT when we get a schedule tree, periodic transfers
+- * won't always be at the head of a singleton queue...
+- */
+- sched = NULL;
+- break;
+- }
+-
+- /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */
++ /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */
+
+- /* kick first urb off the hardware, if needed */
++ /* Kick the first URB off the hardware, if needed */
+ qh->is_ready = 0;
+- if (!sched || qh == first_qh(sched)) {
++ if (musb_ep_get_qh(qh->hw_ep, is_in) == qh) {
+ urb = next_urb(qh);
+
+ /* make software (then hardware) stop ASAP */
+--
+1.6.0.4
+