| 3448 | | |
| | 3446 | else |
| | 3447 | { |
| | 3448 | if (Ed.hwinfo & ED_HWINFO_SKIP) |
| | 3449 | { |
| | 3450 | LogFlow(("ohciServicePeriodicList: Ed=%#010RX32 Ed.TailP=%#010RX32 SKIP\n", EdAddr, Ed.TailP)); |
| | 3451 | /* If the ED is in 'skip' state, no transactions on it are allowed and we must |
| | 3452 | * cancel outstanding URBs, if any. |
| | 3453 | */ |
| | 3454 | uint32_t TdAddr = Ed.HeadP & ED_PTR_MASK; |
| | 3455 | PVUSBURB pUrb = ohciTdInFlightUrb(pThis, TdAddr); |
| | 3456 | if (pUrb) |
| | 3457 | pThis->RootHub.pIRhConn->pfnCancelUrbsEp(pThis->RootHub.pIRhConn, pUrb); |
| | 3458 | } |
| | 3459 | } |
| | 3544 | if (!fValidHCCA) |
| | 3545 | return; |
| | 3546 | |
| | 3547 | for (i = 0, cLeft = pThis->cInFlight; cLeft && i < RT_ELEMENTS(pThis->aInFlight); i++) |
| | 3548 | if (pThis->aInFlight[i].pUrb) |
| | 3549 | { |
| | 3550 | pThis->aInFlight[i].inactive = true; |
| | 3551 | cLeft--; |
| | 3552 | } |
| | 3553 | Assert(cLeft == 0); |
| | 3554 | |
| | 3555 | for (i = 0; i < 2 + OHCI_HCCA_NUM_INTR; i++) |
| | 3556 | { |
| | 3557 | switch (i) |
| | 3558 | { |
| | 3559 | case OHCI_HCCA_NUM_INTR: |
| | 3560 | EdAddr = pThis->bulk_head; |
| | 3561 | break; |
| | 3562 | case OHCI_HCCA_NUM_INTR + 1: |
| | 3563 | EdAddr = pThis->ctrl_head; |
| | 3564 | break; |
| | 3565 | default: |
| | 3566 | ohciGetDWords(pThis, pThis->hcca + i * sizeof(EdAddr), &EdAddr, 1); |
| | 3567 | break; |
| | 3568 | } |
| | 3569 | while (EdAddr) |
| | 3570 | { |
| | 3571 | OHCIED Ed; |
| | 3572 | OHCITD Td; |
| | 3573 | ohciReadEd(pThis, EdAddr, &Ed); |
| | 3574 | uint32_t TdAddr = Ed.HeadP & ED_PTR_MASK; |
| | 3575 | do |
| | 3576 | { |
| | 3577 | ohciReadTd(pThis, TdAddr, &Td); |
| | 3578 | j = ohci_in_flight_find(pThis, TdAddr); |
| | 3579 | if (j > -1) |
| | 3580 | pThis->aInFlight[j].inactive = false; |
| | 3581 | TdAddr = Td.NextTD & ED_PTR_MASK; |
| | 3582 | } while (TdAddr != (Ed.TailP & ED_PTR_MASK)); |
| | 3583 | EdAddr = Ed.NextED & ED_PTR_MASK; |
| | 3584 | } |
| | 3585 | } |
| | 3586 | |
| | 3587 | for (i = 0, cLeft = pThis->cInFlight; cLeft && i < RT_ELEMENTS(pThis->aInFlight); i++) |
| | 3588 | if (pThis->aInFlight[i].pUrb) |
| | 3589 | { |
| | 3590 | cLeft--; |
| | 3591 | pUrb = pThis->aInFlight[i].pUrb; |
| | 3592 | if (pThis->aInFlight[i].inactive |
| | 3593 | && pUrb->enmState == VUSBURBSTATE_IN_FLIGHT |
| | 3594 | && !pUrb->enmType == VUSBXFERTYPE_CTRL) |
| | 3595 | pThis->RootHub.pIRhConn->pfnCancelUrbsEp(pThis->RootHub.pIRhConn, pUrb); |
| | 3596 | } |
| | 3597 | Assert(cLeft == 0); |
| | 3598 | } |
| | 3599 | |