+static void ed_unhalt(struct admhcd *ahcd, struct ed *ed, struct urb *urb)
+{
+ struct list_head *entry,*tmp;
+ __hc32 toggle = ed->hwHeadP & cpu_to_hc32(ahcd, ED_C);
+
+#ifdef ADMHC_VERBOSE_DEBUG
+ admhc_dump_ed(ahcd, "UNHALT", ed, 0);
+#endif
+ /* 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);
+ wmb();
+ 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);
+ __hc32 info;
+
+ if (td->urb != urb)
+ break;
+
+ info = td->hwINFO;
+ info &= ~cpu_to_hc32(ahcd, TD_CC | TD_OWN);
+ td->hwINFO = info;
+
+ ed->hwHeadP = td->hwNextTD | toggle;
+ wmb();
+ }
+
+}
+
+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);
+}
+
+static inline int is_td_halted(struct admhcd *ahcd, struct ed *ed,
+ struct td *td)
+{
+ return ((hc32_to_cpup(ahcd, &ed->hwHeadP) & TD_MASK) ==
+ (hc32_to_cpup(ahcd, &td->hwNextTD) & TD_MASK));
+}
+