Changeset 24749 in vbox for trunk/src/VBox
- Timestamp:
- Nov 18, 2009 12:32:14 AM (15 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevAHCI.cpp
r24588 r24749 583 583 PDMCRITSECT lock; 584 584 585 /** Semaphore that gets set when fSignalIdle is set. */586 RTSEMEVENT hEvtIdle;587 #if HC_ARCH_BITS == 32588 uint32_t Alignment7;589 #endif590 591 585 /** Bitmask of ports which asserted an interrupt. */ 592 586 uint32_t u32PortsInterrupted; … … 601 595 /** If the new async interface is used if available. */ 602 596 bool fUseAsyncInterfaceIfAvailable; 603 /** Indicates that hEvtIdle should be signalled when a port is entering the604 * idle state. */597 /** Indicates that PDMDevHlpAsyncNotificationCompleted should be called when 598 * a port is entering the idle state. */ 605 599 bool volatile fSignalIdle; 606 600 bool afAlignment8[1]; … … 4928 4922 4929 4923 if (pAhciPort->uActTasksActive == 0 && pAhciPort->pAhciR3->fSignalIdle) 4930 RTSemEventSignal(pAhciPort->pAhciR3->hEvtIdle);4924 PDMDevHlpAsyncNotificationCompleted(pAhciPort->pDevInsR3); 4931 4925 return rc; 4932 4926 } … … 5387 5381 ASMAtomicXchgBool(&pAhciPort->fAsyncIOThreadIdle, true); 5388 5382 if (pAhci->fSignalIdle) 5389 RTSemEventSignal(pAhci->hEvtIdle);5383 PDMDevHlpAsyncNotificationCompleted(pAhciPort->pDevInsR3); 5390 5384 5391 5385 rc = RTSemEventWait(pAhciPort->AsyncIORequestSem, 1000); … … 5652 5646 5653 5647 if (pAhci->fSignalIdle) 5654 RTSemEventSignal(pAhci->hEvtIdle);5648 PDMDevHlpAsyncNotificationCompleted(pAhciPort->pDevInsR3); 5655 5649 5656 5650 /* Free task state memory */ … … 5785 5779 ataControllerDestroy(&pAhci->aCts[i]); 5786 5780 5787 RTSemEventDestroy(pAhci->hEvtIdle);5788 pAhci->hEvtIdle = NIL_RTSEMEVENT;5789 5790 5781 PDMR3CritSectDelete(&pAhci->lock); 5791 5782 } … … 5895 5886 } 5896 5887 5897 static bool ahciWaitForAllAsyncIOIsFinished(PPDMDEVINS pDevIns, unsigned cMillies) 5898 { 5899 PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI); 5900 uint64_t u64Start; 5901 PAHCIPort pAhciPort; 5902 bool fAllFinished; 5903 5904 ASMAtomicWriteBool(&pAhci->fSignalIdle, true); 5905 u64Start = RTTimeMilliTS(); 5906 for (;;) 5907 { 5908 fAllFinished = true; 5909 for (uint32_t i = 0; i < RT_ELEMENTS(pAhci->ahciPort); i++) 5910 { 5911 pAhciPort = &pAhci->ahciPort[i]; 5912 5913 if (pAhciPort->pDrvBase) 5914 { 5915 if (pAhciPort->fAsyncInterface) 5916 fAllFinished &= (pAhciPort->uActTasksActive == 0); 5917 else 5918 fAllFinished &= ((pAhciPort->uActTasksActive == 0) && (pAhciPort->fAsyncIOThreadIdle)); 5919 5920 if (!fAllFinished) 5921 break; 5922 } 5923 } 5924 if ( fAllFinished 5925 || RTTimeMilliTS() - u64Start >= cMillies) 5926 break; 5927 5928 /* Wait for a port to signal idleness. */ 5929 int rc = RTSemEventWait(pAhci->hEvtIdle, 100 /*ms*/); 5930 AssertMsg(RT_SUCCESS(rc) || rc == VERR_TIMEOUT, ("%Rrc\n", rc)); NOREF(rc); 5931 } 5932 5933 ASMAtomicWriteBool(&pAhci->fSignalIdle, false); 5934 return fAllFinished; 5888 /** 5889 * Checks if all asynchronous I/O is finished. 5890 * 5891 * @returns true if quiesced, false if busy. 5892 * @param pDevIns The device instance. 5893 */ 5894 static bool ahciR3AllAsyncIOIsFinished(PPDMDEVINS pDevIns) 5895 { 5896 PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI); 5897 5898 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->ahciPort); i++) 5899 { 5900 PAHCIPort pThisPort = &pThis->ahciPort[i]; 5901 if (pThisPort->pDrvBase) 5902 { 5903 bool fFinished; 5904 if (pThisPort->fAsyncInterface) 5905 fFinished = (pThisPort->uActTasksActive == 0); 5906 else 5907 fFinished = ((pThisPort->uActTasksActive == 0) && (pThisPort->fAsyncIOThreadIdle)); 5908 if (!fFinished) 5909 return false; 5910 } 5911 } 5912 return true; 5935 5913 } 5936 5914 … … 5939 5917 PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI); 5940 5918 5941 if (!ahciWaitForAllAsyncIOIsFinished(pDevIns, 20000)) 5942 AssertMsgFailed(("One port is still active\n")); 5919 Assert(ahciR3AllAsyncIOIsFinished(pDevIns)); 5943 5920 5944 5921 for (uint32_t i = 0; i < RT_ELEMENTS(pAhci->aCts); i++) … … 5968 5945 5969 5946 return VINF_SUCCESS; 5947 } 5948 5949 /** 5950 * Callback employed by ataSuspend and ataR3PowerOff. 5951 * 5952 * @returns true if we've quiesced, false if we're still working. 5953 * @param pDevIns The device instance. 5954 */ 5955 static DECLCALLBACK(bool) ahciR3IsAsyncSuspendOrPowerOffDone(PPDMDEVINS pDevIns) 5956 { 5957 if (!ahciR3AllAsyncIOIsFinished(pDevIns)) 5958 return false; 5959 5960 PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI); 5961 ASMAtomicWriteBool(&pThis->fSignalIdle, false); 5962 return true; 5963 } 5964 5965 /** 5966 * Common worker for ataSuspend and ataR3PowerOff. 5967 */ 5968 static void ahciR3SuspendOrPowerOff(PPDMDEVINS pDevIns) 5969 { 5970 PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI); 5971 5972 ASMAtomicWriteBool(&pThis->fSignalIdle, true); 5973 if (!ahciR3AllAsyncIOIsFinished(pDevIns)) 5974 PDMDevHlpSetAsyncNotification(pDevIns, ahciR3IsAsyncSuspendOrPowerOffDone); 5975 else 5976 ASMAtomicWriteBool(&pThis->fSignalIdle, false); 5970 5977 } 5971 5978 … … 5978 5985 static DECLCALLBACK(void) ahciSuspend(PPDMDEVINS pDevIns) 5979 5986 { 5987 PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI); 5988 Log(("%s:\n", __FUNCTION__)); 5989 5990 ahciR3SuspendOrPowerOff(pDevIns); 5991 5992 for (uint32_t i = 0; i < RT_ELEMENTS(pAhci->aCts); i++) 5993 ataControllerSuspend(&pAhci->aCts[i]); 5994 } 5995 5996 /** 5997 * Resume notification. 5998 * 5999 * @param pDevIns The device instance data. 6000 */ 6001 static DECLCALLBACK(void) ahciResume(PPDMDEVINS pDevIns) 6002 { 5980 6003 PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI); 5981 5982 if (!ahciWaitForAllAsyncIOIsFinished(pDevIns, 20000))5983 AssertMsgFailed(("AHCI: One port is still active\n"));5984 6004 5985 6005 Log(("%s:\n", __FUNCTION__)); 5986 6006 for (uint32_t i = 0; i < RT_ELEMENTS(pAhci->aCts); i++) 5987 {5988 ataControllerSuspend(&pAhci->aCts[i]);5989 }5990 return;5991 }5992 5993 5994 /**5995 * Resume notification.5996 *5997 * @returns VBox status.5998 * @param pDevIns The device instance data.5999 */6000 static DECLCALLBACK(void) ahciResume(PPDMDEVINS pDevIns)6001 {6002 PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);6003 6004 Log(("%s:\n", __FUNCTION__));6005 for (uint32_t i = 0; i < RT_ELEMENTS(pAhci->aCts); i++)6006 {6007 6007 ataControllerResume(&pAhci->aCts[i]); 6008 }6009 6008 return; 6010 6009 } … … 6400 6399 6401 6400 /** 6402 * Reset notification.6401 * Common reset worker. 6403 6402 * 6404 * @returns VBox status.6405 6403 * @param pDevIns The device instance data. 6406 6404 */ 6407 static DECLCALLBACK(void) ahciReset(PPDMDEVINS pDevIns)6405 static int ahciR3ResetCommon(PPDMDEVINS pDevIns, bool fConstructor) 6408 6406 { 6409 6407 PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI); 6410 6411 if (!ahciWaitForAllAsyncIOIsFinished(pDevIns, 20000))6412 AssertMsgFailed(("AHCI: One port is still active\n"));6413 6408 6414 6409 ahciHBAReset(pAhci); … … 6420 6415 for (uint32_t i = 0; i < RT_ELEMENTS(pAhci->aCts); i++) 6421 6416 ataControllerReset(&pAhci->aCts[i]); 6417 return VINF_SUCCESS; 6418 } 6419 6420 /** 6421 * Callback employed by ahciReset. 6422 * 6423 * @returns true if we've quiesced, false if we're still working. 6424 * @param pDevIns The device instance. 6425 */ 6426 static DECLCALLBACK(bool) ahciR3IsAsyncResetDone(PPDMDEVINS pDevIns) 6427 { 6428 PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI); 6429 6430 if (!ahciR3AllAsyncIOIsFinished(pDevIns)) 6431 return false; 6432 ASMAtomicWriteBool(&pThis->fSignalIdle, false); 6433 6434 ahciR3ResetCommon(pDevIns, false /*fConstructor*/); 6435 return true; 6436 } 6437 6438 /** 6439 * Reset notification. 6440 * 6441 * @param pDevIns The device instance data. 6442 */ 6443 static DECLCALLBACK(void) ahciReset(PPDMDEVINS pDevIns) 6444 { 6445 PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI); 6446 6447 ASMAtomicWriteBool(&pThis->fSignalIdle, true); 6448 if (!ahciR3AllAsyncIOIsFinished(pDevIns)) 6449 PDMDevHlpSetAsyncNotification(pDevIns, ahciR3IsAsyncResetDone); 6450 else 6451 { 6452 ASMAtomicWriteBool(&pThis->fSignalIdle, false); 6453 ahciR3ResetCommon(pDevIns, false /*fConstructor*/); 6454 } 6422 6455 } 6423 6456 … … 6432 6465 PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI); 6433 6466 6434 if (!ahciWaitForAllAsyncIOIsFinished(pDevIns, 20000)) 6435 AssertMsgFailed(("AHCI: One port is still active\n")); 6467 ahciR3SuspendOrPowerOff(pDevIns); 6436 6468 6437 6469 for (uint32_t i = 0; i < RT_ELEMENTS(pAhci->aCts); i++) … … 6522 6554 pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns); 6523 6555 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 6524 pThis->hEvtIdle = NIL_RTSEMEVENT;6525 6556 6526 6557 PCIDevSetVendorId (&pThis->dev, 0x8086); /* Intel */ … … 6603 6634 return rc; 6604 6635 } 6605 6606 rc = RTSemEventCreate(&pThis->hEvtIdle);6607 AssertRCReturn(rc, rc);6608 6636 6609 6637 /* Create the timer for command completion coalescing feature. */ … … 6950 6978 return rc; 6951 6979 6952 ahciReset(pDevIns); 6953 6954 return rc; 6980 return ahciR3ResetCommon(pDevIns, true /*fConstructor*/); 6955 6981 } 6956 6982 -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeGC.cpp
r24624 r24749 1236 1236 GEN_CHECK_OFF(AHCI, aCts[1]); 1237 1237 GEN_CHECK_OFF(AHCI, lock); 1238 GEN_CHECK_OFF(AHCI, hEvtIdle);1239 1238 GEN_CHECK_OFF(AHCI, u32PortsInterrupted); 1240 1239 GEN_CHECK_OFF(AHCI, fReset);
Note:
See TracChangeset
for help on using the changeset viewer.