Changeset 56454 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Jun 16, 2015 1:57:21 PM (9 years ago)
- Location:
- trunk/src/VBox/Devices/USB
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/VBox/Devices/USB/DevOHCI.cpp ¶
r56292 r56454 375 375 376 376 /** The framer thread. */ 377 R3PTRTYPE(PPDMTHREAD) hThreadFrame;377 R3PTRTYPE(PPDMTHREAD) hThreadFrame; 378 378 /** Event semaphore to interact with the framer thread. */ 379 R3PTRTYPE(RTSEMEVENT ) hSemEventFrame;379 R3PTRTYPE(RTSEMEVENTMULTI) hSemEventFrame; 380 380 /** Event semaphore to release the thread waiting for the framer thread to stop. */ 381 381 R3PTRTYPE(RTSEMEVENTMULTI) hSemEventFrameStopped; 382 382 /** Flag whether the framer thread should processing frames. */ 383 volatile bool fBusStarted;383 volatile bool fBusStarted; 384 384 /** Alignment. */ 385 uint32_t Alignment5;385 uint32_t Alignment5; 386 386 /** How long to wait until the next frame. */ 387 uint64_t nsWait;387 uint64_t nsWait; 388 388 /** Critical section to synchronize the framer and URB completion handler. */ 389 RTCRITSECT CritSect;389 RTCRITSECT CritSect; 390 390 391 391 } OHCI; … … 2214 2214 } 2215 2215 if (uNewFrameRate != pThis->uFrameRate) 2216 { 2217 LogFlow(("Frame rate changed from %u to %u\n", pThis->uFrameRate, uNewFrameRate)); 2216 2218 ohciCalcTimerIntervals(pThis, uNewFrameRate); 2219 } 2217 2220 } 2218 2221 … … 2606 2609 /* Calculate new frame rate and wakeup the . */ 2607 2610 ohciFramerateCalcNew(pThis); 2608 RTSemEvent Signal(pThis->hSemEventFrame);2611 RTSemEventMultiSignal(pThis->hSemEventFrame); 2609 2612 RTCritSectLeave(&pThis->CritSect); 2610 2613 } … … 2980 2983 { 2981 2984 /* Get validate the previous TD */ 2982 int iInFlightPrev = ohci_in_flight_find(pThis, ITdAddr );2983 AssertMsgReturn(iInFlightPrev >= 0, ("ITdAddr=%#RX32\n", ITdAddr ), false);2985 int iInFlightPrev = ohci_in_flight_find(pThis, ITdAddrPrev); 2986 AssertMsgReturn(iInFlightPrev >= 0, ("ITdAddr=%#RX32\n", ITdAddrPrev), false); 2984 2987 PVUSBURB pUrbPrev = pThis->aInFlight[iInFlightPrev].pUrb; 2985 2988 if (ohciHasUrbBeenCanceled(pThis, pUrbPrev, pEd)) /* ensures the copy is correct. */ … … 3870 3873 static DECLCALLBACK(int) ohciR3ThreadFrame(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 3871 3874 { 3872 int rc = VINF_SUCCESS;3873 3875 POHCI pThis = (POHCI)pThread->pvUser; 3874 uint64_t tsNanoStart = 0; 3876 uint64_t tsBeginServicing = 0; 3877 uint64_t cFramesProcessed = 0; 3875 3878 3876 3879 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) 3877 3880 return VINF_SUCCESS; 3878 3881 3882 tsBeginServicing = RTTimeNanoTS(); 3883 cFramesProcessed = 0; 3884 3879 3885 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 3880 3886 { 3881 3887 while ( !ASMAtomicReadBool(&pThis->fBusStarted) 3882 && pThread->enmState == PDMTHREADSTATE_RUNNING 3883 && RT_SUCCESS(rc)) 3888 && pThread->enmState == PDMTHREADSTATE_RUNNING) 3884 3889 { 3885 3890 /* Signal the waiter that we are stopped now. */ 3886 rc = RTSemEventMultiSignal(pThis->hSemEventFrameStopped);3891 int rc = RTSemEventMultiSignal(pThis->hSemEventFrameStopped); 3887 3892 AssertRC(rc); 3888 rc = RTSemEventWait(pThis->hSemEventFrame, RT_INDEFINITE_WAIT); 3893 rc = RTSemEventMultiReset(pThis->hSemEventFrame); 3894 AssertRC(rc); 3895 3896 /* 3897 * We have to check that the Bus was not started and the thread state 3898 * did not change or otherwise we risk hanging here indefinitely 3899 * if the signaller set the event semaphore before we reset it. 3900 */ 3901 if (ASMAtomicReadBool(&pThis->fBusStarted) || pThread->enmState != PDMTHREADSTATE_RUNNING) 3902 break; 3903 3904 rc = RTSemEventMultiWait(pThis->hSemEventFrame, RT_INDEFINITE_WAIT); 3905 AssertLogRelMsgReturn(RT_SUCCESS(rc) || rc == VERR_TIMEOUT, ("%Rrc\n", rc), rc); 3906 tsBeginServicing = RTTimeNanoTS(); 3907 cFramesProcessed = 0; 3889 3908 } 3890 3909 3891 AssertLogRelMsgReturn(RT_SUCCESS(rc) || rc == VERR_TIMEOUT, ("%Rrc\n", rc), rc);3892 3910 if (RT_UNLIKELY(pThread->enmState != PDMTHREADSTATE_RUNNING)) 3893 3911 break; 3894 3912 3895 tsNanoStart = RTTimeNanoTS();3896 3897 3913 RTCritSectEnter(&pThis->CritSect); 3898 3914 … … 3900 3916 pThis->fIdle = true; 3901 3917 3902 /* Frame boundary, so do EOF stuff here. */ 3903 bump_frame_number(pThis); 3904 if ( (pThis->dqic != 0x7) && (pThis->dqic != 0)) 3905 pThis->dqic--; 3906 3907 /* Clean up any URBs that have been removed. */ 3908 ohciCancelOrphanedURBs(pThis); 3909 3910 /* Start the next frame. */ 3911 ohciStartOfFrame(pThis); 3918 /* 3919 * Process new frames until we reached the required amount of 3920 * frames for this service period. We might need to catch up 3921 * here and process multiple frames at once due to scheduling 3922 * preempting us. This is required because isochronous transfers 3923 * have a tight timing requirement. 3924 */ 3925 uint64_t tsNow = RTTimeNanoTS(); 3926 uint64_t nsWait = 0; 3927 while (tsBeginServicing + (cFramesProcessed * RT_NS_1MS) < tsNow) 3928 { 3929 uint64_t tsNanoStart = RTTimeNanoTS(); 3930 LogFlowFunc(("Starting new frame at ts %llu\n", tsNanoStart)); 3931 3932 /* Frame boundary, so do EOF stuff here. */ 3933 bump_frame_number(pThis); 3934 if ( (pThis->dqic != 0x7) && (pThis->dqic != 0)) 3935 pThis->dqic--; 3936 3937 /* Clean up any URBs that have been removed. */ 3938 ohciCancelOrphanedURBs(pThis); 3939 3940 /* Start the next frame. */ 3941 ohciStartOfFrame(pThis); 3942 cFramesProcessed++; 3943 3944 tsNow = RTTimeNanoTS(); 3945 uint64_t tsFrameNext = tsNanoStart + pThis->nsWait; 3946 3947 if (tsFrameNext > tsNow) 3948 { 3949 nsWait = tsFrameNext - tsNow; 3950 LogFlowFunc(("Current frame took %llu nano seconds to finish, we can wait %llu ns for the next frame\n", tsNow - tsNanoStart, nsWait)); 3951 break; 3952 } 3953 else if (tsBeginServicing + (cFramesProcessed + 100) * RT_NS_1MS < tsNow) 3954 { 3955 /* If we lag to far behind stop trying to catch up. */ 3956 LogRel(("OHCI#%u: Lagging too far behind, not trying to catch up anymore. Expect glitches with USB devices\n", 3957 pThis->pDevInsR3->iInstance)); 3958 tsBeginServicing = tsNow; 3959 cFramesProcessed = 0; 3960 } 3961 } 3912 3962 3913 3963 RTCritSectLeave(&pThis->CritSect); 3914 3964 3915 3965 /* Wait for the next round. */ 3916 RTMSINTERVAL msWait = (RTMSINTERVAL)(((RTTimeNanoTS() + pThis->nsWait) - tsNanoStart) / 1000000); 3917 rc = RTSemEventWait(pThis->hSemEventFrame, msWait); 3966 if (nsWait >= 500 * RT_NS_1US) 3967 { 3968 LogFlowFunc(("Going to sleep for at least %llu ns\n", nsWait)); 3969 int rc = RTSemEventMultiWaitEx(pThis->hSemEventFrame, RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_UNINTERRUPTIBLE, 3970 nsWait); 3971 AssertLogRelMsg(RT_SUCCESS(rc) || rc == VERR_TIMEOUT, ("%Rrc\n", rc)); 3972 RTSemEventMultiReset(pThis->hSemEventFrame); 3973 } 3918 3974 } 3919 3975 … … 3931 3987 { 3932 3988 POHCI pThis = PDMINS_2_DATA(pDevIns, POHCI); 3933 return RTSemEvent Signal(pThis->hSemEventFrame);3989 return RTSemEventMultiSignal(pThis->hSemEventFrame); 3934 3990 } 3935 3991 … … 3937 3993 * Do frame processing on frame boundary 3938 3994 */ 3939 static void ohciFrameBoundaryTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) 3940 { 3941 POHCI pThis = (POHCI)pvUser; 3942 STAM_PROFILE_START(&pThis->StatTimer, a); 3943 STAM_PROFILE_STOP(&pThis->StatTimer, a); 3995 static DECLCALLBACK(void) ohciFrameBoundaryTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) 3996 { 3944 3997 } 3945 3998 … … 3958 4011 bool fBusActive = ASMAtomicXchgBool(&pThis->fBusStarted, true); 3959 4012 if (!fBusActive) 3960 RTSemEvent Signal(pThis->hSemEventFrame);4013 RTSemEventMultiSignal(pThis->hSemEventFrame); 3961 4014 } 3962 4015 … … 3973 4026 3974 4027 /* Signal the frame thread to stop. */ 3975 RTSemEvent Signal(pThis->hSemEventFrame);4028 RTSemEventMultiSignal(pThis->hSemEventFrame); 3976 4029 3977 4030 /* Wait for signal from the thrad that it stopped. */ … … 5609 5662 LogFlowFunc(("Bus was active, restart frame thread\n")); 5610 5663 ASMAtomicXchgBool(&pThis->fBusStarted, true); 5611 RTSemEvent Signal(pThis->hSemEventFrame);5664 RTSemEventMultiSignal(pThis->hSemEventFrame); 5612 5665 } 5613 5666 } … … 5703 5756 */ 5704 5757 if (pThis->hSemEventFrame) 5705 RTSemEvent Destroy(pThis->hSemEventFrame);5758 RTSemEventMultiDestroy(pThis->hSemEventFrame); 5706 5759 if (pThis->hSemEventFrameStopped) 5707 5760 RTSemEventMultiDestroy(pThis->hSemEventFrameStopped); … … 5874 5927 N_("EHCI: Failed to create critical section")); 5875 5928 5876 rc = RTSemEvent Create(&pThis->hSemEventFrame);5929 rc = RTSemEventMultiCreate(&pThis->hSemEventFrame); 5877 5930 AssertRCReturn(rc, rc); 5878 5931 … … 5886 5939 5887 5940 rc = PDMDevHlpThreadCreate(pDevIns, &pThis->hThreadFrame, pThis, ohciR3ThreadFrame, 5888 ohciR3ThreadFrameWakeup, 0, RTTHREADTYPE_ IO, "OhciFramer");5941 ohciR3ThreadFrameWakeup, 0, RTTHREADTYPE_TIMER, "OhciFramer"); 5889 5942 if (RT_FAILURE(rc)) 5890 5943 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, … … 5903 5956 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatCanceledGenUrbs, STAMTYPE_COUNTER, "/Devices/OHCI/CanceledGenUrbs", STAMUNIT_OCCURENCES, "Detected canceled general URBs."); 5904 5957 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatDroppedUrbs, STAMTYPE_COUNTER, "/Devices/OHCI/DroppedUrbs", STAMUNIT_OCCURENCES, "Dropped URBs (endpoint halted, or URB canceled)."); 5905 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatTimer, STAMTYPE_PROFILE, "/Devices/OHCI/Timer", STAMUNIT_TICKS_PER_CALL, "Profiling ohciFrameBoundaryTimer.");5906 5958 #endif 5907 5959 -
TabularUnified trunk/src/VBox/Devices/USB/DrvVUSBRootHub.cpp ¶
r56292 r56454 429 429 */ 430 430 pUrb->enmState = VUSBURBSTATE_ALLOCATED; 431 pUrb->fCompleting = false; 431 432 pUrb->pszDesc = NULL; 432 433 pUrb->VUsb.pNext = NULL; … … 598 599 * Cancel and reap the URB(s) on an endpoint. 599 600 */ 600 LogFlow(("vusbRhCancelUrbsEp: pRh=%p pUrb=%p\n", pRh ));601 LogFlow(("vusbRhCancelUrbsEp: pRh=%p pUrb=%p\n", pRh, pUrb)); 601 602 602 603 vusbUrbCancelAsync(pUrb, CANCELMODE_UNDO); -
TabularUnified trunk/src/VBox/Devices/USB/VUSBDevice.cpp ¶
r56395 r56454 1047 1047 * Iterate the URBs and cancel them. 1048 1048 */ 1049 RTCritSectEnter(&pDev->CritSectAsyncUrbs);1050 1049 PVUSBURB pUrb = pDev->pAsyncUrbHead; 1051 1050 while (pUrb) … … 1064 1063 * Reap any URBs which became ripe during cancel now. 1065 1064 */ 1065 RTCritSectEnter(&pDev->CritSectAsyncUrbs); 1066 1066 unsigned cReaped; 1067 1067 do -
TabularUnified trunk/src/VBox/Devices/USB/VUSBUrb.cpp ¶
r56292 r56454 977 977 || pUrb->enmState == VUSBURBSTATE_CANCELLED); 978 978 if (pUrb->enmState != VUSBURBSTATE_CANCELLED) 979 { 979 980 pUrb->enmState = VUSBURBSTATE_ALLOCATED; 981 pUrb->fCompleting = false; 982 } 980 983 RTCritSectLeave(&pPipe->CritSectCtrl); 981 984 … … 1012 1015 || pUrb->enmState == VUSBURBSTATE_CANCELLED, ("%d\n", pUrb->enmState)); 1013 1016 1014 if (pUrb->VUsb.pDev->hSniffer) 1017 if ( pUrb->VUsb.pDev 1018 && pUrb->VUsb.pDev->hSniffer) 1015 1019 { 1016 1020 int rc = VUSBSnifferRecordEvent(pUrb->VUsb.pDev->hSniffer, pUrb, … … 1288 1292 */ 1289 1293 pExtra->Urb.enmState = VUSBURBSTATE_ALLOCATED; 1294 pExtra->Urb.fCompleting = false; 1290 1295 } 1291 1296 … … 1299 1304 pExtra->enmStage = CTLSTAGE_SETUP; 1300 1305 if (pExtra->Urb.enmState != VUSBURBSTATE_CANCELLED) 1306 { 1301 1307 pExtra->Urb.enmState = VUSBURBSTATE_ALLOCATED; 1308 pExtra->Urb.fCompleting = false; 1309 } 1302 1310 } 1303 1311 … … 1345 1353 Assert(pUrb->VUsb.pvFreeCtx == &pExtra->Urb); 1346 1354 pUrb->enmState = VUSBURBSTATE_ALLOCATED; 1355 pUrb->fCompleting = false; 1347 1356 } 1348 1357 } … … 1394 1403 pExtra->Urb.u32Magic = VUSBURB_MAGIC; 1395 1404 pExtra->Urb.enmState = VUSBURBSTATE_ALLOCATED; 1405 pExtra->Urb.fCompleting = false; 1396 1406 #ifdef LOG_ENABLED 1397 1407 RTStrAPrintf(&pExtra->Urb.pszDesc, "URB %p msg->%p", &pExtra->Urb, pUrb); … … 1460 1470 pExtra->pMsg = (PVUSBSETUP)pExtra->Urb.abData; 1461 1471 pExtra->Urb.enmState = VUSBURBSTATE_ALLOCATED; 1472 pExtra->Urb.fCompleting = false; 1462 1473 } 1463 1474 … … 2180 2191 void vusbUrbCancelAsync(PVUSBURB pUrb, CANCELMODE mode) 2181 2192 { 2182 int rc = vusbDevIoThreadExec(pUrb->VUsb.pDev, 0 /* fFlags */, (PFNRT)vusbUrbCancelWorker, 2, pUrb, mode); 2183 AssertRC(rc); 2193 /* Don't try to cancel the URB when completion is in progress at the moment. */ 2194 if (!ASMAtomicXchgBool(&pUrb->fCompleting, true)) 2195 { 2196 int rc = vusbDevIoThreadExec(pUrb->VUsb.pDev, 0 /* fFlags */, (PFNRT)vusbUrbCancelWorker, 2, pUrb, mode); 2197 AssertRC(rc); 2198 } 2184 2199 } 2185 2200 … … 2200 2215 { 2201 2216 pUrb->enmState = VUSBURBSTATE_REAPED; 2202 vusbUrbCompletion(pUrb); 2217 if (!ASMAtomicXchgBool(&pUrb->fCompleting, true)) 2218 vusbUrbCompletion(pUrb); 2203 2219 } 2204 2220 else if (pUrb->enmState == VUSBURBSTATE_CANCELLED)
Note:
See TracChangeset
for help on using the changeset viewer.