- Timestamp:
- Nov 17, 2009 9:44:52 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevATA.cpp
r24587 r24741 3746 3746 * @returns true on success. 3747 3747 * @returns false when the thread is still processing. 3748 * @param pThis Pointer to the controller data. 3749 * @param cMillies How long to wait (total). This isn't very accurate. 3748 * @param pThis Pointer to the controller data. 3749 * @param cMillies How long to wait (total). This isn't very 3750 * accurate. 3751 * @param fLeaveSignallingOn Leave the signalling on so that it will notifiy 3752 * PDM about completion of the asynchronous 3753 * notification. 3750 3754 */ 3751 static bool ataWaitForAsyncIOIsIdle(PATACONTROLLER pCtl, unsigned cMillies )3755 static bool ataWaitForAsyncIOIsIdle(PATACONTROLLER pCtl, unsigned cMillies, bool fLeaveSignallingOn) 3752 3756 { 3753 3757 uint64_t u64Start; … … 3785 3789 } 3786 3790 3787 ASMAtomicWriteBool(&pCtl->fSignalIdle, false); 3791 if (fRc || !fLeaveSignallingOn) 3792 ASMAtomicWriteBool(&pCtl->fSignalIdle, false); 3788 3793 return fRc; 3789 3794 } … … 3795 3800 * @returns true on success. 3796 3801 * @returns false when one or more threads is still processing. 3797 * @param pThis Pointer to the instance data. 3798 * @param cMillies How long to wait per controller. 3802 * @param pThis Pointer to the instance data. 3803 * @param cMillies How long to wait per controller. 3804 * @param fLeaveSignallingOn Leave the signalling on so that it will notifiy 3805 * PDM about completion of the asynchronous 3806 * notification. 3799 3807 */ 3800 static bool ataWaitForAllAsyncIOIsIdle(PPDMDEVINS pDevIns, uint32_t cMillies )3808 static bool ataWaitForAllAsyncIOIsIdle(PPDMDEVINS pDevIns, uint32_t cMillies, bool fLeaveSignallingOn) 3801 3809 { 3802 3810 PCIATAState *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *); … … 3804 3812 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aCts); i++) 3805 3813 if ( pThis->aCts[i].AsyncIOThread != NIL_RTTHREAD 3806 && !ataWaitForAsyncIOIsIdle(&pThis->aCts[i], cMillies ))3814 && !ataWaitForAsyncIOIsIdle(&pThis->aCts[i], cMillies, fLeaveSignallingOn)) 3807 3815 { 3808 3816 LogRel(("PIIX3 ATA: Ctl#%u is still executing, DevSel=%d AIOIf=%d CmdIf0=%#04x CmdIf1=%#04x\n", … … 4568 4576 if ( pCtl->fSignalIdle 4569 4577 && ataAsyncIOIsIdle(pCtl, false /*fStrict*/)) 4578 { 4570 4579 RTThreadUserSignal(pCtl->AsyncIOThread); 4580 PDMDevHlpAsyncNotificationCompleted(pCtl->pDevInsR3); 4581 } 4571 4582 4572 4583 rc = RTSemMutexRelease(pCtl->AsyncIORequestMutex); AssertRC(rc); … … 5304 5315 ataAsyncIOPutRequest(&pThis->aCts[i], &ataResetARequest); 5305 5316 ataAsyncIOPutRequest(&pThis->aCts[i], &ataResetCRequest); 5306 if (!ataWaitForAsyncIOIsIdle(&pThis->aCts[i], 30000)) 5317 /** @todo Deadlock alert. see @bugref{4394}. */ 5318 if (!ataWaitForAsyncIOIsIdle(&pThis->aCts[i], 30000, false /*fLeaveSignallingOn*/)) 5307 5319 { 5308 5320 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "DevATA_ASYNCBUSY", … … 5622 5634 5623 5635 #ifdef IN_RING3 5636 5637 /** 5638 * Callback employed by ataSuspend and ataPowerOff. 5639 * 5640 * @returns true if we've quiesced, false if we're still working. 5641 * @param pDevIns The device instance. 5642 */ 5643 static DECLCALLBACK(bool) ataR3IsAsyncSuspendOrPowerOffDone(PPDMDEVINS pDevIns) 5644 { 5645 return ataWaitForAllAsyncIOIsIdle(pDevIns, 0, true /*fLeaveSignallingOn*/); 5646 } 5647 5648 5649 /** 5650 * Common worker for ataSuspend and ataPowerOff. 5651 */ 5652 static void ataR3SuspendOrPowerOff(PPDMDEVINS pDevIns) 5653 { 5654 #if 1 5655 if (!ataWaitForAllAsyncIOIsIdle(pDevIns, 0, true /*fLeaveSignallingOn*/)) 5656 PDMDevHlpSetAsyncNotification(pDevIns, ataR3IsAsyncSuspendOrPowerOffDone); 5657 #else 5658 if (!ataWaitForAllAsyncIOIsIdle(pDevIns, 20000)) 5659 AssertMsgFailed(("Async I/O didn't stop in ~40 seconds!\n")); 5660 #endif 5661 } 5662 5624 5663 5625 5664 DECLINLINE(void) ataRelocBuffer(PPDMDEVINS pDevIns, ATADevState *s) … … 5981 6020 { 5982 6021 Log(("%s:\n", __FUNCTION__)); 5983 if (!ataWaitForAllAsyncIOIsIdle(pDevIns, 20000)) 5984 AssertMsgFailed(("Async I/O didn't stop in ~40 seconds!\n")); 5985 return; 6022 ataR3SuspendOrPowerOff(pDevIns); 5986 6023 } 5987 6024 … … 6020 6057 { 6021 6058 Log(("%s:\n", __FUNCTION__)); 6022 if (!ataWaitForAllAsyncIOIsIdle(pDevIns, 20000)) 6023 AssertMsgFailed(("Async I/O didn't stop in ~40 seconds!\n")); 6024 return; 6059 ataR3SuspendOrPowerOff(pDevIns); 6025 6060 } 6026 6061
Note:
See TracChangeset
for help on using the changeset viewer.