VirtualBox

Ticket #11207: vbox-ohci_cancellations_v2.diff

File vbox-ohci_cancellations_v2.diff, 3.7 KB (added by Derek, 12 years ago)

Cancellations by scanning for removed transfer descriptors

  • src/VBox/Devices/USB/DevOHCI.cpp

     
    303303    {
    304304        /** Address of the transport descriptor. */
    305305        uint32_t GCPhysTD;
    306 #if HC_ARCH_BITS == 64
    307         uint32_t Alignment0; /**< Alignment pUrb correctly. */
    308 #endif
     306        bool inactive;
    309307        /** Pointer to the URB. */
    310308        R3PTRTYPE(PVUSBURB) pUrb;
    311309    } aInFlight[257];
     
    34453443            else
    34463444                break;
    34473445        }
    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        }
    34493460        /* next end point */
    34503461        EdAddr = Ed.NextED & ED_PTR_MASK;
    34513462    }
     
    35213532    pThis->uFrameRate         = u32FrameRate;
    35223533}
    35233534
     3535static void ohciPerformCancellations(POHCI pThis)
     3536{
     3537    bool fValidHCCA = !(    pThis->hcca >= OHCI_HCCA_MASK
     3538                        ||  pThis->hcca < ~OHCI_HCCA_MASK);
     3539    unsigned i, cLeft;
     3540    int j;
     3541    uint32_t EdAddr;
     3542    PVUSBURB pUrb;
    35243543
     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
    35253600/**
    35263601 * Generate a Start-Of-Frame event, and set a timer for End-Of-Frame.
    35273602 */
     
    37003775    if ( (pThis->dqic != 0x7) && (pThis->dqic != 0) )
    37013776        pThis->dqic--;
    37023777
     3778    /* Clean up any URBs that have been removed */
     3779    ohciPerformCancellations(pThis);
     3780
    37033781    /* Start the next frame */
    37043782    ohciStartOfFrame(pThis);
    37053783

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy