Index: /trunk/src/VBox/Devices/Storage/DevBusLogic.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevBusLogic.cpp	(revision 29613)
+++ /trunk/src/VBox/Devices/Storage/DevBusLogic.cpp	(revision 29614)
@@ -381,4 +381,13 @@
     /** Partner of ILeds. */
     R3PTRTYPE(PPDMILEDCONNECTORS)  pLedsConnector;
+
+#if HC_ARCH_BITS == 64
+    uint32_t                       Alignment3;
+#endif
+
+    /** Indicates that PDMDevHlpAsyncNotificationCompleted should be called when
+     * a port is entering the idle state. */
+    bool volatile                  fSignalIdle;
+
 } BUSLOGIC, *PBUSLOGIC;
 
@@ -1987,4 +1996,8 @@
     /* Add task to the cache. */
     RTMemCacheFree(pBusLogic->hTaskCache, pTaskState);
+
+    if (pBusLogicDevice->cOutstandingRequests == 0 && pBusLogic->fSignalIdle)
+        PDMDevHlpAsyncNotificationCompleted(pBusLogic->pDevInsR3);
+
     return VINF_SUCCESS;
 }
@@ -2386,4 +2399,72 @@
 }
 
+/* -=-=-=-=- Helper -=-=-=-=- */
+
+ /**
+ * Checks if all asynchronous I/O is finished.
+ *
+ * Used by lsilogicReset, lsilogicSuspend and lsilogicPowerOff.
+ *
+ * @returns true if quiesced, false if busy.
+ * @param   pDevIns         The device instance.
+ */
+static bool buslogicR3AllAsyncIOIsFinished(PPDMDEVINS pDevIns)
+{
+    PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
+
+    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aDeviceStates); i++)
+    {
+        PBUSLOGICDEVICE pThisDevice = &pThis->aDeviceStates[i];
+        if (pThisDevice->pDrvBase)
+        {
+            if (pThisDevice->cOutstandingRequests != 0)
+                return false;
+        }
+    }
+
+    return true;
+}
+
+/**
+ * Callback employed by lsilogicR3Suspend and lsilogicR3PowerOff..
+ *
+ * @returns true if we've quiesced, false if we're still working.
+ * @param   pDevIns     The device instance.
+ */
+static DECLCALLBACK(bool) buslogicR3IsAsyncSuspendOrPowerOffDone(PPDMDEVINS pDevIns)
+{
+    if (!buslogicR3AllAsyncIOIsFinished(pDevIns))
+        return false;
+
+    PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
+    ASMAtomicWriteBool(&pThis->fSignalIdle, false);
+    return true;
+}
+
+/**
+ * Common worker for ahciR3Suspend and ahciR3PowerOff.
+ */
+static void buslogicR3SuspendOrPowerOff(PPDMDEVINS pDevIns)
+{
+    PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
+
+    ASMAtomicWriteBool(&pThis->fSignalIdle, true);
+    if (!buslogicR3AllAsyncIOIsFinished(pDevIns))
+        PDMDevHlpSetAsyncNotification(pDevIns, buslogicR3IsAsyncSuspendOrPowerOffDone);
+    else
+        ASMAtomicWriteBool(&pThis->fSignalIdle, false);
+}
+
+/**
+ * Suspend notification.
+ *
+ * @param   pDevIns     The device instance data.
+ */
+static DECLCALLBACK(void) buslogicSuspend(PPDMDEVINS pDevIns)
+{
+    Log(("buslogicSuspend\n"));
+    buslogicR3SuspendOrPowerOff(pDevIns);
+}
+
 /**
  * Detach notification.
@@ -2462,4 +2543,39 @@
 }
 
+/**
+ * Callback employed by buslogicR3Reset.
+ *
+ * @returns true if we've quiesced, false if we're still working.
+ * @param   pDevIns     The device instance.
+ */
+static DECLCALLBACK(bool) buslogicR3IsAsyncResetDone(PPDMDEVINS pDevIns)
+{
+    PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
+
+    if (!buslogicR3AllAsyncIOIsFinished(pDevIns))
+        return false;
+    ASMAtomicWriteBool(&pThis->fSignalIdle, false);
+
+    buslogicHwReset(pThis);
+    return true;
+}
+
+/**
+ * @copydoc FNPDMDEVRESET
+ */
+static DECLCALLBACK(void) buslogicReset(PPDMDEVINS pDevIns)
+{
+    PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
+
+    ASMAtomicWriteBool(&pThis->fSignalIdle, true);
+    if (!buslogicR3AllAsyncIOIsFinished(pDevIns))
+        PDMDevHlpSetAsyncNotification(pDevIns, buslogicR3IsAsyncResetDone);
+    else
+    {
+        ASMAtomicWriteBool(&pThis->fSignalIdle, false);
+        buslogicHwReset(pThis);
+    }
+}
+
 static DECLCALLBACK(void) buslogicRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
 {
@@ -2480,14 +2596,12 @@
 
 /**
- * Reset notification.
- *
- * @returns VBox status.
- * @param   pDevIns     The device instance data.
- */
-static DECLCALLBACK(void)  buslogicReset(PPDMDEVINS pDevIns)
-{
-    PBUSLOGIC pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
-
-    buslogicHwReset(pThis);
+ * Poweroff notification.
+ *
+ * @param   pDevIns Pointer to the device instance
+ */
+static DECLCALLBACK(void) buslogicPowerOff(PPDMDEVINS pDevIns)
+{
+    Log(("buslogicPowerOff\n"));
+    buslogicR3SuspendOrPowerOff(pDevIns);
 }
 
@@ -2682,5 +2796,6 @@
     "BusLogic BT-958 SCSI host adapter.\n",
     /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
+    PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION,
     /* fClass */
     PDM_DEVREG_CLASS_STORAGE,
@@ -2702,5 +2817,5 @@
     buslogicReset,
     /* pfnSuspend */
-    NULL,
+    buslogicSuspend,
     /* pfnResume */
     NULL,
@@ -2714,5 +2829,5 @@
     NULL,
     /* pfnPowerOff */
-    NULL,
+    buslogicPowerOff,
     /* pfnSoftReset */
     NULL,
Index: /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
===================================================================
--- /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 29613)
+++ /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 29614)
@@ -1459,4 +1459,5 @@
     GEN_CHECK_OFF(BUSLOGIC, ILeds);
     GEN_CHECK_OFF(BUSLOGIC, pLedsConnector);
+    GEN_CHECK_OFF(BUSLOGIC, fSignalIdle);
 #endif /* VBOX_WITH_BUSLOGIC */
 
