- Timestamp:
- Oct 26, 2009 11:22:39 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 53983
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/pdmifs.h
r23185 r24098 2556 2556 * 2557 2557 * @returns VBox status code. 2558 * @param pInterface Pointer to this interface.2559 * @param pSCSIRequest Pointer to the SCSI request to execute.2558 * @param pInterface Pointer to this interface. 2559 * @param pSCSIRequest Pointer to the SCSI request to execute. 2560 2560 */ 2561 2561 DECLR3CALLBACKMEMBER(int, pfnSCSIRequestSend, (PPDMISCSICONNECTOR pInterface, PPDMSCSIREQUEST pSCSIRequest)); 2562 2563 /** 2564 * Wait for all current requests to complete. 2565 * 2566 * This can only be called while the VM is running. 2567 * 2568 * @returns VINF_SUCCESS, VERR_NO_MEMORY, VERR_INVALID_STATE or VERR_TIMEOUT. 2569 * @param pInterface Pointer to this interface. 2570 * @param cMillies The timeout in milliseconds or RT_INDEFINITE_WAIT. 2571 */ 2572 DECLR3CALLBACKMEMBER(int, pfnSyncronizeRequests, (PPDMISCSICONNECTOR pInterface, uint32_t cMillies)); 2562 2573 2563 2574 } PDMISCSICONNECTOR; -
trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
r24071 r24098 2381 2381 pThis->cMaxBuses = 1; 2382 2382 pThis->cbReplyFrame = 128; /* @todo Figure out where it is needed. */ 2383 /* @todo: Put stuff to reset here. */2383 /** @todo: Put stuff to reset here. */ 2384 2384 2385 2385 lsilogicInitializeConfigurationPages(pThis); … … 4786 4786 * @retruns Flag which indicates if all I/O completed in the given timeout. 4787 4787 * @param pLsiLogic Pointer to the dveice instance to check. 4788 * @param cMillis Timeout in milliseconds to wait .4788 * @param cMillis Timeout in milliseconds to wait per device. 4789 4789 */ 4790 4790 static bool lsilogicWaitForAsyncIOFinished(PLSILOGICSCSI pLsiLogic, unsigned cMillies) 4791 4791 { 4792 4792 uint64_t u64Start; 4793 bool fIdle;4793 unsigned i; 4794 4794 4795 4795 /* … … 4799 4799 for (;;) 4800 4800 { 4801 fIdle = true;4802 4803 4801 /* Check every port. */ 4804 for (unsigned i = 0; i < RT_ELEMENTS(pLsiLogic->aDeviceStates); i++) 4805 { 4806 PLSILOGICDEVICE pLsiLogicDevice = &pLsiLogic->aDeviceStates[i]; 4807 if (ASMAtomicReadU32(&pLsiLogicDevice->cOutstandingRequests)) 4808 { 4809 fIdle = false; 4802 for (i = 0; i < RT_ELEMENTS(pLsiLogic->aDeviceStates); i++) 4803 if (ASMAtomicReadU32(&pLsiLogic->aDeviceStates[i].cOutstandingRequests)) 4810 4804 break; 4811 } 4812 } 4813 if ( fIdle 4814 || RTTimeMilliTS() - u64Start >= cMillies) 4815 break; 4816 4817 /* Sleep for a bit. */ 4818 RTThreadSleep(100); /** @todo wait on something which can be woken up. 100ms is too long for teleporting VMs! */ 4819 } 4820 4821 return fIdle; 4805 if (i >= RT_ELEMENTS(pLsiLogic->aDeviceStates)) 4806 return true; 4807 4808 uint64_t cMsElapsed = RTTimeMilliTS() - u64Start; 4809 if (cMsElapsed >= cMillies) 4810 return false; 4811 4812 /* Try synchronize the request queue for this device. */ 4813 PPDMISCSICONNECTOR pDrvSCSIConnector = pLsiLogic->aDeviceStates[i].pDrvSCSIConnector; 4814 uint32_t cMsLeft = cMillies - (uint32_t)cMsElapsed; 4815 pDrvSCSIConnector->pfnSyncronizeRequests(pDrvSCSIConnector, RT_MAX(cMsLeft, 100)); 4816 } 4822 4817 } 4823 4818 … … 4833 4828 } 4834 4829 4835 static DECLCALLBACK(int) lsilogicSave LoadPrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)4830 static DECLCALLBACK(int) lsilogicSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 4836 4831 { 4837 4832 PLSILOGICSCSI pLsiLogic = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI); 4838 4833 4839 /* Wait that no task is pending on any device. */4840 if (!lsilogicWaitForAsyncIOFinished(pLsiLogic, 20000))4841 {4842 AssertLogRelMsgFailed(("LsiLogic: There are still tasks outstanding\n"));4843 return VERR_TIMEOUT;4844 }4845 4846 return VINF_SUCCESS;4847 }4848 4849 static DECLCALLBACK(int) lsilogicSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)4850 {4851 PLSILOGICSCSI pLsiLogic = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);4852 4853 4834 /* Every device first. */ 4854 lsilogic SaveLoadPrep(pDevIns, pSSM);4835 lsilogicLiveExec(pDevIns, pSSM, SSM_PASS_FINAL); 4855 4836 for (unsigned i = 0; i < RT_ELEMENTS(pLsiLogic->aDeviceStates); i++) 4856 4837 { … … 5172 5153 5173 5154 /** 5174 * @copydoc FNPDMDEVPOWEROFF5175 */5176 static DECLCALLBACK(void) lsilogicPowerOff(PPDMDEVINS pDevIns)5177 {5178 PLSILOGICSCSI pLsiLogic = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);5179 5180 bool fIdle = lsilogicWaitForAsyncIOFinished(pLsiLogic, 20000);5181 Assert(fIdle);5182 }5183 5184 /**5185 * @copydoc FNPDMDEVSUSPEND5186 */5187 static DECLCALLBACK(void) lsilogicSuspend(PPDMDEVINS pDevIns)5188 {5189 PLSILOGICSCSI pLsiLogic = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);5190 5191 bool fIdle = lsilogicWaitForAsyncIOFinished(pLsiLogic, 20000);5192 Assert(fIdle);5193 }5194 5195 /**5196 5155 * @copydoc FNPDMDEVRESET 5197 5156 */ … … 5201 5160 int rc; 5202 5161 5162 /** @todo r=bird: this is a deadlock trap. We're EMT(0), if there are 5163 * outstanding requests they may require EMT interaction because of 5164 * physical write backs around lsilogicDeviceSCSIRequestCompleted... 5165 * 5166 * I have some more generic solution for delayed suspend, reset and 5167 * poweroff handling that I'm considering. The idea is that the 5168 * notification callback returns a status indicating that it didn't 5169 * complete and needs to be called again or something. EMT continues on 5170 * the next device and when it's done, it processes incoming requests and 5171 * does another notification round... This way we could combine the waits 5172 * in the I/O controllers and reduce the time it takes to suspend a VM a 5173 * wee bit... 5174 */ 5203 5175 bool fIdle = lsilogicWaitForAsyncIOFinished(pLsiLogic, 20000); 5204 5176 Assert(fIdle); … … 5449 5421 5450 5422 /* Register save state handlers. */ 5451 rc = PDMDevHlpSSMRegisterEx(pDevIns, LSILOGIC_SAVED_STATE_VERSION, sizeof(*pThis), NULL, 5452 NULL, lsilogicLiveExec, NULL, 5453 lsilogicSaveLoadPrep, lsilogicSaveExec, NULL, 5454 lsilogicSaveLoadPrep, lsilogicLoadExec, NULL); 5423 rc = PDMDevHlpSSMRegister3(pDevIns, LSILOGIC_SAVED_STATE_VERSION, sizeof(*pThis), 5424 lsilogicLiveExec, lsilogicSaveExec, lsilogicLoadExec); 5455 5425 if (RT_FAILURE(rc)) 5456 5426 return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic cannot register save state handlers")); … … 5503 5473 lsilogicReset, 5504 5474 /* pfnSuspend */ 5505 lsilogicSuspend,5475 NULL, 5506 5476 /* pfnResume */ 5507 5477 NULL, … … 5515 5485 NULL, 5516 5486 /* pfnPowerOff */ 5517 lsilogicPowerOff,5487 NULL, 5518 5488 /* pfnSoftReset */ 5519 5489 NULL, -
trunk/src/VBox/Devices/Storage/DrvSCSI.cpp
r23472 r24098 671 671 672 672 /** 673 * Request function to syncronize the request execution. 674 * 675 * @returns VINF_SUCCESS. 676 */ 677 static int drvscsiAsyncIOLoopSyncCallback(void) 678 { 679 return VINF_SUCCESS; 680 } 681 682 /** 673 683 * Request function to wakeup the thread. 674 684 * … … 716 726 rc = RTReqCall(pThis->pQueueRequests, &pReq, 10000 /* 10 sec. */, (PFNRT)drvscsiAsyncIOLoopWakeupFunc, 0); 717 727 AssertMsgRC(rc, ("Inserting request into queue failed rc=%Rrc\n", rc)); 728 if (RT_SUCCESS(rc)) 729 RTReqFree(pReq); 730 /*else: leak it */ 718 731 719 732 return rc; … … 735 748 736 749 return VINF_SUCCESS; 750 } 751 752 /** @copydoc PDMISCSICONNECTOR::pfnSyncronizeRequests. */ 753 static DECLCALLBACK(int) drvscsiSyncronizeRequests(PPDMISCSICONNECTOR pInterface, uint32_t cMillies) 754 { 755 int rc; 756 PDRVSCSI pThis = PDMISCSICONNECTOR_2_DRVSCSI(pInterface); 757 PRTREQ pReq; 758 759 Assert(cMillies > 100); 760 AssertReturn(pThis->pQueueRequests, VERR_INVALID_STATE); 761 762 rc = RTReqCall(pThis->pQueueRequests, &pReq, cMillies, (PFNRT)drvscsiAsyncIOLoopSyncCallback, 0); 763 AssertMsgRC(rc, ("Inserting request into queue failed rc=%Rrc\n", rc)); 764 if (RT_SUCCESS(rc)) 765 RTReqFree(pReq); 766 /*else: leak it */ 767 768 return rc; 737 769 } 738 770 … … 794 826 pDrvIns->IBase.pfnQueryInterface = drvscsiQueryInterface; 795 827 pThis->ISCSIConnector.pfnSCSIRequestSend = drvscsiRequestSend; 828 pThis->ISCSIConnector.pfnSyncronizeRequests = drvscsiSyncronizeRequests; 796 829 797 830 /* … … 904 937 NULL, 905 938 /* pfnDetach */ 906 NULL, 939 NULL, 907 940 /* pfnPowerOff */ 908 NULL, 941 NULL, 909 942 /* pfnSoftReset */ 910 943 NULL,
Note:
See TracChangeset
for help on using the changeset viewer.