Index: /trunk/include/VBox/pdmdev.h
===================================================================
--- /trunk/include/VBox/pdmdev.h	(revision 16020)
+++ /trunk/include/VBox/pdmdev.h	(revision 16021)
@@ -345,4 +345,10 @@
 /** Indicates that the devices support PAE36 on a 32-bit guest. */
 #define PDM_DEVREG_FLAGS_PAE36                  0x00001000
+
+/** Indicates that the device needs to be notified before the drivers when suspending. */
+#define PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION 0x00002000
+
+/** Indicates that the device needs to be notified before the drivers when powering off. */
+#define PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION 0x00004000
 /** @} */
 
Index: /trunk/src/VBox/VMM/PDM.cpp
===================================================================
--- /trunk/src/VBox/VMM/PDM.cpp	(revision 16020)
+++ /trunk/src/VBox/VMM/PDM.cpp	(revision 16021)
@@ -976,4 +976,17 @@
     for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3)
     {
+        /*
+         * Some devices need to be notified first that the VM is suspended to ensure that that there are no pending
+         * requests from the guest which are still processed. Calling the drivers before these requests are finished
+         * might lead to errors otherwise. One example is the SATA controller which might still have I/O requests
+         * pending. But DrvVD sets the files into readonly mode and every request will fail then.
+         */
+        if (pDevIns->pDevReg->pfnSuspend && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION))
+        {
+            LogFlow(("PDMR3Suspend: Notifying - device '%s'/%d\n",
+                     pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
+            pDevIns->pDevReg->pfnSuspend(pDevIns);
+        }
+
         for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext)
             for (PPDMDRVINS pDrvIns = pLun->pTop; pDrvIns; pDrvIns = pDrvIns->Internal.s.pDown)
@@ -985,5 +998,6 @@
                 }
 
-        if (pDevIns->pDevReg->pfnSuspend)
+        /* Don't call the suspend notification again if it was already called. */
+        if (pDevIns->pDevReg->pfnSuspend && !(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION))
         {
             LogFlow(("PDMR3Suspend: Notifying - device '%s'/%d\n",
@@ -1102,4 +1116,12 @@
     for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3)
     {
+
+        if (pDevIns->pDevReg->pfnPowerOff && (pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION))
+        {
+            LogFlow(("PDMR3PowerOff: Notifying - device '%s'/%d\n",
+                     pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
+            pDevIns->pDevReg->pfnPowerOff(pDevIns);
+        }
+
         for (PPDMLUN pLun = pDevIns->Internal.s.pLunsR3; pLun; pLun = pLun->pNext)
             for (PPDMDRVINS pDrvIns = pLun->pTop; pDrvIns; pDrvIns = pDrvIns->Internal.s.pDown)
@@ -1111,5 +1133,5 @@
                 }
 
-        if (pDevIns->pDevReg->pfnPowerOff)
+        if (pDevIns->pDevReg->pfnPowerOff && !(pDevIns->pDevReg->fFlags & PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION))
         {
             LogFlow(("PDMR3PowerOff: Notifying - device '%s'/%d\n",
