VirtualBox

Changeset 108094 in vbox for trunk


Ignore:
Timestamp:
Feb 6, 2025 9:58:06 AM (3 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167392
Message:

USB/RootHub: bugref:10779 Re-attach VUSB devices on resume, prevent double detaching on poweroff after save.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/USB/DrvVUSBRootHub.cpp

    r106061 r108094  
    508508     */
    509509    vusbDevSetStateCmp(pDev, VUSB_DEVICE_STATE_DEFAULT, VUSB_DEVICE_STATE_RESET);
    510     vusbHubDetach(pThis, pDev);
     510    /*
     511     * USB Devices that do not support state saving get detached during save prep step.
     512     * We do not want to re-attach these back if VM gets shut down, which means that
     513     * they will be in detached state when PDMR3Term gets called, and it will try to
     514     * detach these again. Prevent detaching the same device twice!
     515     * See @bugref for details.
     516     */
     517    if (vusbDevGetState(pDev) != VUSB_DEVICE_STATE_DETACHED)
     518        vusbHubDetach(pThis, pDev);
    511519    vusbDevRelease(pDev, "vusbPDMHubDetachDevice");
    512520    return VINF_SUCCESS;
     
    14081416                /*
    14091417                 * Save the device pointers here so we can reattach them afterwards.
    1410                  * This will work fine even if the save fails since the Done handler is
    1411                  * called unconditionally if the Prep handler was called.
     1418                 * Note that the actual reattaching happens in the Resume handler, not
     1419                 * in the Done handler, because memory writes are still disallowed when
     1420                 * the Done handler is called.
    14121421                 */
    14131422                Assert(!pThis->apDevByPort[i]);
     
    14181427    }
    14191428
    1420     return VINF_SUCCESS;
    1421 }
    1422 
    1423 
    1424 /**
    1425  * @callback_method_impl{FNSSMDRVSAVEDONE}
    1426  */
    1427 static DECLCALLBACK(int) vusbR3RhSaveDone(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM)
    1428 {
    1429     PVUSBROOTHUB pThis = PDMINS_2_DATA(pDrvIns, PVUSBROOTHUB);
    1430     PVUSBDEV     aPortsOld[VUSB_DEVICES_MAX];
    1431     unsigned     i;
    1432     LogFlow(("vusbR3RhSaveDone:\n"));
    1433     RT_NOREF(pSSM);
    1434 
    1435     /* Save the current data. */
    1436     memcpy(aPortsOld, pThis->apDevByPort, sizeof(aPortsOld));
    1437     AssertCompile(sizeof(aPortsOld) == sizeof(pThis->apDevByPort));
    1438 
    1439     /*
    1440      * NULL the dev pointers.
    1441      */
    1442     for (i = 0; i < RT_ELEMENTS(pThis->apDevByPort); i++)
    1443         if (pThis->apDevByPort[i] && !VUSBIDevIsSavedStateSupported(&pThis->apDevByPort[i]->IDevice))
    1444             pThis->apDevByPort[i] = NULL;
    1445 
    1446     /*
    1447      * Attach the devices.
    1448      */
    1449     for (i = 0; i < RT_ELEMENTS(pThis->apDevByPort); i++)
    1450     {
    1451         PVUSBDEV pDev = aPortsOld[i];
    1452         if (pDev && !VUSBIDevIsSavedStateSupported(&pDev->IDevice))
    1453             vusbHubAttach(pThis, pDev);
    1454     }
    1455 
    1456     ASMAtomicXchgBool(&pThis->fSavingState, false);
    14571429    return VINF_SUCCESS;
    14581430}
     
    15941566
    15951567/* -=-=-=-=-=- PDM Driver methods -=-=-=-=-=- */
     1568
     1569
     1570/**
     1571 * @interface_method_impl{PDMDRVREG,pfnResume}
     1572 */
     1573static DECLCALLBACK(void) vusbRhResume(PPDMDRVINS pDrvIns)
     1574{
     1575    VMRESUMEREASON enmReason = PDMDrvHlpVMGetResumeReason(pDrvIns);
     1576
     1577    LogFlowFunc(("enmReason=%u\n", enmReason));
     1578    if (enmReason == VMRESUMEREASON_STATE_SAVED)
     1579    {
     1580        PVUSBROOTHUB pThis = PDMINS_2_DATA(pDrvIns, PVUSBROOTHUB);
     1581        PVUSBDEV     aPortsOld[VUSB_DEVICES_MAX];
     1582        unsigned     i;
     1583        /* Save the current data. */
     1584        memcpy(aPortsOld, pThis->apDevByPort, sizeof(aPortsOld));
     1585        AssertCompile(sizeof(aPortsOld) == sizeof(pThis->apDevByPort));
     1586        Assert(ASMAtomicReadBool(&pThis->fSavingState));
     1587
     1588        /*
     1589        * NULL the dev pointers.
     1590        */
     1591        for (i = 0; i < RT_ELEMENTS(pThis->apDevByPort); i++)
     1592            if (pThis->apDevByPort[i] && !VUSBIDevIsSavedStateSupported(&pThis->apDevByPort[i]->IDevice))
     1593                pThis->apDevByPort[i] = NULL;
     1594
     1595        /*
     1596        * Attach the devices.
     1597        */
     1598        for (i = 0; i < RT_ELEMENTS(pThis->apDevByPort); i++)
     1599        {
     1600            PVUSBDEV pDev = aPortsOld[i];
     1601            if (pDev && !VUSBIDevIsSavedStateSupported(&pDev->IDevice))
     1602                vusbHubAttach(pThis, pDev);
     1603        }
     1604        ASMAtomicXchgBool(&pThis->fSavingState, false);
     1605    }
     1606}
    15961607
    15971608
     
    17571768    rc = PDMDrvHlpSSMRegisterEx(pDrvIns, VUSB_ROOTHUB_SAVED_STATE_VERSION, 0,
    17581769                                NULL, NULL, NULL,
    1759                                 vusbR3RhSavePrep, NULL, vusbR3RhSaveDone,
     1770                                vusbR3RhSavePrep, NULL, NULL /* see vusbRhResume */,
    17601771                                vusbR3RhLoadPrep, NULL, vusbR3RhLoadDone);
    17611772    AssertRCReturn(rc, rc);
     
    19361947    NULL,
    19371948    /* pfnResume */
    1938     NULL,
     1949    vusbRhResume,
    19391950    /* pfnAttach */
    19401951    NULL,
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette