[adm5120] minor fixes in the RB153 CF driver
[openwrt.git] / target / linux / adm5120 / files / drivers / usb / host / adm5120-q.c
index 24acc87..9995d42 100644 (file)
@@ -1,8 +1,11 @@
 /*
- * OHCI HCD (Host Controller Driver) for USB.
+ * ADM5120 HCD (Host Controller Driver) for USB
  *
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
- * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
+ * Copyright (C) 2007 Gabor Juhos <juhosg at openwrt.org>
+ *
+ * This file was derived from: drivers/usb/host/ohci-q.c
+ *   (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ *   (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
  *
  * This file is licenced under the GPL.
  */
@@ -38,7 +41,7 @@ __acquires(ahcd->lock)
                        && urb->status == 0) {
                urb->status = -EREMOTEIO;
 #ifdef ADMHC_VERBOSE_DEBUG
-               urb_print(urb, "SHORT", usb_pipeout (urb->pipe));
+               urb_print(ahcd, urb, "SHORT", usb_pipeout(urb->pipe));
 #endif
        }
        spin_unlock(&urb->lock);
@@ -53,7 +56,7 @@ __acquires(ahcd->lock)
        }
 
 #ifdef ADMHC_VERBOSE_DEBUG
-       urb_print(urb, "RET", usb_pipeout (urb->pipe));
+       urb_print(ahcd, urb, "RET", usb_pipeout (urb->pipe));
 #endif
 
        /* urb->complete() can reenter this HCD */
@@ -112,7 +115,7 @@ static void periodic_link (struct admhcd *ahcd, struct ed *ed)
        unsigned        i;
 
        admhc_vdbg (ahcd, "link %sed %p branch %d [%dus.], interval %d\n",
-               (ed->hwINFO & cpu_to_hc32 (ahcd, ED_ISO)) ? "iso " : "",
+               (ed->hwINFO & cpu_to_hc32(ahcd, ED_ISO)) ? "iso " : "",
                ed, ed->branch, ed->load, ed->interval);
 
        for (i = ed->branch; i < NUM_INTS; i += ed->interval) {
@@ -202,7 +205,7 @@ static void periodic_unlink (struct admhcd *ahcd, struct ed *ed)
 
        admhcd_to_hcd(ahcd)->self.bandwidth_allocated -= ed->load / ed->interval;
        admhc_vdbg (ahcd, "unlink %sed %p branch %d [%dus.], interval %d\n",
-               (ed->hwINFO & cpu_to_hc32 (ahcd, ED_ISO)) ? "iso " : "",
+               (ed->hwINFO & cpu_to_hc32(ahcd, ED_ISO)) ? "iso " : "",
                ed, ed->branch, ed->load, ed->interval);
 }
 #endif
