Index: /trunk/src/VBox/Devices/Audio/DevIchHda.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchHda.cpp	(revision 59321)
+++ /trunk/src/VBox/Devices/Audio/DevIchHda.cpp	(revision 59322)
@@ -572,7 +572,4 @@
 typedef struct HDASTREAMSTATE
 {
-    /** Number of BDLEs (Buffer Descriptor List Entry).
-     *  Should be SDnLVI + 1 usually. */
-    uint16_t            cBDLE;
     /** Current BDLE to use. Wraps around to 0 if
      *  maximum (cBDLE) is reached. */
@@ -590,6 +587,6 @@
     /** Event signalling that the stream's state has been changed. */
     RTSEMEVENT          hStateChangedEvent;
-    /** Array of BDLEs. */
-    R3PTRTYPE(PHDABDLE) paBDLE;
+    /** Current BDLE (Buffer Descriptor List Entry). */
+    HDABDLE             BDLE;
 } HDASTREAMSTATE, *PHDASTREAMSTATE;
 
@@ -806,13 +803,14 @@
  * {IOB}SDn read/write functions.
  */
-static int hdaRegWriteSDCBL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
-static int hdaRegWriteSDCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
-static int hdaRegWriteSDSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
-static int hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
-static int hdaRegWriteSDFIFOW(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
-static int hdaRegWriteSDFIFOS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
-static int hdaRegWriteSDFMT(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
-static int hdaRegWriteSDBDPL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
-static int hdaRegWriteSDBDPU(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
+static int  hdaRegWriteSDCBL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
+static int  hdaRegWriteSDCTL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
+static int  hdaRegWriteSDSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
+static int  hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
+static int  hdaRegWriteSDFIFOW(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
+static int  hdaRegWriteSDFIFOS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
+static int  hdaRegWriteSDFMT(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
+static int  hdaRegWriteSDBDPL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
+static int  hdaRegWriteSDBDPU(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
+inline bool hdaRegWriteSDIsAllowed(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value);
 
 /*
@@ -829,5 +827,4 @@
 
 #ifdef IN_RING3
-static int hdaStreamInit(PHDASTATE pThis, PHDASTREAM pStrmSt, uint8_t u8Strm);
 static void hdaStreamDestroy(PHDASTREAM pStrmSt);
 static int hdaStreamStart(PHDASTREAM pStrmSt);
@@ -841,7 +838,6 @@
 static void hdaStreamUpdateLPIB(PHDASTATE pThis, PHDASTREAM pStrmSt, uint32_t u32LPIB);
 # ifdef LOG_ENABLED
-static void hdaBDLEDumpAll(PHDASTATE pThis, uint64_t u64BaseDMA, uint16_t u16LVI);
+static void hdaBDLEDumpAll(PHDASTATE pThis, uint64_t u64BaseDMA, uint16_t cBDLE);
 # endif
-static void hdaBDLEReset(PHDABDLE pBDLE);
 #endif
 
@@ -988,6 +984,15 @@
 
 #ifdef IN_RING3
-/** HDABDLESTATE field descriptors for the v5+ saved state. */
-static SSMFIELD const g_aSSMBDLEStateFields5[] =
+/** HDABDLE field descriptors for the v6+ saved state. */
+static SSMFIELD const g_aSSMBDLEFields6[] =
+{
+    SSMFIELD_ENTRY(HDABDLE, u64BufAdr),
+    SSMFIELD_ENTRY(HDABDLE, u32BufSize),
+    SSMFIELD_ENTRY(HDABDLE, fIntOnCompletion),
+    SSMFIELD_ENTRY_TERM()
+};
+
+/** HDABDLESTATE field descriptors for the v6+ saved state. */
+static SSMFIELD const g_aSSMBDLEStateFields6[] =
 {
     SSMFIELD_ENTRY(HDABDLESTATE, u32BDLIndex),
@@ -998,10 +1003,12 @@
 };
 
-/** HDASTREAMSTATE field descriptors for the v5+ saved state. */
-static SSMFIELD const g_aSSMStreamStateFields5[] =
-{
-    SSMFIELD_ENTRY       (HDASTREAMSTATE, cBDLE),
-    SSMFIELD_ENTRY       (HDASTREAMSTATE, uCurBDLE),
-    SSMFIELD_ENTRY_IGNORE(HDASTREAMSTATE, paBDLE),
+/** HDASTREAMSTATE field descriptors for the v6+ saved state. */
+static SSMFIELD const g_aSSMStreamStateFields6[] =
+{
+    SSMFIELD_ENTRY_OLD(cBDLE, 2),
+    SSMFIELD_ENTRY(HDASTREAMSTATE, uCurBDLE),
+    SSMFIELD_ENTRY(HDASTREAMSTATE, fDoStop),
+    SSMFIELD_ENTRY(HDASTREAMSTATE, fActive),
+    SSMFIELD_ENTRY(HDASTREAMSTATE, fInReset),
     SSMFIELD_ENTRY_TERM()
 };
@@ -1034,7 +1041,10 @@
     {
         int rc2 = PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns),
-                                        (pThis->u64DPBase & DPBASE_ADDR_MASK) + (pStrmSt->u8Strm * 8),
+                                        (pThis->u64DPBase & DPBASE_ADDR_MASK) + (pStrmSt->u8Strm * 2 * sizeof(uint32_t)),
                                         (void *)&u32LPIB, sizeof(uint32_t));
         AssertRC(rc2);
+#ifdef DEBUG
+        hdaBDLEDumpAll(pThis, pStrmSt->u64BaseDMA, pStrmSt->State.uCurBDLE);
+#endif
     }
 }
@@ -1096,34 +1106,16 @@
 #ifdef IN_RING3
 /**
- * Returns the current BDLE to use for a stream.
+ * Fetches the next BDLE to use for a stream.
  *
- * @return BDLE to use, NULL if none found.
- */
-DECLINLINE(PHDABDLE) hdaStreamGetCurrentBDLE(PHDASTATE pThis, PHDASTREAM pStrmSt)
-{
-    AssertPtrReturn(pThis,   NULL);
-    AssertPtrReturn(pStrmSt, NULL);
-
-    Assert(pStrmSt->State.paBDLE);
-    Assert(pStrmSt->State.uCurBDLE < pStrmSt->State.cBDLE);
-
-    PHDABDLE pBDLE = &pStrmSt->State.paBDLE[pStrmSt->State.uCurBDLE];
-    return pBDLE;
-}
-
-/**
- * Returns the next BDLE to use for a stream.
- *
- * @return BDLE to use next, NULL if none found.
- */
-DECLINLINE(PHDABDLE) hdaStreamGetNextBDLE(PHDASTATE pThis, PHDASTREAM pStrmSt)
-{
-    AssertPtrReturn(pThis,   NULL);
-    AssertPtrReturn(pStrmSt, NULL);
+ * @return  IPRT status code.
+ */
+DECLINLINE(int) hdaStreamGetNextBDLE(PHDASTATE pThis, PHDASTREAM pStrmSt)
+{
+    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
+    AssertPtrReturn(pStrmSt, VERR_INVALID_POINTER);
 
     NOREF(pThis);
 
-    Assert(pStrmSt->State.paBDLE);
-    Assert(pStrmSt->State.uCurBDLE < pStrmSt->State.cBDLE);
+    Assert(pStrmSt->State.uCurBDLE < pStrmSt->u16LVI + 1);
 
 #ifdef DEBUG
@@ -1136,5 +1128,5 @@
      */
     pStrmSt->State.uCurBDLE++;
-    if (pStrmSt->State.uCurBDLE == pStrmSt->State.cBDLE)
+    if (pStrmSt->State.uCurBDLE == pStrmSt->u16LVI + 1)
     {
         pStrmSt->State.uCurBDLE = 0;
@@ -1143,16 +1135,13 @@
     }
 
-    Assert(pStrmSt->State.uCurBDLE < pStrmSt->State.cBDLE);
-
-    PHDABDLE pBDLE = &pStrmSt->State.paBDLE[pStrmSt->State.uCurBDLE];
-    AssertPtr(pBDLE);
-
-    hdaBDLEReset(pBDLE);
+    Assert(pStrmSt->State.uCurBDLE < pStrmSt->u16LVI + 1);
+
+    int rc = hdaBDLEFetch(pThis, &pStrmSt->State.BDLE, pStrmSt->u64BaseDMA, pStrmSt->State.uCurBDLE);
 
 #ifdef DEBUG
-    LogFlowFunc(("[SD%RU8]: uOldBDLE=%RU16, uCurBDLE=%RU16, cBDLE=%RU32, %R[bdle]\n",
-                 pStrmSt->u8Strm, uOldBDLE, pStrmSt->State.uCurBDLE, pStrmSt->State.cBDLE, pBDLE));
-#endif
-    return pBDLE;
+    LogFlowFunc(("[SD%RU8]: uOldBDLE=%RU16, uCurBDLE=%RU16, LVI=%RU32, %R[bdle]\n",
+                 pStrmSt->u8Strm, uOldBDLE, pStrmSt->State.uCurBDLE, pStrmSt->u16LVI, &pStrmSt->State.BDLE));
+#endif
+    return rc;
 }
 #endif
@@ -1454,4 +1443,6 @@
     AssertRC(rc);
 
+    pStrmSt->u8Strm         = UINT8_MAX;
+
     pStrmSt->State.fActive  = false;
     pStrmSt->State.fInReset = false;
@@ -1462,4 +1453,22 @@
 }
 
+static void hdaStreamDestroy(PHDASTREAM pStrmSt)
+{
+    AssertPtrReturnVoid(pStrmSt);
+
+    LogFlowFunc(("[SD%RU8]: Destroy\n", pStrmSt->u8Strm));
+
+    int rc2 = hdaStreamStop(pStrmSt);
+    AssertRC(rc2);
+
+    if (pStrmSt->State.hStateChangedEvent != NIL_RTSEMEVENT)
+    {
+        rc2 = RTSemEventDestroy(pStrmSt->State.hStateChangedEvent);
+        AssertRC(rc2);
+    }
+
+    LogFlowFuncLeave();
+}
+
 static int hdaStreamInit(PHDASTATE pThis, PHDASTREAM pStrmSt, uint8_t u8Strm)
 {
@@ -1468,94 +1477,28 @@
 
     pStrmSt->u8Strm     = u8Strm;
-    pStrmSt->u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, u8Strm),
+    pStrmSt->u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStrmSt->u8Strm),
+                                      HDA_STREAM_REG(pThis, BDPU, pStrmSt->u8Strm));
+    pStrmSt->u16LVI     = HDA_STREAM_REG(pThis, LVI, pStrmSt->u8Strm);
+    pStrmSt->u32CBL     = HDA_STREAM_REG(pThis, CBL, pStrmSt->u8Strm);
+    pStrmSt->u16FIFOS   = hdaSDFIFOSToBytes(HDA_STREAM_REG(pThis, FIFOS, pStrmSt->u8Strm));
+
+    RT_ZERO(pStrmSt->State.BDLE);
+    pStrmSt->State.uCurBDLE = 0;
+
+    LogFlowFunc(("[SD%RU8]: DMA @ 0x%x (%RU32 bytes), LVI=%RU16, FIFOS=%RU16\n",
+                 pStrmSt->u8Strm, pStrmSt->u64BaseDMA, pStrmSt->u32CBL, pStrmSt->u16LVI, pStrmSt->u16FIFOS));
+
+#ifdef DEBUG
+    uint64_t u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, u8Strm),
                                       HDA_STREAM_REG(pThis, BDPU, u8Strm));
