/* Unlink an interrupt queue head from the periodic schedule frame list. */
VOID EhcUnlinkQhFromPeriod(IN USB2_HC_DEV *Ehc, IN EHC_QH *Qh)
/* Unlink an interrupt queue head from the periodic schedule frame list. */
VOID EhcUnlinkQhFromPeriod(IN USB2_HC_DEV *Ehc, IN EHC_QH *Qh)
{
  UINTN   Index;
  EHC_QH  *Prev;
  EHC_QH  *This;
  for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) {
    ASSERT (!EHC_LINK_TERMINATED (((UINT32 *)Ehc->PeriodFrame)[Index]));
    This = (EHC_QH *)((UINTN *)Ehc->PeriodFrameHost)[Index];
    Prev = NULL;
    while ((This != NULL) && (This != Qh)) {
      Prev = This;
      This = This->NextQh;
    }
    if (This == NULL) {
      continue;
    }
    if (Prev == NULL) {
      ((UINT32 *)Ehc->PeriodFrame)[Index]    = Qh->QhHw.HorizonLink;
      ((UINTN *)Ehc->PeriodFrameHost)[Index] = (UINTN)Qh->NextQh;
    } else {
      Prev->NextQh           = Qh->NextQh;
      Prev->QhHw.HorizonLink = Qh->QhHw.HorizonLink;
    }
  }
}