@@ -231,6 +234,11 @@ static void periodic_unlink (struct admhcd *ahcd, struct ed *ed)
  */
 static void ed_deschedule(struct admhcd *ahcd, struct ed *ed)
 {
+
+#ifdef ADMHC_VERBOSE_DEBUG
+       admhc_dump_ed(ahcd, "ED-DESCHED", ed, 1);
+#endif
+
        ed->hwINFO |= cpu_to_hc32(ahcd, ED_SKIP);
        wmb();
        ed->state = ED_UNLINK;
@@ -333,7 +341,12 @@ static struct ed *ed_get(struct admhcd *ahcd,      struct usb_host_endpoint *ep,
  */
 static void start_ed_unlink(struct admhcd *ahcd, struct ed *ed)
 {
-       ed->hwINFO |= cpu_to_hc32 (ahcd, ED_DEQUEUE);
+
+#ifdef ADMHC_VERBOSE_DEBUG
+       admhc_dump_ed(ahcd, "ED-UNLINK", ed, 1);
+#endif
+
+       ed->hwINFO |= cpu_to_hc32(ahcd, ED_DEQUEUE);
        ed_deschedule(ahcd, ed);
 
        /* add this ED into the remove list */
@@ -432,9 +445,7 @@ static void td_submit_urb(struct admhcd *ahcd, struct urb *urb)
        int             cnt = 0;
        u32             info = 0;
        int             is_out = usb_pipeout(urb->pipe);
-       int             periodic = 0;
        u32             toggle = 0;
-       struct td       *td;
 
        /* OHCI handles the bulk/interrupt data toggles itself.  We just
         * use the device toggle bits for resetting, and rely on the fact
@@ -644,15 +655,15 @@ ed_halted(struct admhcd *ahcd, struct td *td, int cc, struct td *rev)
        struct urb              *urb = td->urb;
        struct ed               *ed = td->ed;
        struct list_head        *tmp = td->td_list.next;
-       __hc32                  toggle = ed->hwHeadP & cpu_to_hc32 (ahcd, ED_C);
+       __hc32                  toggle = ed->hwHeadP & cpu_to_hc32(ahcd, ED_C);
 
        admhc_dump_ed(ahcd, "ed halted", td->ed, 1);
        /* clear ed halt; this is the td that caused it, but keep it inactive
         * until its urb->complete() has a chance to clean up.
         */
-       ed->hwINFO |= cpu_to_hc32 (ahcd, ED_SKIP);
+       ed->hwINFO |= cpu_to_hc32(ahcd, ED_SKIP);
        wmb();
-       ed->hwHeadP &= ~cpu_to_hc32 (ahcd, ED_H);
+       ed->hwHeadP &= ~cpu_to_hc32(ahcd, ED_H);
 
        /* put any later tds from this urb onto the donelist, after 'td',
         * order won't matter here: no errors, and nothing was transferred.
@@ -677,9 +688,9 @@ ed_halted(struct admhcd *ahcd, struct td *td, int cc, struct td *rev)
                 */
                info = next->hwINFO;
 #if 0          /* FIXME */
-               info |= cpu_to_hc32 (ahcd, TD_DONE);
+               info |= cpu_to_hc32(ahcd, TD_DONE);
 #endif
-               info &= ~cpu_to_hc32 (ahcd, TD_CC);
+               info &= ~cpu_to_hc32(ahcd, TD_CC);
                next->hwINFO = info;
 
                next->next_dl_td = rev;
@@ -737,8 +748,8 @@ skip_ed:
                                last = &ed->ed_rm_next;
                                continue;
                        }
-
-                       if (!list_empty (&ed->td_list)) {
+#if 0
+                       if (!list_empty(&ed->td_list)) {
                                struct td       *td;
                                u32             head;
 
@@ -751,6 +762,7 @@ skip_ed:
                                if (td->td_dma != head)
                                        goto skip_ed;
                        }
+#endif
                }
 
                /* reentrancy:  if we drop the schedule lock, someone might
@@ -772,7 +784,7 @@ skip_ed:
 rescan_this:
                completed = 0;
                prev = &ed->hwHeadP;
-               list_for_each_safe (entry, tmp, &ed->td_list) {
+               list_for_each_safe(entry, tmp, &ed->td_list) {
                        struct td       *td;
                        struct urb      *urb;
                        struct urb_priv *urb_priv;
@@ -795,7 +807,9 @@ rescan_this:
                        *prev = td->hwNextTD | savebits;
 
                        /* HC may have partly processed this TD */
-                       urb_print(urb, "PARTIAL", 1);
+#ifdef ADMHC_VERBOSE_DEBUG
+                       urb_print(ahcd, urb, "PARTIAL", 0);
+#endif
                        td_done(ahcd, urb, td);
 
                        /* if URB is done, clean up */
@@ -804,18 +818,18 @@ rescan_this:
                                finish_urb(ahcd, urb);
                        }
                }
-               if (completed && !list_empty (&ed->td_list))
+               if (completed && !list_empty(&ed->td_list))
                        goto rescan_this;
 
                /* ED's now officially unlinked, hc doesn't see */
                ed->state = ED_IDLE;
                ed->hwHeadP &= ~cpu_to_hc32(ahcd, ED_H);
                ed->hwNextED = 0;
-               wmb ();
-               ed->hwINFO &= ~cpu_to_hc32 (ahcd, ED_SKIP | ED_DEQUEUE);
+               wmb();
+               ed->hwINFO &= ~cpu_to_hc32(ahcd, ED_SKIP | ED_DEQUEUE);
 
                /* but if there's work queued, reschedule */