-    pStrmSt->u16LVI     = HDA_STREAM_REG(pThis, LVI, u8Strm);
-    pStrmSt->u32CBL     = HDA_STREAM_REG(pThis, CBL, u8Strm);
-    pStrmSt->u16FIFOS   = hdaSDFIFOSToBytes(HDA_STREAM_REG(pThis, FIFOS, u8Strm));
-
-    int rc = VINF_SUCCESS;
-
-    if (pStrmSt->State.paBDLE)
-    {
-        Assert(pStrmSt->State.cBDLE);
-        RTMemFree(pStrmSt->State.paBDLE);
-        pStrmSt->State.paBDLE = NULL;
-    }
-
-    pStrmSt->State.cBDLE = 0;
-
-    if (/* Is there a base DMA address set? */
-           pStrmSt->u64BaseDMA
-        /* Any BDLEs to fetch? */
-        && pStrmSt->u16LVI)
-    {
-        uint32_t cbBDLE = 0;
-
-        pStrmSt->State.cBDLE  = pStrmSt->u16LVI + 1; /* See 18.2.37: If LVI is n, then there are n + 1 entries. */
-        pStrmSt->State.paBDLE = (PHDABDLE)RTMemAllocZ(sizeof(HDABDLE) * pStrmSt->State.cBDLE);
-        if (pStrmSt->State.paBDLE)
-        {
-            for (uint16_t i = 0; i < pStrmSt->State.cBDLE; i++)
-            {
-                rc = hdaBDLEFetch(pThis, &pStrmSt->State.paBDLE[i], pStrmSt->u64BaseDMA, i);
-                if (RT_FAILURE(rc))
-                    break;
-
-                cbBDLE += pStrmSt->State.paBDLE[i].u32BufSize;
-            }
-
-#ifdef DEBUG
-            hdaBDLEDumpAll(pThis, pStrmSt->u64BaseDMA, pStrmSt->State.cBDLE);
-#endif
-            if (RT_SUCCESS(rc))
-            {
-                if (pStrmSt->u32CBL != cbBDLE)
-                {
-                    AssertMsgFailed(("CBL (%RU32) does not match BDL entries (%RU32)\n", pStrmSt->u32CBL, cbBDLE));
-                    LogRel(("HDA: Warning: CBL (%RU32) does not match BDL entries (%RU32); expect sound hickups\n",
-                            pStrmSt->u32CBL, cbBDLE));
-                }
-
-                HDA_STREAM_REG(pThis, STS, pStrmSt->u8Strm) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS);
-            }
-        }
-        else
-            rc = VERR_NO_MEMORY;
-    }
-
-    LogFunc(("[SD%RU8]: DMA=0x%x, LVI=%RU16, CBL=%RU32, FIFOS=%RU16\n",
-             u8Strm, pStrmSt->u64BaseDMA, pStrmSt->u16LVI, pStrmSt->u32CBL, pStrmSt->u16FIFOS));
-
-    return rc;
-}
-
-static void hdaStreamDestroy(PHDASTREAM pStrmSt)
-{
-    AssertPtrReturnVoid(pStrmSt);
-
-    LogFlowFuncEnter();
-
-    int rc2 = hdaStreamStop(pStrmSt);
-    AssertRC(rc2);
-
-    if (pStrmSt->State.hStateChangedEvent != NIL_RTSEMEVENT)
-    {
-        rc2 = RTSemEventDestroy(pStrmSt->State.hStateChangedEvent);
-        AssertRC(rc2);
-    }
-
-    /*
-     * Destroy.
-     */
-    if (pStrmSt->State.paBDLE)
-    {
-        Assert(pStrmSt->State.cBDLE);
-        RTMemFree(pStrmSt->State.paBDLE);
-        pStrmSt->State.paBDLE = NULL;
-    }
-
-    pStrmSt->State.cBDLE = 0;
-
-    LogFlowFuncLeave();
+    uint16_t u16LVI     = HDA_STREAM_REG(pThis, LVI, u8Strm);
+    uint32_t u32CBL     = HDA_STREAM_REG(pThis, CBL, u8Strm);
+
+    LogFlowFunc(("\t-> DMA @ 0x%x, LVI=%RU16, CBL=%RU32\n", u64BaseDMA, u16LVI, u32CBL));
+
+    hdaBDLEDumpAll(pThis, u64BaseDMA, u16LVI + 1);
+#endif
+
+    return VINF_SUCCESS;
 }
 
@@ -1580,10 +1523,5 @@
      * First, reset the internal stream state.
      */
-    pStrmSt->u8Strm     = u8Strm;
-    pStrmSt->u64BaseDMA = 0;
-    pStrmSt->u32CBL     = 0;
-    pStrmSt->u16FMT     = 0;
-    pStrmSt->u16FIFOS   = 0;
-    pStrmSt->u16LVI     = 0;
+    RT_BZERO(pStrmSt, sizeof(HDASTREAM));
 
     /*
@@ -1605,4 +1543,11 @@
     HDA_STREAM_REG(pThis, BDPL,  u8Strm) = 0;
 
+    /*
+     * Third, set the internal state according to the just set registers.
+     */
+    pStrmSt->u8Strm   = u8Strm;
+    pStrmSt->u16FIFOS = HDA_STREAM_REG(pThis, FIFOS, u8Strm);
+
+
     /* Report that we're done resetting this stream. */
     HDA_STREAM_REG(pThis, CTL,   u8Strm) = 0;
@@ -1980,10 +1925,4 @@
         if (fInRun != fRun)
         {
-            if (fRun)
-            {
-                int rc2 = hdaStreamInit(pThis, pStrmSt, u8Strm);
-                AssertRC(rc2);
-            }
-
             Assert(!fReset && !fInReset);
             LogFunc(("[SD%RU8]: fRun=%RTbool\n", u8Strm, fRun));
@@ -2020,4 +1959,8 @@
             }
         }
+
+        if (!fInRun && !fRun)
+            hdaStreamInit(pThis, pStrmSt, u8Strm);
+
 #else /* !IN_RING3 */
         return VINF_IOM_R3_MMIO_WRITE;
@@ -2039,11 +1982,6 @@
 static int hdaRegWriteSDLVI(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
 {
-    /* Only can be modified if RUN bit is 0. */
-    bool fIsRunning = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
-    if (fIsRunning)
-    {
-        AssertMsgFailed(("Cannot write to register when RUN bit is set\n"));
+    if (!hdaRegWriteSDIsAllowed(pThis, iReg, u32Value))
         return VINF_SUCCESS;
-    }
 
     int rc = hdaRegWriteU32(pThis, iReg, u32Value);
@@ -2259,4 +2197,9 @@
 static int hdaRegWriteSDBDPL(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
 {
+    if (!hdaRegWriteSDIsAllowed(pThis, iReg, u32Value))
+        return VINF_SUCCESS;
+
+    LogFlowFunc(("[SD%RU8]: DMA BDPL -> 0x%x\n", HDA_SD_NUM_FROM_REG(pThis, CTL, iReg), u32Value));
+
     int rc = hdaRegWriteU32(pThis, iReg, u32Value);
     if (RT_FAILURE(rc))
@@ -2267,8 +2210,37 @@
 static int hdaRegWriteSDBDPU(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
 {
+    if (!hdaRegWriteSDIsAllowed(pThis, iReg, u32Value))
+        return VINF_SUCCESS;
+
+    LogFlowFunc(("[SD%RU8]: DMA BDPU -> 0x%x\n", HDA_SD_NUM_FROM_REG(pThis, CTL, iReg), u32Value));
+
     int rc = hdaRegWriteU32(pThis, iReg, u32Value);
     if (RT_FAILURE(rc))
         AssertRCReturn(rc, VINF_SUCCESS);
     return rc;
+}
+
+/**
+ * Checks whether a write to a specific SDnXXX register is allowed or not.
+ *
+ * @return  bool                Returns @true if write is allowed, @false if not.
+ * @param   pThis               Pointer to HDA state.
+ * @param   iReg                Register to write.
+ * @param   u32Value            Value to write.
+ */
+inline bool hdaRegWriteSDIsAllowed(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value)
+{
+    /* Check if the SD's RUN bit is set. */
+    bool fIsRunning = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN));
+    if (fIsRunning)
+    {
+#ifdef VBOX_STRICT
+        AssertMsgFailed(("[SD%RU8]: Cannot write to register 0x%x (0x%x) when RUN bit is set\n",
+                         HDA_SD_NUM_FROM_REG(pThis, CTL, iReg), iReg, u32Value));
+#endif
+        return false;
+    }
+
+    return true;
 }
 
@@ -2380,10 +2352,6 @@
 
             /* Also make sure to handle the DMA position enable bit. */
-            bool fEnabled = pThis->au32Regs[iRegMem] & RT_BIT_32(0);
-            if (pThis->fDMAPosition != fEnabled)
-            {
-                LogRel(("HDA: %s DMA position buffer\n", fEnabled ? "Enabled" : "Disabled"));
-                pThis->fDMAPosition = fEnabled;
-            }
+            pThis->fDMAPosition = pThis->au32Regs[iRegMem] & RT_BIT_32(0);
+            LogRel(("HDA: %s DMA position buffer\n", pThis->fDMAPosition ? "Enabled" : "Disabled"));
             break;
         }
@@ -2414,6 +2382,9 @@
 static void hdaBDLEDumpAll(PHDASTATE pThis, uint64_t u64BaseDMA, uint16_t cBDLE)
 {
+    LogFlowFunc(("BDLEs @ 0x%x (%RU16):\n", u64BaseDMA, cBDLE));
+    if (!u64BaseDMA)
+        return;
+
     uint32_t cbBDLE = 0;
-
     for (uint16_t i = 0; i < cBDLE; i++)
     {
@@ -2425,5 +2396,5 @@
         uint32_t ioc  = *(uint32_t *)&bdle[12];
 
-        LogFlowFunc(("#%03d BDLE(adr:0x%llx, size:%RU32, ioc:%RTbool)\n",
+        LogFlowFunc(("\t#%03d BDLE(adr:0x%llx, size:%RU32, ioc:%RTbool)\n",
                      i, addr, len, RT_BOOL(ioc & 0x1)));
 
@@ -2436,12 +2407,13 @@
         return;
 
+    LogFlowFunc(("DMA counters:\n", cbBDLE));
+
     for (int i = 0; i < 8; i++) /** @todo Use a define for MAX_STREAMS! */
     {
         uint32_t uDMACnt;
-        PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), (pThis->u64DPBase & DPBASE_ADDR_MASK) + i * 8, /** @todo Use a define. */
+        PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), (pThis->u64DPBase & DPBASE_ADDR_MASK) + (i * 2 * sizeof(uint32_t)),
                           &uDMACnt, sizeof(&uDMACnt));
 
-        LogFlowFunc(("%s #%02d STREAM(0x%x)\n",
-                     i == HDA_SDCTL_NUM(pThis, 4) || i == HDA_SDCTL_NUM(pThis, 0) ? "*" : " ", i , uDMACnt));
+        LogFlowFunc(("\t#%03d DMA @ 0x%x\n", i , uDMACnt));
     }
 }
@@ -2469,4 +2441,6 @@
         return rc;
 
+    RT_BZERO(pBDLE, sizeof(HDABDLE));
+
     pBDLE->State.u32BDLIndex = u16Entry;
     pBDLE->u64BufAdr         = *(uint64_t *) uBundleEntry;
@@ -2480,12 +2454,4 @@
 }
 
-static void hdaBDLEReset(PHDABDLE pBDLE)
-{
-    AssertPtrReturnVoid(pBDLE);
-
-    pBDLE->State.u32BufOff    = 0;
-    pBDLE->State.cbBelowFIFOW = 0;
-}
-
 /**
  * Returns the number of outstanding stream data bytes which need to be processed
@@ -2502,5 +2468,5 @@
         return 0;
 
-    PHDABDLE pBDLE = hdaStreamGetCurrentBDLE(pThis, pStrmSt);
+    PHDABDLE pBDLE = &pStrmSt->State.BDLE;
 
     uint32_t cbFree = pStrmSt->u32CBL - HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm);
@@ -2573,5 +2539,5 @@
     AssertPtrReturn(pStrmSt, false);
 
-    PHDABDLE pBDLE   = hdaStreamGetCurrentBDLE(pThis, pStrmSt);
+    PHDABDLE pBDLE   = &pStrmSt->State.BDLE;
     uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm);
 
@@ -2582,7 +2548,5 @@
      * the CBL limit or our internal DMA buffer is full. */
     bool fNeedsNextBDLE   = (   fCBLLimitReached
-                             || (   pBDLE->State.u32BufOff
-                                 && pBDLE->State.u32BufOff >= pBDLE->u32BufSize)
-                            );
+                             || (pBDLE->State.u32BufOff >= pBDLE->u32BufSize));
 
     Assert(u32LPIB                <= pStrmSt->u32CBL);
@@ -2599,10 +2563,4 @@
     }
 
-    if (fNeedsNextBDLE)
-    {
-        /* Reset current BDLE. */
-        hdaBDLEReset(pBDLE);
-    }
-
     return fNeedsNextBDLE;
 }
@@ -2617,5 +2575,5 @@
     Assert(cbInc <= pStrmSt->u16FIFOS);
 
-    PHDABDLE pBDLE = hdaStreamGetCurrentBDLE(pThis, pStrmSt);
+    PHDABDLE pBDLE = &pStrmSt->State.BDLE;
 
     /*
@@ -2645,5 +2603,5 @@
     bool fIsComplete = false;
 
-    PHDABDLE       pBDLE   = hdaStreamGetCurrentBDLE(pThis, pStrmSt);
+    PHDABDLE       pBDLE   = &pStrmSt->State.BDLE;
     const uint32_t u32LPIB = HDA_STREAM_REG(pThis, LPIB, pStrmSt->u8Strm);
 
@@ -2701,5 +2659,5 @@
     /* pcbRead is optional. */
 
-    PHDABDLE pBDLE = hdaStreamGetCurrentBDLE(pThis, pStrmSt);
+    PHDABDLE pBDLE = &pStrmSt->State.BDLE;
 
     int rc;
@@ -2768,6 +2726,5 @@
     /* pcbWritten is optional. */
 
-    PHDABDLE pBDLE = hdaStreamGetCurrentBDLE(pThis, pStrmSt);
-    int rc;
+    PHDABDLE pBDLE = &pStrmSt->State.BDLE;
 
     uint32_t cbWritten = 0;
@@ -2780,4 +2737,5 @@
      * previous unreported transfer we write at offset 'pBDLE->State.cbUnderFifoW').
      */
+    int rc;
     if (!cbData)
     {
@@ -3151,6 +3109,4 @@
     /* pcbProcessed is optional. */
 
-    LogFlowFunc(("enmSrc=%RU32, cbToProcess=%RU32\n", enmSrc, cbToProcess));
-
     if (ASMAtomicReadBool(&pThis->fInReset)) /* HDA controller in reset mode? Bail out. */
     {
@@ -3206,7 +3162,4 @@
     /* Is the stream not in a running state currently? */
     else if (!(HDA_STREAM_REG(pThis, CTL, pStrmSt->u8Strm) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)))
-        fProceed = false;
-    /* There must be BDLEs defined in order to have a working stream. */
-    else if (pStrmSt->State.cBDLE == 0)
         fProceed = false;
     /* Nothing to process? */
@@ -3221,4 +3174,6 @@
     }
 
+    LogFlowFunc(("enmSrc=%RU32, cbToProcess=%RU32\n", enmSrc, cbToProcess));
+
     /* Sanity checks. */
     Assert(pStrmSt->u8Strm <= 7); /** @todo Use a define for MAX_STREAMS! */
@@ -3227,5 +3182,4 @@
 
     /* State sanity checks. */
-    AssertPtr(pStrmSt->State.paBDLE);
     Assert(ASMAtomicReadBool(&pStrmSt->State.fInReset) == false);
 
@@ -3395,5 +3349,8 @@
 {
     if (pThis->fInReset && idxRegDsc != HDA_REG_GCTL)
-        LogFunc(("access to registers except GCTL is blocked while reset\n"));  /** @todo where is this enforced? */
+    {
+        LogRel2(("HDA: Access to register 0x%x is blocked while reset\n", idxRegDsc));
+        return VINF_SUCCESS;
+    }
 
     uint32_t idxRegMem = g_aHdaRegMap[idxRegDsc].mem_idx;
@@ -3413,6 +3370,6 @@
 PDMBOTHCBDECL(int) hdaMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
 {
-    PHDASTATE               pThis  = PDMINS_2_DATA(pDevIns, PHDASTATE);
-    int                     rc;
+    PHDASTATE pThis  = PDMINS_2_DATA(pDevIns, PHDASTATE);
+    int       rc;
 
     /*
@@ -3594,4 +3551,8 @@
 static int hdaSaveStream(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, PHDASTREAM pStrm)
 {
+    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
+
+    LogFlowFunc(("[SD%RU8]\n", pStrm->u8Strm));
+
     /* Save stream ID. */
     int rc = SSMR3PutU8(pSSM, pStrm->u8Strm);
@@ -3599,14 +3560,48 @@
     Assert(pStrm->u8Strm <= 7); /** @todo Use a define. */
 
-    rc = SSMR3PutStructEx(pSSM, &pStrm->State, sizeof(HDASTREAMSTATE), 0 /*fFlags*/, g_aSSMStreamStateFields5, NULL);
+    rc = SSMR3PutStructEx(pSSM, &pStrm->State, sizeof(HDASTREAMSTATE), 0 /*fFlags*/, g_aSSMStreamStateFields6, NULL);
     AssertRCReturn(rc, rc);
 
-    for (uint32_t i = 0; i < pStrm->State.cBDLE; i++)
-    {
-        rc = SSMR3PutStructEx(pSSM, &pStrm->State.paBDLE[i].State, sizeof(HDABDLESTATE),
-                              0 /*fFlags*/, g_aSSMBDLEStateFields5, NULL);
-        AssertRCReturn(rc, rc);
-    }
-
+#ifdef DEBUG /* Sanity checks. */
+    uint64_t u64BaseDMA = RT_MAKE_U64(HDA_STREAM_REG(pThis, BDPL, pStrm->u8Strm),
+                                      HDA_STREAM_REG(pThis, BDPU, pStrm->u8Strm));
+    uint16_t u16LVI     = HDA_STREAM_REG(pThis, LVI, pStrm->u8Strm);
+    uint32_t u32CBL     = HDA_STREAM_REG(pThis, CBL, pStrm->u8Strm);
+
+    hdaBDLEDumpAll(pThis, u64BaseDMA, u16LVI + 1);
+
+    Assert(u64BaseDMA == pStrm->u64BaseDMA);
+    Assert(u16LVI     == pStrm->u16LVI);
+    Assert(u32CBL     == pStrm->u32CBL);
+#endif
+
+    rc = SSMR3PutStructEx(pSSM, &pStrm->State.BDLE, sizeof(HDABDLE),
+                          0 /*fFlags*/, g_aSSMBDLEFields6, NULL);
+    AssertRCReturn(rc, rc);
+
+    rc = SSMR3PutStructEx(pSSM, &pStrm->State.BDLE.State, sizeof(HDABDLESTATE),
+                          0 /*fFlags*/, g_aSSMBDLEStateFields6, NULL);
+    AssertRCReturn(rc, rc);
+
+#ifdef DEBUG /* Sanity checks. */
+    PHDABDLE pBDLE = &pStrm->State.BDLE;
+    if (u64BaseDMA)
+    {
+        Assert(pStrm->State.uCurBDLE <= u16LVI + 1);
+
+        HDABDLE curBDLE;
+        rc = hdaBDLEFetch(pThis, &curBDLE, u64BaseDMA, pStrm->State.uCurBDLE);
+        AssertRC(rc);
+
+        Assert(curBDLE.u32BufSize       == pBDLE->u32BufSize);
+        Assert(curBDLE.u64BufAdr        == pBDLE->u64BufAdr);
+        Assert(curBDLE.fIntOnCompletion == pBDLE->fIntOnCompletion);
+    }
+    else
+    {
+        Assert(pBDLE->u64BufAdr  == 0);
+        Assert(pBDLE->u32BufSize == 0);
+    }
+#endif
     return rc;
 }
@@ -3728,31 +3723,29 @@
      *       according to the spec).
      */
-#define HDA_SSM_LOAD_BDLE_STATE_PRE_V5(v, x)                        \
-    rc = SSMR3Skip(pSSM, sizeof(uint32_t));    /* Begin marker */   \
-    AssertRCReturn(rc, rc);                                         \
-    rc = SSMR3Skip(pSSM, sizeof(uint64_t));    /* u64BdleCviAddr */ \
-    AssertRCReturn(rc, rc);                                         \
-    rc = SSMR3Skip(pSSM, sizeof(uint32_t));    /* u32BdleMaxCvi */  \
-    AssertRCReturn(rc, rc);                                         \
-    rc = SSMR3GetU32(pSSM, &x->u32BDLIndex);   /* u32BdleCvi */     \
-    AssertRCReturn(rc, rc);                                         \
-    rc = SSMR3Skip(pSSM, sizeof(uint32_t));    /* u32BdleCviLen */  \
-    AssertRCReturn(rc, rc);                                         \
-    rc = SSMR3GetU32(pSSM, &x->u32BufOff);     /* u32BdleCviPos */  \
-    AssertRCReturn(rc, rc);                                         \
-    rc = SSMR3Skip(pSSM, sizeof(uint8_t));     /* fBdleCviIoc */    \
-    AssertRCReturn(rc, rc);                                         \
-    rc = SSMR3GetU32(pSSM, &x->cbBelowFIFOW);  /* cbUnderFifoW */   \
-    AssertRCReturn(rc, rc);                                         \
-    rc = SSMR3GetMem(pSSM, &x->au8FIFO, sizeof(x->au8FIFO));        \
-    AssertRCReturn(rc, rc);                                         \
-    rc = SSMR3Skip(pSSM, sizeof(uint32_t));    /* End marker */     \
-    AssertRCReturn(rc, rc);                                         \
+#define HDA_SSM_LOAD_BDLE_STATE_PRE_V5(v, x)                            \
+    rc = SSMR3Skip(pSSM, sizeof(uint32_t));        /* Begin marker */   \
+    AssertRCReturn(rc, rc);                                             \
+    rc = SSMR3GetU64(pSSM, &x.u64BufAdr);          /* u64BdleCviAddr */ \
+    AssertRCReturn(rc, rc);                                             \
+    rc = SSMR3Skip(pSSM, sizeof(uint32_t));        /* u32BdleMaxCvi */  \
+    AssertRCReturn(rc, rc);                                             \
+    rc = SSMR3GetU32(pSSM, &x.State.u32BDLIndex);  /* u32BdleCvi */     \
+    AssertRCReturn(rc, rc);                                             \
+    rc = SSMR3GetU32(pSSM, &x.u32BufSize);         /* u32BdleCviLen */  \
+    AssertRCReturn(rc, rc);                                             \
+    rc = SSMR3GetU32(pSSM, &x.State.u32BufOff);    /* u32BdleCviPos */  \
+    AssertRCReturn(rc, rc);                                             \
+    rc = SSMR3GetBool(pSSM, &x.fIntOnCompletion);  /* fBdleCviIoc */    \
+    AssertRCReturn(rc, rc);                                             \
+    rc = SSMR3GetU32(pSSM, &x.State.cbBelowFIFOW); /* cbUnderFifoW */   \
+    AssertRCReturn(rc, rc);                                             \
+    rc = SSMR3GetMem(pSSM, &x.State.au8FIFO, sizeof(x.State.au8FIFO));  \
+    AssertRCReturn(rc, rc);                                             \
+    rc = SSMR3Skip(pSSM, sizeof(uint32_t));        /* End marker */     \
+    AssertRCReturn(rc, rc);                                             \
 
     /*
      * Load BDLEs (Buffer Descriptor List Entries) and DMA counters.
      */
-    HDABDLESTATE StateBDLEDummy;
-
     switch (uVersion)
     {
@@ -3765,5 +3758,6 @@
              * The rest will be initialized from the saved registers later. */
 
-            /* Note: Only the *current* BDLE for a stream was saved! */
+            /* Note 1: Only the *current* BDLE for a stream was saved! */
+            /* Note 2: The stream's saving order is/was fixed, so don't touch! */
 
             /* Output */
@@ -3771,18 +3765,20 @@
             if (RT_FAILURE(rc))
                 break;
-            HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, (   pThis->StrmStOut.State.cBDLE
-                                                      ? &pThis->StrmStOut.State.paBDLE[0].State : &StateBDLEDummy));
+            HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, pThis->StrmStOut.State.BDLE);
+            pThis->StrmStOut.State.uCurBDLE = pThis->StrmStOut.State.BDLE.State.u32BDLIndex;
+
             /* Microphone-In */
             rc = hdaStreamInit(pThis, &pThis->StrmStMicIn,  2 /* Stream number, hardcoded */);
             if (RT_FAILURE(rc))
                 break;
-            HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, (   pThis->StrmStMicIn.State.cBDLE
-                                                      ? &pThis->StrmStMicIn.State.paBDLE[0].State : &StateBDLEDummy));
+            HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, pThis->StrmStMicIn.State.BDLE);
+            pThis->StrmStMicIn.State.uCurBDLE = pThis->StrmStMicIn.State.BDLE.State.u32BDLIndex;
+
             /* Line-In */
             rc = hdaStreamInit(pThis, &pThis->StrmStLineIn, 0 /* Stream number, hardcoded */);
             if (RT_FAILURE(rc))
                 break;
-            HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, (  pThis->StrmStLineIn.State.cBDLE
-                                                      ? &pThis->StrmStLineIn.State.paBDLE[0].State : &StateBDLEDummy));
+            HDA_SSM_LOAD_BDLE_STATE_PRE_V5(uVersion, pThis->StrmStLineIn.State.BDLE);
+            pThis->StrmStLineIn.State.uCurBDLE = pThis->StrmStLineIn.State.BDLE.State.u32BDLIndex;
             break;
         }
@@ -3826,46 +3822,81 @@
                     default:
                         pStrm = &StreamDummy;
+
+                        LogRel2(("HDA: Warning: Stream ID=%RU32 not supported, skipping to load ...\n", uStreamID));
                         break;
                 }
 
                 RT_BZERO(pStrm, sizeof(HDASTREAM));
-                rc = SSMR3GetStructEx(pSSM, &pStrm->State, sizeof(HDASTREAMSTATE), 0 /* fFlags */, g_aSSMStreamStateFields5, NULL);
-                if (RT_FAILURE(rc))
-                    break;
-#ifdef DEBUG
-                uint32_t cBDLE = pStrm->State.cBDLE;
-                LogFlowFunc(("Stream #%RU32: ID=%RU8, cBDLE=%RU32\n", i, uStreamID, cBDLE));
-#endif
+
                 rc = hdaStreamInit(pThis, pStrm, uStreamID);
                 if (RT_FAILURE(rc))
                 {
-                    LogRel(("HDA: Stream #%RU32: Inititialization of stream (ID=%RU8, cBDLE=%RU32) failed, rc=%Rrc\n", i, uStreamID, pStrm->State.cBDLE, rc));
+                    LogRel(("HDA: Stream #%RU32: Initialization of stream %RU8 failed, rc=%Rrc\n", i, uStreamID, rc));
                     break;
                 }
-#ifdef DEBUG
-                AssertMsg(cBDLE == pStrm->State.cBDLE, ("Loaded BDLE states (%RU32) vs. emulated ones (%RU32) don't match\n",
-                                                        cBDLE, pStrm->State.cBDLE));
-#endif
-                /* Load BDLE states. */
-                for (uint32_t a = 0; a < pStrm->State.cBDLE; a++)
+
+                if (uVersion == HDA_SSM_VERSION_5)
                 {
-                    if (uVersion == HDA_SSM_VERSION_5)
+                    /* Get the current BDLE entry and skip the rest. */
+                    uint16_t cBDLE;
+
+                    rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* Begin marker */
+                    AssertRC(rc);
+                    rc = SSMR3GetU16(pSSM, &cBDLE);                 /* cBDLE */
+                    AssertRC(rc);
+                    rc = SSMR3GetU16(pSSM, &pStrm->State.uCurBDLE); /* uCurBDLE */
+                    AssertRC(rc);
+                    rc = SSMR3Skip(pSSM, sizeof(uint32_t));         /* End marker */
+                    AssertRC(rc);
+
+                    uint32_t u32BDLEIndex;
+                    for (uint16_t i = 0; i < cBDLE; i++)
                     {
-                        /* v5 saved the entire HDABDLE struct instead of only HDABDLESTATE,
-                         * so skip. */
-                        rc = SSMR3Skip(pSSM, 0x120 /* sizeof(HDABLDE) in v5 */);
+                        rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* Begin marker */
+                        AssertRC(rc);
+                        rc = SSMR3GetU32(pSSM, &u32BDLEIndex);  /* u32BDLIndex */
+                        AssertRC(rc);
+
+                        /* Does the current BDLE index match the current BDLE to process? */
+                        if (u32BDLEIndex == pStrm->State.uCurBDLE)
+                        {
+                            rc = SSMR3GetU32(pSSM, &pStrm->State.BDLE.State.cbBelowFIFOW); /* cbBelowFIFOW */
+                            AssertRC(rc);
+                            rc = SSMR3GetMem(pSSM,
+                                             &pStrm->State.BDLE.State.au8FIFO,
+                                             sizeof(uint8_t) * 256);                       /* au8FIFO */
+                            AssertRC(rc);
+                            rc = SSMR3GetU32(pSSM, &pStrm->State.BDLE.State.u32BufOff);    /* u32BufOff */
+                            AssertRC(rc);
+                            rc = SSMR3Skip(pSSM, sizeof(uint32_t));                        /* End marker */
+                            AssertRC(rc);
+                        }
+                        else /* Skip not current BDLEs. */
+                        {
+                            rc = SSMR3Skip(pSSM,   sizeof(uint32_t)      /* cbBelowFIFOW */
+                                                 + sizeof(uint8_t) * 256 /* au8FIFO */
+                                                 + sizeof(uint32_t)      /* u32BufOff */
+                                                 + sizeof(uint32_t));    /* End marker */
+                            AssertRC(rc);
+                        }
                     }
-                    else
-                    {
-                        rc = SSMR3GetStructEx(pSSM, &pStrm->State.paBDLE[a].State, sizeof(HDABDLESTATE),
-                                              0 /* fFlags */, g_aSSMBDLEStateFields5, NULL);
-                    }
+                }
+                else
+                {
+                    rc = SSMR3GetStructEx(pSSM, &pStrm->State, sizeof(HDASTREAMSTATE),
+                                          0 /* fFlags */, g_aSSMStreamStateFields6, NULL);
+                    if (RT_FAILURE(rc))
+                        break;
+
+                    rc = SSMR3GetStructEx(pSSM, &pStrm->State.BDLE, sizeof(HDABDLE),
+                                          0 /* fFlags */, g_aSSMBDLEFields6, NULL);
+                    if (RT_FAILURE(rc))
+                        break;
+
+                    rc = SSMR3GetStructEx(pSSM, &pStrm->State.BDLE.State, sizeof(HDABDLESTATE),
+                                          0 /* fFlags */, g_aSSMBDLEStateFields6, NULL);
                     if (RT_FAILURE(rc))
                         break;
                 }
-
-                /* Destroy dummy again. */
-                if (pStrm == &StreamDummy)
-                    hdaStreamDestroy(pStrm);
             }
             break;
@@ -3909,7 +3940,10 @@
     if (RT_SUCCESS(rc))
     {
-        pThis->u64CORBBase = RT_MAKE_U64(HDA_REG(pThis, CORBLBASE), HDA_REG(pThis, CORBUBASE));
-        pThis->u64RIRBBase = RT_MAKE_U64(HDA_REG(pThis, RIRBLBASE), HDA_REG(pThis, RIRBUBASE));
-        pThis->u64DPBase   = RT_MAKE_U64(HDA_REG(pThis, DPLBASE),   HDA_REG(pThis, DPUBASE));
+        pThis->u64CORBBase  = RT_MAKE_U64(HDA_REG(pThis, CORBLBASE), HDA_REG(pThis, CORBUBASE));
+        pThis->u64RIRBBase  = RT_MAKE_U64(HDA_REG(pThis, RIRBLBASE), HDA_REG(pThis, RIRBUBASE));
+        pThis->u64DPBase    = RT_MAKE_U64(HDA_REG(pThis, DPLBASE),   HDA_REG(pThis, DPUBASE));
+
+        /* Also make sure to update the DMA position bit if this was enabled when saving the state. */
+        pThis->fDMAPosition = RT_BOOL(HDA_REG(pThis, DPLBASE) & RT_BIT_32(0));
     }
     else
@@ -4147,35 +4181,4 @@
     LogFunc(("Resetting ...\n"));
 
-    /*
-     * Stop any audio currently playing and/or recording.
-     */
-    PHDADRIVER pDrv;
-    RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
-    {
-        pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->LineIn.pStrmIn, false /* Disable */);
-#ifdef VBOX_WITH_HDA_MIC_IN
-        /* Ignore rc. */
-        pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->MicIn.pStrmIn, false /* Disable */);
-#endif
-        /* Ditto. */
-        pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Out.pStrmOut, false /* Disable */);
-        /* Ditto. */
-    }
-
-    pThis->cbCorbBuf = 256 * sizeof(uint32_t); /** @todo Use a define here. */
-
-    if (pThis->pu32CorbBuf)
-        RT_BZERO(pThis->pu32CorbBuf, pThis->cbCorbBuf);
-    else
-        pThis->pu32CorbBuf = (uint32_t *)RTMemAllocZ(pThis->cbCorbBuf);
-
-    pThis->cbRirbBuf = 256 * sizeof(uint64_t); /** @todo Use a define here. */
-    if (pThis->pu64RirbBuf)
-        RT_BZERO(pThis->pu64RirbBuf, pThis->cbRirbBuf);
-    else
-        pThis->pu64RirbBuf = (uint64_t *)RTMemAllocZ(pThis->cbRirbBuf);
-
-    pThis->u64BaseTS = PDMDevHlpTMTimeVirtGetNano(pDevIns);
-
 # ifndef VBOX_WITH_AUDIO_CALLBACKS
     /*
@@ -4189,4 +4192,35 @@
     }
 # endif
+
+    /*
+     * Stop any audio currently playing and/or recording.
+     */
+    PHDADRIVER pDrv;
+    RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
+    {
+        pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->LineIn.pStrmIn, false /* Disable */);
+# ifdef VBOX_WITH_HDA_MIC_IN
+        /* Ignore rc. */
+        pDrv->pConnector->pfnEnableIn(pDrv->pConnector, pDrv->MicIn.pStrmIn, false /* Disable */);
+# endif
+        /* Ditto. */
+        pDrv->pConnector->pfnEnableOut(pDrv->pConnector, pDrv->Out.pStrmOut, false /* Disable */);
+        /* Ditto. */
+    }
+
+    pThis->cbCorbBuf = 256 * sizeof(uint32_t); /** @todo Use a define here. */
+
+    if (pThis->pu32CorbBuf)
+        RT_BZERO(pThis->pu32CorbBuf, pThis->cbCorbBuf);
+    else
+        pThis->pu32CorbBuf = (uint32_t *)RTMemAllocZ(pThis->cbCorbBuf);
+
+    pThis->cbRirbBuf = 256 * sizeof(uint64_t); /** @todo Use a define here. */
+    if (pThis->pu64RirbBuf)
+        RT_BZERO(pThis->pu64RirbBuf, pThis->cbRirbBuf);
+    else
+        pThis->pu64RirbBuf = (uint64_t *)RTMemAllocZ(pThis->cbRirbBuf);
+
+    pThis->u64BaseTS = PDMDevHlpTMTimeVirtGetNano(pDevIns);
 
     for (uint8_t u8Strm = 0; u8Strm < 8; u8Strm++) /** @todo Use a define here. */
@@ -4220,4 +4254,5 @@
     if (pThis->pTimer)
     {
+        LogFunc(("Restarting timer\n"));
         rc2 = TMTimerSet(pThis->pTimer, TMTimerGet(pThis->pTimer) + pThis->cTimerTicks);
         AssertRC(rc2);
