/* caller must hold ehci->lock */ static int periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr) { union ehci_shadow *prev_p = &ehci->pshadow [frame]; __le32 *hw_p = &ehci->periodic [frame]; union ehci_shadow here = *prev_p; union ehci_shadow *next_p; /* find predecessor of "ptr"; hw and shadow lists are in sync */ while (here.ptr && here.ptr != ptr) { prev_p = periodic_next_shadow (prev_p, Q_NEXT_TYPE (*hw_p)); hw_p = &here.qh->hw_next; here = *prev_p; } /* an interrupt entry (at list end) could have been shared */ if (!here.ptr) { dbg ("entry %p no longer on frame [%d]", ptr, frame); return 0; } // vdbg ("periodic unlink %p from frame %d", ptr, frame); /* update hardware list ... HC may still know the old structure, so * don't change hw_next until it'll have purged its cache */ next_p = periodic_next_shadow (&here, Q_NEXT_TYPE (*hw_p)); *hw_p = here.qh->hw_next; /* unlink from shadow list; HCD won't see old structure again */ *prev_p = *next_p; next_p->ptr = NULL; return 1; }
/* caller must hold ehci->lock */ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr) { union ehci_shadow *prev_p = &ehci->pshadow [frame]; __le32 *hw_p = &ehci->periodic [frame]; union ehci_shadow here = *prev_p; /* find predecessor of "ptr"; hw and shadow lists are in sync */ while (here.ptr && here.ptr != ptr) { prev_p = periodic_next_shadow (prev_p, Q_NEXT_TYPE (*hw_p)); hw_p = here.hw_next; here = *prev_p; } /* an interrupt entry (at list end) could have been shared */ if (!here.ptr) return; /* update shadow and hardware lists ... the old "next" pointers * from ptr may still be in use, the caller updates them. */ *prev_p = *periodic_next_shadow (&here, Q_NEXT_TYPE (*hw_p)); *hw_p = *here.hw_next; }
static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr) { union ehci_shadow *prev_p = &ehci->pshadow[frame]; __hc32 *hw_p = &ehci->periodic[frame]; union ehci_shadow here = *prev_p; while (here.ptr && here.ptr != ptr) { prev_p = periodic_next_shadow(ehci, prev_p, Q_NEXT_TYPE(ehci, *hw_p)); hw_p = shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p)); here = *prev_p; } if (!here.ptr) return; *prev_p = *periodic_next_shadow(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p)); *hw_p = *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p)); }