-               if (!list_empty (&ed->td_list)) {
+               if (!list_empty(&ed->td_list)) {
                        if (HC_IS_RUNNING(admhcd_to_hcd(ahcd)->state))
                                ed_schedule(ahcd, ed);
                }
@@ -838,9 +852,7 @@ rescan_this:
 static void ed_unhalt(struct admhcd *ahcd, struct ed *ed, struct urb *urb)
 {
        struct list_head *entry,*tmp;
-       struct urb_priv *urb_priv = urb->hcpriv;
-       __hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ahcd, ED_C);
-
+       __hc32 toggle = ed->hwHeadP & cpu_to_hc32(ahcd, ED_C);
 
 #ifdef ADMHC_VERBOSE_DEBUG
        admhc_dump_ed(ahcd, "UNHALT", ed, 0);
@@ -848,9 +860,9 @@ static void ed_unhalt(struct admhcd *ahcd, struct ed *ed, struct urb *urb)
        /* clear ed halt; this is the td that caused it, but keep it inactive
         * until its urb->complete() has a chance to clean up.
         */
-       ed->hwINFO |= cpu_to_hc32 (ahcd, ED_SKIP);
+       ed->hwINFO |= cpu_to_hc32(ahcd, ED_SKIP);
        wmb();
-       ed->hwHeadP &= ~cpu_to_hc32 (ahcd, ED_H);
+       ed->hwHeadP &= ~cpu_to_hc32(ahcd, ED_H);
 
        list_for_each_safe(entry, tmp, &ed->td_list) {
                struct td *td = list_entry(entry, struct td, td_list);
@@ -869,6 +881,14 @@ static void ed_unhalt(struct admhcd *ahcd, struct ed *ed, struct urb *urb)
 
 }
 
+static void ed_intr_refill(struct admhcd *ahcd, struct ed *ed)
+{
+       __hc32 toggle = ed->hwHeadP & cpu_to_hc32(ahcd, ED_C);
+
+       ed->hwHeadP = ed->hwTailP | toggle;
+}
+
+
 static inline int is_ed_halted(struct admhcd *ahcd, struct ed *ed)
 {
        return ((hc32_to_cpup(ahcd, &ed->hwHeadP) & ED_H) == ED_H);
@@ -886,7 +906,7 @@ static void ed_update(struct admhcd *ahcd, struct ed *ed)
        struct list_head *entry,*tmp;
 
 #ifdef ADMHC_VERBOSE_DEBUG
-       admhc_dump_ed(ahcd, "UPDATE", ed, 0);
+       admhc_dump_ed(ahcd, "UPDATE", ed, 1);
 #endif
 
        list_for_each_safe(entry, tmp, &ed->td_list) {
@@ -903,6 +923,9 @@ static void ed_update(struct admhcd *ahcd, struct ed *ed)
                if (is_ed_halted(ahcd, ed) && is_td_halted(ahcd, ed, td))
                        ed_unhalt(ahcd, ed, urb);
 
+               if (ed->type == PIPE_INTERRUPT)
+                       ed_intr_refill(ahcd,ed);
+
                /* If all this urb's TDs are done, call complete() */
                if (urb_priv->td_idx == urb_priv->td_cnt)
                        finish_urb(ahcd, urb);
@@ -913,13 +936,13 @@ static void ed_update(struct admhcd *ahcd, struct ed *ed)
                                start_ed_unlink(ahcd, ed);
 
                /* ... reenabling halted EDs only after fault cleanup */
-               } else if ((ed->hwINFO & cpu_to_hc32 (ahcd,
+               } else if ((ed->hwINFO & cpu_to_hc32(ahcd,
                                                ED_SKIP | ED_DEQUEUE))
-                                       == cpu_to_hc32 (ahcd, ED_SKIP)) {
+                                       == cpu_to_hc32(ahcd, ED_SKIP)) {
                        td = list_entry(ed->td_list.next, struct td, td_list);
 #if 0
-                       if (!(td->hwINFO & cpu_to_hc32 (ahcd, TD_DONE))) {
-                               ed->hwINFO &= ~cpu_to_hc32 (ahcd, ED_SKIP);
+                       if (!(td->hwINFO & cpu_to_hc32(ahcd, TD_DONE))) {
+                               ed->hwINFO &= ~cpu_to_hc32(ahcd, ED_SKIP);
                                /* ... hc may need waking-up */
                                switch (ed->type) {
                                case PIPE_CONTROL:
This page took 0.040586 seconds and 4 git commands to generate.