VirtualBox

Changeset 24744 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Nov 17, 2009 10:33:38 PM (15 years ago)
Author:
vboxsync
Message:

PDM: Async reset notification handling as well.

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PDM.cpp

    r24740 r24744  
    10391039
    10401040
    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 */
     1050DECLINLINE(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 */
     1091DECLINLINE(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 */
     1126DECLINLINE(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.
    10461158 *
    10471159 * @param   pVM     VM Handle.
     
    10501162{
    10511163    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    }
    10521239
    10531240    /*
     
    10631250    }
    10641251    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_USB
    1091     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 #endif
    11101252
    11111253    LogFlow(("PDMR3Reset: returns void\n"));
  • trunk/src/VBox/VMM/PDMDevHlp.cpp

    r24740 r24744  
    23402340    AssertStmt(pfnAsyncNotify, rc = VERR_INVALID_PARAMETER);
    23412341    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);
    23432343    VMSTATE enmVMState = VMR3GetState(pDevIns->Internal.s.pVMR3);
    23442344    AssertStmt(   enmVMState == VMSTATE_SUSPENDING
    23452345               || enmVMState == VMSTATE_SUSPENDING_EXT_LS
    23462346               || enmVMState == VMSTATE_SUSPENDING_LS
     2347               || enmVMState == VMSTATE_RESETTING
     2348               || enmVMState == VMSTATE_RESETTING_LS
    23472349               || enmVMState == VMSTATE_POWERING_OFF
    23482350               || enmVMState == VMSTATE_POWERING_OFF_LS,
     
    23672369        || enmVMState == VMSTATE_SUSPENDING_EXT_LS
    23682370        || enmVMState == VMSTATE_SUSPENDING_LS
     2371        || enmVMState == VMSTATE_RESETTING
     2372        || enmVMState == VMSTATE_RESETTING_LS
    23692373        || enmVMState == VMSTATE_POWERING_OFF
    23702374        || enmVMState == VMSTATE_POWERING_OFF_LS)
  • trunk/src/VBox/VMM/PDMDriver.cpp

    r24740 r24744  
    10291029    AssertStmt(pfnAsyncNotify, rc = VERR_INVALID_PARAMETER);
    10301030    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);
    10321032    VMSTATE enmVMState = VMR3GetState(pDrvIns->Internal.s.pVM);
    10331033    AssertStmt(   enmVMState == VMSTATE_SUSPENDING
    10341034               || enmVMState == VMSTATE_SUSPENDING_EXT_LS
    10351035               || enmVMState == VMSTATE_SUSPENDING_LS
     1036               || enmVMState == VMSTATE_RESETTING
     1037               || enmVMState == VMSTATE_RESETTING_LS
    10361038               || enmVMState == VMSTATE_POWERING_OFF
    10371039               || enmVMState == VMSTATE_POWERING_OFF_LS,
     
    10561058        || enmVMState == VMSTATE_SUSPENDING_EXT_LS
    10571059        || enmVMState == VMSTATE_SUSPENDING_LS
     1060        || enmVMState == VMSTATE_RESETTING
     1061        || enmVMState == VMSTATE_RESETTING_LS
    10581062        || enmVMState == VMSTATE_POWERING_OFF
    10591063        || enmVMState == VMSTATE_POWERING_OFF_LS)
  • trunk/src/VBox/VMM/PDMInternal.h

    r24730 r24744  
    142142 * a failure (already resumed/powered-on devices are suspended). */
    143143#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)
    144146/** @} */
    145147
     
    178180    /** The port number that we're connected to. */
    179181    uint32_t                        iPort;
    180     /** Indicates that the driver hasn't been powered on or resumed.
     182    /** Indicates that the USB device hasn't been powered on or resumed.
    181183     * See PDMDEVINSINT_FLAGS_SUSPENDED. */
    182184    bool                            fVMSuspended;
     185    /** Indicates that the USB device has been reset. */
     186    bool                            fVMReset;
    183187    /** Pointer to the asynchronous notification callback set while in
    184188     * FNPDMDEVSUSPEND or FNPDMDEVPOWEROFF. */
     
    210214     * See PDMDEVINSINT_FLAGS_SUSPENDED. */
    211215    bool                            fVMSuspended;
     216    /** Indicates that the driver has been reset already. */
     217    bool                            fVMReset;
    212218    /** Pointer to the asynchronous notification callback set while in
    213219     * PDMUSBREG::pfnVMSuspend or PDMUSBREG::pfnVMPowerOff. */
Note: See TracChangeset for help on using the changeset viewer.

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