- Timestamp:
- Aug 1, 2023 8:01:46 PM (19 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
r99739 r100774 419 419 static int vusbHubDetach(PVUSBROOTHUB pThis, PVUSBDEV pDev) 420 420 { 421 Assert(pDev->i16Port != -1); 421 /* 422 * It is possible to race the re-attach timer callback in some extreme cases, 423 * typically involving custom VBox builds that does very little guest code 424 * execution before terminating the VM again (e.g. IEM debugging). 425 */ 426 Assert(pDev->i16Port != -1 || pThis->pLoad); 427 if (pDev->i16Port == -1 && pThis->pLoad) 428 return VINF_SUCCESS; 422 429 423 430 /* … … 1305 1312 1306 1313 /** 1314 * Helper that frees up pThis->pLoad. 1315 * 1316 * This is called in a few places. 1317 */ 1318 static void vushR3RhFreeLoadData(PVUSBROOTHUB pThis, PPDMDRVINS pDrvIns) 1319 { 1320 PVUSBROOTHUBLOAD const pLoad = pThis->pLoad; 1321 if (pLoad) 1322 { 1323 pThis->pLoad = NULL; 1324 PDMDrvHlpTimerDestroy(pDrvIns, pLoad->hTimer); 1325 pLoad->hTimer = NIL_TMTIMERHANDLE; 1326 RTMemFree(pLoad); 1327 } 1328 } 1329 1330 1331 /** 1307 1332 * @callback_method_impl{FNSSMDRVSAVEPREP, All URBs needs to be canceled.} 1308 1333 */ … … 1312 1337 LogFlow(("vusbR3RhSavePrep:\n")); 1313 1338 RT_NOREF(pSSM); 1339 1340 /* 1341 * If there is old load state hanging around, we'll have to execute it first 1342 * to get the hub into the right state prior to saving. This isn't entirely 1343 * right wrt snapshotting and continuing execution, but OTOH it will screw up 1344 * if shutting down afterwards. 1345 */ 1346 PVUSBROOTHUBLOAD const pLoad = pThis->pLoad; 1347 if (pLoad) 1348 { 1349 for (unsigned i = 0; i < pLoad->cDevs; i++) 1350 vusbHubAttach(pThis, pLoad->apDevs[i]); 1351 vushR3RhFreeLoadData(pThis, pDrvIns); 1352 } 1314 1353 1315 1354 /* … … 1341 1380 RTCritSectLeave(&pThis->CritSectDevices); 1342 1381 1343 /*1344 * Kill old load data which might be hanging around.1345 */1346 if (pThis->pLoad)1347 {1348 PDMDrvHlpTimerDestroy(pDrvIns, pThis->pLoad->hTimer);1349 pThis->pLoad->hTimer = NIL_TMTIMERHANDLE;1350 PDMDrvHlpMMHeapFree(pDrvIns, pThis->pLoad);1351 pThis->pLoad = NULL;1352 }1353 1354 1382 return VINF_SUCCESS; 1355 1383 } … … 1406 1434 if (!pThis->pLoad) 1407 1435 { 1436 /** @todo allocate first, it may fail later and we'll potentially leave things 1437 * dangling. */ 1408 1438 VUSBROOTHUBLOAD Load; 1409 1439 unsigned i; … … 1432 1462 if (Load.cDevs) 1433 1463 { 1434 pThis->pLoad = (PVUSBROOTHUBLOAD)RTMem AllocZ(sizeof(Load));1464 pThis->pLoad = (PVUSBROOTHUBLOAD)RTMemDup(&Load, sizeof(Load)); 1435 1465 if (!pThis->pLoad) 1436 1466 return VERR_NO_MEMORY; 1437 *pThis->pLoad = Load;1438 1467 } 1439 1468 } … … 1445 1474 1446 1475 /** 1447 * Reattaches devices after a saved state load. 1476 * Timer callback that reattaches devices after a saved state load. 1477 * 1448 1478 */ 1449 1479 static DECLCALLBACK(void) vusbR3RhLoadReattachDevices(PPDMDRVINS pDrvIns, TMTIMERHANDLE hTimer, void *pvUser) … … 1451 1481 PVUSBROOTHUB pThis = PDMINS_2_DATA(pDrvIns, PVUSBROOTHUB); 1452 1482 PVUSBROOTHUBLOAD pLoad = pThis->pLoad; 1483 AssertPtrReturnVoid(pLoad); 1453 1484 LogFlow(("vusbR3RhLoadReattachDevices:\n")); 1454 1485 Assert(hTimer == pLoad->hTimer); RT_NOREF(pvUser); … … 1463 1494 * Cleanup. 1464 1495 */ 1465 PDMDrvHlpTimerDestroy(pDrvIns, hTimer); 1466 pLoad->hTimer = NIL_TMTIMERHANDLE; 1467 RTMemFree(pLoad); 1468 pThis->pLoad = NULL; 1496 vushR3RhFreeLoadData(pThis, pDrvIns); 1469 1497 } 1470 1498 … … 1482 1510 * Start a timer if we've got devices to reattach 1483 1511 */ 1484 if (pThis->pLoad) 1512 PVUSBROOTHUBLOAD const pLoad = pThis->pLoad; 1513 if (pLoad) 1485 1514 { 1486 1515 int rc = PDMDrvHlpTMTimerCreate(pDrvIns, TMCLOCK_VIRTUAL, vusbR3RhLoadReattachDevices, NULL, 1487 1516 TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0, 1488 "VUSB reattach on load", &pThis->pLoad->hTimer); 1517 "VUSB reattach on load", &pLoad->hTimer); 1518 AssertLogRelRC(rc); 1489 1519 if (RT_SUCCESS(rc)) 1490 rc = PDMDrvHlpTimerSetMillies(pDrvIns, pThis->pLoad->hTimer, 250); 1520 rc = PDMDrvHlpTimerSetMillies(pDrvIns, pLoad->hTimer, 250); 1521 else 1522 vushR3RhFreeLoadData(pThis, pDrvIns); /** @todo or call vusbR3RhLoadReattachDevices directly then fail? */ 1491 1523 return rc; 1492 1524 }
Note:
See TracChangeset
for help on using the changeset viewer.