Changeset 24744 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Nov 17, 2009 10:33:38 PM (15 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PDM.cpp
r24740 r24744 1039 1039 1040 1040 1041 1042 1043 /** 1044 * This function will notify all the devices and their 1045 * attached drivers about the VM now being reset. 1041 /** 1042 * Worker for PDMR3Reset that deals with one driver. 1043 * 1044 * @param pDrvIns The driver instance. 1045 * @param pcAsync The asynchronous reset notification counter. 1046 * @param pszDeviceName The parent device name. 1047 * @param iDevInstance The parent device instance number. 1048 * @param iLun The parent LUN number. 1049 */ 1050 DECLINLINE(bool) pdmR3ResetDrv(PPDMDRVINS pDrvIns, unsigned *pcAsync, 1051 const char *pszDeviceName, uint32_t iDevInstance, uint32_t iLun) 1052 { 1053 if (!pDrvIns->Internal.s.fVMReset) 1054 { 1055 pDrvIns->Internal.s.fVMReset = true; 1056 if (pDrvIns->pDrvReg->pfnReset) 1057 { 1058 if (!pDrvIns->Internal.s.pfnAsyncNotify) 1059 { 1060 LogFlow(("PDMR3Reset: Notifying - driver '%s'/%d on LUN#%d of device '%s'/%d\n", 1061 pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance)); 1062 pDrvIns->pDrvReg->pfnReset(pDrvIns); 1063 if (pDrvIns->Internal.s.pfnAsyncNotify) 1064 LogFlow(("PDMR3Reset: Async notification started - driver '%s'/%d on LUN#%d of device '%s'/%d\n", 1065 pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance)); 1066 } 1067 else if (pDrvIns->Internal.s.pfnAsyncNotify(pDrvIns)) 1068 { 1069 pDrvIns->Internal.s.pfnAsyncNotify = false; 1070 LogFlow(("PDMR3Reset: Async notification completed - driver '%s'/%d on LUN#%d of device '%s'/%d\n", 1071 pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, iLun, pszDeviceName, iDevInstance)); 1072 } 1073 if (pDrvIns->Internal.s.pfnAsyncNotify) 1074 { 1075 pDrvIns->Internal.s.fVMReset = false; 1076 (*pcAsync)++; 1077 return false; 1078 } 1079 } 1080 } 1081 return true; 1082 } 1083 1084 1085 /** 1086 * Worker for PDMR3Reset that deals with one USB device instance. 1087 * 1088 * @param pUsbIns The USB device instance. 1089 * @param pcAsync The asynchronous reset notification counter. 1090 */ 1091 DECLINLINE(void) pdmR3ResetUsb(PPDMUSBINS pUsbIns, unsigned *pcAsync) 1092 { 1093 if (!pUsbIns->Internal.s.fVMReset) 1094 { 1095 pUsbIns->Internal.s.fVMReset = true; 1096 if (pUsbIns->pUsbReg->pfnVMReset) 1097 { 1098 if (!pUsbIns->Internal.s.pfnAsyncNotify) 1099 { 1100 LogFlow(("PDMR3Reset: Notifying - device '%s'/%d\n", pUsbIns->pUsbReg->szDeviceName, pUsbIns->iInstance)); 1101 pUsbIns->pUsbReg->pfnVMReset(pUsbIns); 1102 if (pUsbIns->Internal.s.pfnAsyncNotify) 1103 LogFlow(("PDMR3Reset: Async notification started - device '%s'/%d\n", pUsbIns->pUsbReg->szDeviceName, pUsbIns->iInstance)); 1104 } 1105 else if (pUsbIns->Internal.s.pfnAsyncNotify(pUsbIns)) 1106 { 1107 LogFlow(("PDMR3Reset: Async notification completed - device '%s'/%d\n", pUsbIns->pUsbReg->szDeviceName, pUsbIns->iInstance)); 1108 pUsbIns->Internal.s.pfnAsyncNotify = NULL; 1109 } 1110 if (pUsbIns->Internal.s.pfnAsyncNotify) 1111 { 1112 pUsbIns->Internal.s.fVMReset = false; 1113 (*pcAsync)++; 1114 } 1115 } 1116 } 1117 } 1118 1119 1120 /** 1121 * Worker for PDMR3Reset that deals with one device instance. 1122 * 1123 * @param pDevIns The device instance. 1124 * @param pcAsync The asynchronous reset notification counter. 1125 */ 1126 DECLINLINE(void) pdmR3ResetDev(PPDMDEVINS pDevIns, unsigned *pcAsync) 1127 { 1128 if (!(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_RESET)) 1129 { 1130 pDevIns->Internal.s.fIntFlags |= PDMDEVINSINT_FLAGS_RESET; 1131 if (pDevIns->pDevReg->pfnReset) 1132 { 1133 if (!pDevIns->Internal.s.pfnAsyncNotify) 1134 { 1135 LogFlow(("PDMR3Reset: Notifying - device '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1136 pDevIns->pDevReg->pfnReset(pDevIns); 1137 if (pDevIns->Internal.s.pfnAsyncNotify) 1138 LogFlow(("PDMR3Reset: Async notification started - device '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1139 } 1140 else if (pDevIns->Internal.s.pfnAsyncNotify(pDevIns)) 1141 { 1142 LogFlow(("PDMR3Reset: Async notification completed - device '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 1143 pDevIns->Internal.s.pfnAsyncNotify = NULL; 1144 } 1145 if (pDevIns->Internal.s.pfnAsyncNotify) 1146 { 1147 pDevIns->Internal.s.fIntFlags &= ~PDMDEVINSINT_FLAGS_RESET; 1148 (*pcAsync)++; 1149 } 1150 } 1151 } 1152 } 1153 1154 1155 /** 1156 * This function will notify all the devices and their attached drivers about 1157 * the VM now being reset. 1046 1158 * 1047 1159 * @param pVM VM Handle. … … 1050 1162 { 1051 1163 LogFlow(("PDMR3Reset:\n")); 1164 1165 /* 1166 * Clear all the reset flags. 1167 */ 1168 for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3) 1169 { 1170 pDevIns->Internal.s.fIntFlags &= ~PDMDEVINSINT_FLAGS_RESET; 1171 for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext) 1172 for (PPDMDRVINS pDrvIns = pLun->pTop; pDrvIns; pDrvIns = pDrvIns->Internal.s.pDown) 1173 pDrvIns->Internal.s.fVMReset = false; 1174 } 1175 #ifdef VBOX_WITH_USB 1176 for (PPDMUSBINS pUsbIns = pVM->pdm.s.pUsbInstances; pUsbIns; pUsbIns = pUsbIns->Internal.s.pNext) 1177 { 1178 pUsbIns->Internal.s.fVMReset = false; 1179 for (PPDMLUN pLun = pUsbIns->Internal.s.pLuns; pLun; pLun = pLun->pNext) 1180 for (PPDMDRVINS pDrvIns = pLun->pTop; pDrvIns; pDrvIns = pDrvIns->Internal.s.pDown) 1181 pDrvIns->Internal.s.fVMReset = false; 1182 } 1183 #endif 1184 1185 /* 1186 * The outer loop repeats until there are no more async requests. 1187 */ 1188 unsigned cAsync; 1189 for (unsigned iLoop = 0; ; iLoop++) 1190 { 1191 /* 1192 * Iterate thru the device instances and USB device instances, 1193 * processing the drivers associated with those. 1194 */ 1195 cAsync = 0; 1196 for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3) 1197 { 1198 unsigned const cAsyncStart = cAsync; 1199 1200 if (cAsync == cAsyncStart) 1201 for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext) 1202 for (PPDMDRVINS pDrvIns = pLun->pTop; pDrvIns; pDrvIns = pDrvIns->Internal.s.pDown) 1203 if (!pdmR3ResetDrv(pDrvIns, &cAsync, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pLun->iLun)) 1204 break; 1205 1206 if (cAsync == cAsyncStart) 1207 pdmR3ResetDev(pDevIns, &cAsync); 1208 } 1209 1210 #ifdef VBOX_WITH_USB 1211 for (PPDMUSBINS pUsbIns = pVM->pdm.s.pUsbInstances; pUsbIns; pUsbIns = pUsbIns->Internal.s.pNext) 1212 { 1213 unsigned const cAsyncStart = cAsync; 1214 1215 for (PPDMLUN pLun = pUsbIns->Internal.s.pLuns; pLun; pLun = pLun->pNext) 1216 for (PPDMDRVINS pDrvIns = pLun->pTop; pDrvIns; pDrvIns = pDrvIns->Internal.s.pDown) 1217 if (!pdmR3ResetDrv(pDrvIns, &cAsync, pUsbIns->pUsbReg->szDeviceName, pUsbIns->iInstance, pLun->iLun)) 1218 break; 1219 1220 if (cAsync == cAsyncStart) 1221 pdmR3ResetUsb(pUsbIns, &cAsync); 1222 } 1223 #endif 1224 if (!cAsync) 1225 break; 1226 1227 /* 1228 * Process requests. 1229 */ 1230 /** @todo This is utterly nuts and completely unsafe... will get back to it in a 1231 * bit I hope... */ 1232 int rc = VMR3AsyncPdmNotificationWaitU(&pVM->pUVM->aCpus[0]); 1233 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc)); 1234 rc = VMR3ReqProcessU(pVM->pUVM, VMCPUID_ANY); 1235 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc)); 1236 rc = VMR3ReqProcessU(pVM->pUVM, 0/*idDstCpu*/); 1237 AssertReleaseMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc)); 1238 } 1052 1239 1053 1240 /* … … 1063 1250 } 1064 1251 VM_FF_CLEAR(pVM, VM_FF_PDM_DMA); 1065 1066 /*1067 * Iterate the device instances.1068 * The attached drivers are processed first.1069 */1070 for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3)1071 {1072 for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext)1073 /** @todo Inverse the order here? */1074 for (PPDMDRVINS pDrvIns = pLun->pTop; pDrvIns; pDrvIns = pDrvIns->Internal.s.pDown)1075 if (pDrvIns->pDrvReg->pfnReset)1076 {1077 LogFlow(("PDMR3Reset: Notifying - driver '%s'/%d on LUN#%d of device '%s'/%d\n",1078 pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, pLun->iLun, pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));1079 pDrvIns->pDrvReg->pfnReset(pDrvIns);1080 }1081 1082 if (pDevIns->pDevReg->pfnReset)1083 {1084 LogFlow(("PDMR3Reset: Notifying - device '%s'/%d\n",1085 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));1086 pDevIns->pDevReg->pfnReset(pDevIns);1087 }1088 }1089 1090 #ifdef VBOX_WITH_USB1091 for (PPDMUSBINS pUsbIns = pVM->pdm.s.pUsbInstances; pUsbIns; pUsbIns = pUsbIns->Internal.s.pNext)1092 {1093 for (PPDMLUN pLun = pUsbIns->Internal.s.pLuns; pLun; pLun = pLun->pNext)1094 for (PPDMDRVINS pDrvIns = pLun->pTop; pDrvIns; pDrvIns = pDrvIns->Internal.s.pDown)1095 if (pDrvIns->pDrvReg->pfnReset)1096 {1097 LogFlow(("PDMR3Reset: Notifying - driver '%s'/%d on LUN#%d of usb device '%s'/%d\n",1098 pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, pLun->iLun, pUsbIns->pUsbReg->szDeviceName, pUsbIns->iInstance));1099 pDrvIns->pDrvReg->pfnReset(pDrvIns);1100 }1101 1102 if (pUsbIns->pUsbReg->pfnVMReset)1103 {1104 LogFlow(("PDMR3Reset: Notifying - device '%s'/%d\n",1105 pUsbIns->pUsbReg->szDeviceName, pUsbIns->iInstance));1106 pUsbIns->pUsbReg->pfnVMReset(pUsbIns);1107 }1108 }1109 #endif1110 1252 1111 1253 LogFlow(("PDMR3Reset: returns void\n")); -
trunk/src/VBox/VMM/PDMDevHlp.cpp
r24740 r24744 2340 2340 AssertStmt(pfnAsyncNotify, rc = VERR_INVALID_PARAMETER); 2341 2341 AssertStmt(!pDevIns->Internal.s.pfnAsyncNotify, rc = VERR_WRONG_ORDER); 2342 AssertStmt(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_SUSPENDED, rc = VERR_WRONG_ORDER);2342 AssertStmt(pDevIns->Internal.s.fIntFlags & (PDMDEVINSINT_FLAGS_SUSPENDED | PDMDEVINSINT_FLAGS_RESET), rc = VERR_WRONG_ORDER); 2343 2343 VMSTATE enmVMState = VMR3GetState(pDevIns->Internal.s.pVMR3); 2344 2344 AssertStmt( enmVMState == VMSTATE_SUSPENDING 2345 2345 || enmVMState == VMSTATE_SUSPENDING_EXT_LS 2346 2346 || enmVMState == VMSTATE_SUSPENDING_LS 2347 || enmVMState == VMSTATE_RESETTING 2348 || enmVMState == VMSTATE_RESETTING_LS 2347 2349 || enmVMState == VMSTATE_POWERING_OFF 2348 2350 || enmVMState == VMSTATE_POWERING_OFF_LS, … … 2367 2369 || enmVMState == VMSTATE_SUSPENDING_EXT_LS 2368 2370 || enmVMState == VMSTATE_SUSPENDING_LS 2371 || enmVMState == VMSTATE_RESETTING 2372 || enmVMState == VMSTATE_RESETTING_LS 2369 2373 || enmVMState == VMSTATE_POWERING_OFF 2370 2374 || enmVMState == VMSTATE_POWERING_OFF_LS) -
trunk/src/VBox/VMM/PDMDriver.cpp
r24740 r24744 1029 1029 AssertStmt(pfnAsyncNotify, rc = VERR_INVALID_PARAMETER); 1030 1030 AssertStmt(!pDrvIns->Internal.s.pfnAsyncNotify, rc = VERR_WRONG_ORDER); 1031 AssertStmt(pDrvIns->Internal.s.fVMSuspended , rc = VERR_WRONG_ORDER);1031 AssertStmt(pDrvIns->Internal.s.fVMSuspended || pDrvIns->Internal.s.fVMReset, rc = VERR_WRONG_ORDER); 1032 1032 VMSTATE enmVMState = VMR3GetState(pDrvIns->Internal.s.pVM); 1033 1033 AssertStmt( enmVMState == VMSTATE_SUSPENDING 1034 1034 || enmVMState == VMSTATE_SUSPENDING_EXT_LS 1035 1035 || enmVMState == VMSTATE_SUSPENDING_LS 1036 || enmVMState == VMSTATE_RESETTING 1037 || enmVMState == VMSTATE_RESETTING_LS 1036 1038 || enmVMState == VMSTATE_POWERING_OFF 1037 1039 || enmVMState == VMSTATE_POWERING_OFF_LS, … … 1056 1058 || enmVMState == VMSTATE_SUSPENDING_EXT_LS 1057 1059 || enmVMState == VMSTATE_SUSPENDING_LS 1060 || enmVMState == VMSTATE_RESETTING 1061 || enmVMState == VMSTATE_RESETTING_LS 1058 1062 || enmVMState == VMSTATE_POWERING_OFF 1059 1063 || enmVMState == VMSTATE_POWERING_OFF_LS) -
trunk/src/VBox/VMM/PDMInternal.h
r24730 r24744 142 142 * a failure (already resumed/powered-on devices are suspended). */ 143 143 #define PDMDEVINSINT_FLAGS_SUSPENDED RT_BIT_32(1) 144 /** Indicates that the device has been reset already. Used by PDMR3Reset. */ 145 #define PDMDEVINSINT_FLAGS_RESET RT_BIT_32(2) 144 146 /** @} */ 145 147 … … 178 180 /** The port number that we're connected to. */ 179 181 uint32_t iPort; 180 /** Indicates that the driverhasn't been powered on or resumed.182 /** Indicates that the USB device hasn't been powered on or resumed. 181 183 * See PDMDEVINSINT_FLAGS_SUSPENDED. */ 182 184 bool fVMSuspended; 185 /** Indicates that the USB device has been reset. */ 186 bool fVMReset; 183 187 /** Pointer to the asynchronous notification callback set while in 184 188 * FNPDMDEVSUSPEND or FNPDMDEVPOWEROFF. */ … … 210 214 * See PDMDEVINSINT_FLAGS_SUSPENDED. */ 211 215 bool fVMSuspended; 216 /** Indicates that the driver has been reset already. */ 217 bool fVMReset; 212 218 /** Pointer to the asynchronous notification callback set while in 213 219 * PDMUSBREG::pfnVMSuspend or PDMUSBREG::pfnVMPowerOff. */
Note:
See TracChangeset
for help on using the changeset viewer.