VirtualBox

Changeset 53911 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jan 22, 2015 11:34:26 AM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
97782
Message:

OHCI: Immediately wake up the frame thread when an URB completed and reset the frame rate to 1KHz

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/USB/DevOHCI.cpp

    r53210 r53911  
    21542154
    21552155/**
     2156 * Calculate frame timer variables given a frame rate (1,000 Hz is the full speed).
     2157 */
     2158static void ohciCalcTimerIntervals(POHCI pThis, uint32_t u32FrameRate)
     2159{
     2160    Assert(u32FrameRate <= OHCI_DEFAULT_TIMER_FREQ);
     2161
     2162    pThis->cTicksPerFrame = pThis->u64TimerHz / u32FrameRate;
     2163    if (!pThis->cTicksPerFrame)
     2164        pThis->cTicksPerFrame = 1;
     2165    pThis->cTicksPerUsbTick   = pThis->u64TimerHz >= VUSB_BUS_HZ ? pThis->u64TimerHz / VUSB_BUS_HZ : 1;
     2166    pThis->nsWait             = RT_NS_1SEC / u32FrameRate;
     2167    pThis->uFrameRate         = u32FrameRate;
     2168}
     2169
     2170
     2171/**
     2172 * Calculates the new frame rate based on the idle detection and number of idle
     2173 * cycles.
     2174 *
     2175 * @returns nothing.
     2176 * @param   pThis    The OHCI device data.
     2177 */
     2178static void ohciFramerateCalcNew(POHCI pThis)
     2179{
     2180    uint32_t uNewFrameRate = pThis->uFrameRate;
     2181
     2182    /*
     2183     * Adjust the frame timer interval based on idle detection.
     2184     */
     2185    if (pThis->fIdle)
     2186    {
     2187        pThis->cIdleCycles++;
     2188        /* Set the new frame rate based on how long we've been idle. Tunable. */
     2189        switch (pThis->cIdleCycles)
     2190        {
     2191            case 4: uNewFrameRate = 500;    break;  /*  2ms interval */
     2192            case 16:uNewFrameRate = 125;    break;  /*  8ms interval */
     2193            case 24:uNewFrameRate = 50;     break;  /* 20ms interval */
     2194            default:    break;
     2195        }
     2196        /* Avoid overflow. */
     2197        if (pThis->cIdleCycles > 60000)
     2198            pThis->cIdleCycles = 20000;
     2199    }
     2200    else
     2201    {
     2202        if (pThis->cIdleCycles)
     2203        {
     2204            pThis->cIdleCycles = 0;
     2205            uNewFrameRate      = OHCI_DEFAULT_TIMER_FREQ;
     2206        }
     2207    }
     2208    if (uNewFrameRate != pThis->uFrameRate)
     2209        ohciCalcTimerIntervals(pThis, uNewFrameRate);
     2210}
     2211
     2212
     2213/**
    21562214 * Returns the OHCI_CC_* corresponding to the VUSB status code.
    21572215 *
     
    25382596    /* finally write back the endpoint descriptor. */
    25392597    ohciWriteEd(pThis, pUrb->Hci.EdAddr, &Ed);
     2598
     2599    /* Calculate new frame rate and wakeup the . */
     2600    ohciFramerateCalcNew(pThis);
     2601    RTSemEventSignal(pThis->hSemEventFrame);
    25402602    RTCritSectLeave(&pThis->CritSect);
    25412603}
     
    35813643
    35823644/**
    3583  * Calculate frame timer variables given a frame rate (1,000 Hz is the full speed).
    3584  */
    3585 static void ohciCalcTimerIntervals(POHCI pThis, uint32_t u32FrameRate)
    3586 {
    3587     Assert(u32FrameRate <= OHCI_DEFAULT_TIMER_FREQ);
    3588 
    3589     pThis->cTicksPerFrame = pThis->u64TimerHz / u32FrameRate;
    3590     if (!pThis->cTicksPerFrame)
    3591         pThis->cTicksPerFrame = 1;
    3592     pThis->cTicksPerUsbTick   = pThis->u64TimerHz >= VUSB_BUS_HZ ? pThis->u64TimerHz / VUSB_BUS_HZ : 1;
    3593     pThis->nsWait             = RT_NS_1SEC / u32FrameRate;
    3594     pThis->uFrameRate         = u32FrameRate;
    3595 }
    3596 
    3597 /**
    35983645 * Go over the in-flight URB list and cancel any URBs that are no longer in use.
    35993646 * This occurs when the host removes EDs or TDs from the lists and we don't notice
     
    36943741static void ohciStartOfFrame(POHCI pThis)
    36953742{
    3696     uint32_t    uNewFrameRate = pThis->uFrameRate;
    36973743#ifdef LOG_ENABLED
    36983744    const uint32_t status_old = pThis->status;
     
    37963842     * Adjust the frame timer interval based on idle detection.
    37973843     */
    3798     if (pThis->fIdle)
    3799     {
    3800         pThis->cIdleCycles++;
    3801         /* Set the new frame rate based on how long we've been idle. Tunable. */
    3802         switch (pThis->cIdleCycles)
    3803         {
    3804         case 4: uNewFrameRate = 500;    break;  /*  2ms interval */
    3805         case 16:uNewFrameRate = 125;    break;  /*  8ms interval */
    3806         case 24:uNewFrameRate = 50;     break;  /* 20ms interval */
    3807         default:    break;
    3808         }
    3809         /* Avoid overflow. */
    3810         if (pThis->cIdleCycles > 60000)
    3811             pThis->cIdleCycles = 20000;
    3812     }
    3813     else
    3814     {
    3815         if (pThis->cIdleCycles)
    3816         {
    3817             pThis->cIdleCycles = 0;
    3818             uNewFrameRate      = OHCI_DEFAULT_TIMER_FREQ;
    3819         }
    3820     }
    3821     if (uNewFrameRate != pThis->uFrameRate)
    3822         ohciCalcTimerIntervals(pThis, uNewFrameRate);
     3844    ohciFramerateCalcNew(pThis);
    38233845}
    38243846
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette