Index: /trunk/src/VBox/Devices/Audio/DevHDA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevHDA.cpp	(revision 82330)
+++ /trunk/src/VBox/Devices/Audio/DevHDA.cpp	(revision 82331)
@@ -157,14 +157,9 @@
 #define DEVHDA_LOCK_BOTH_RETURN(a_pDevIns, a_pThis, a_SD, a_rcBusy) \
     do { \
-        int rcLock = TMTimerLock((a_pThis)->pTimer[a_SD], (a_rcBusy)); \
-        if (rcLock == VINF_SUCCESS) \
-        { \
-            rcLock = PDMDevHlpCritSectEnter((a_pDevIns), &(a_pThis)->CritSect, (a_rcBusy)); \
-            if (rcLock == VINF_SUCCESS) \
-                break; \
-            TMTimerUnlock((a_pThis)->pTimer[a_SD]); \
-        } \
-        AssertRC(rcLock); \
-        return rcLock; \
+        VBOXSTRICTRC rcLock = PDMDevHlpTimerLockClock2(pDevIns, (a_pThis)->ahTimers[a_SD], &(a_pThis)->CritSect,  (a_rcBusy)); \
+        if (RT_LIKELY(rcLock == VINF_SUCCESS)) \
+        {  /* likely */ } \
+        else \
+            return VBOXSTRICTRC_TODO(rcLock); \
     } while (0)
 
@@ -173,8 +168,5 @@
  */
 #define DEVHDA_UNLOCK_BOTH(a_pDevIns, a_pThis, a_SD) \
-    do { \
-        PDMDevHlpCritSectLeave((a_pDevIns), &(a_pThis)->CritSect); \
-        TMTimerUnlock((a_pThis)->pTimer[a_SD]); \
-    } while (0)
+    PDMDevHlpTimerUnlockClock2(pDevIns, (a_pThis)->ahTimers[a_SD], &(a_pThis)->CritSect)
 
 
@@ -1400,5 +1392,5 @@
 # endif
                 /* (Re-)initialize the stream with current values. */
-                rc2 = hdaR3StreamInit(pStream, pStream->u8SD);
+                rc2 = hdaR3StreamInit(pDevIns, pStream, pStream->u8SD);
                 if (   RT_SUCCESS(rc2)
                     /* Any vital stream change occurred so that we need to (re-)add the stream to our setup?
@@ -1435,5 +1427,7 @@
                     AssertRC(rc2);
 
-                    rc2 = hdaR3TimerSet(pThis, pStream, TMTimerGet(pThis->pTimer[pStream->u8SD]) + pStream->State.cTransferTicks,
+                    rc2 = hdaR3TimerSet(pDevIns, pThis, pStream,
+                                          PDMDevHlpTimerGet(pDevIns, pThis->ahTimers[pStream->u8SD])
+                                        + pStream->State.cTransferTicks,
                                         false /* fForce */);
                     AssertRC(rc2);
@@ -1527,5 +1521,5 @@
     HDA_PROCESS_INTERRUPT(pDevIns, pThis);
 
-    const uint64_t tsNow = TMTimerGet(pThis->pTimer[uSD]);
+    const uint64_t tsNow = PDMDevHlpTimerGet(pDevIns, pThis->ahTimers[uSD]);
     Assert(tsNow >= pStream->State.tsTransferLast);
 
@@ -1545,7 +1539,5 @@
 
         if (cTicksElapsed <= cTicksToNext)
-        {
             cTicksToNext = cTicksToNext - cTicksElapsed;
-        }
         else /* Catch up. */
         {
@@ -1555,5 +1547,6 @@
             LogRelMax2(64, ("HDA: Stream #%RU8 interrupt lagging behind (expected %uus, got %uus), trying to catch up ...\n",
                             pStream->u8SD,
-                            (TMTimerGetFreq(pThis->pTimer[pStream->u8SD]) / pThis->uTimerHz) / 1000,(tsNow - pStream->State.tsTransferLast) / 1000));
+                            (PDMDevHlpTimerGetFreq(pDevIns, pThis->ahTimers[pStream->u8SD]) / pThis->uTimerHz) / 1000,
+                            (tsNow - pStream->State.tsTransferLast) / 1000));
 
             cTicksToNext = 0;
@@ -1575,5 +1568,5 @@
             /* Re-arm the timer. */
             LogFunc(("Timer set SD%RU8\n", pStream->u8SD));
-            hdaR3TimerSet(pThis, pStream, tsNow + cTicksToNext, false /* fForce */);
+            hdaR3TimerSet(pDevIns, pThis, pStream, tsNow + cTicksToNext, false /* fForce */);
         }
     }
@@ -2845,21 +2838,18 @@
 
 /**
- * Main routine for the stream's timer.
- *
- * @param   pDevIns             Device instance.
- * @param   pTimer              Timer this callback was called for.
- * @param   pvUser              Pointer to associated HDASTREAM.
+ * @callback_method_impl{FNTMTIMERDEV, Main routine for the stream's timer.}
  */
 static DECLCALLBACK(void) hdaR3Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
 {
-    PHDASTATE  pThis   = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
-    PHDASTREAM pStream = (PHDASTREAM)pvUser;
+    PHDASTATE       pThis   = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
+    PHDASTREAM      pStream = (PHDASTREAM)pvUser;
+    TMTIMERHANDLE   hTimer  = RT_SAFE_SUBSCRIPT8(pThis->ahTimers, pStream->u8SD);
     RT_NOREF(pTimer);
 
     AssertPtr(pStream);
     Assert(PDMDevHlpCritSectIsOwner(pDevIns, &pThis->CritSect));
-    Assert(TMTimerIsLockOwner(pStream->pTimer));
-
-    hdaR3StreamUpdate(pStream, true /* fInTimer */);
+    Assert(PDMDevHlpTimerIsLockOwner(pDevIns, hTimer));
+
+    hdaR3StreamUpdate(pDevIns, pStream, true /* fInTimer */);
 
     /* Flag indicating whether to kick the timer again for a new data processing round. */
@@ -2870,10 +2860,10 @@
     if (fSinkActive)
     {
-        const bool fTimerScheduled = hdaR3StreamTransferIsScheduled(pStream);
+        const bool fTimerScheduled = hdaR3StreamTransferIsScheduled(pDevIns, pStream);
         Log3Func(("fSinksActive=%RTbool, fTimerScheduled=%RTbool\n", fSinkActive, fTimerScheduled));
         if (!fTimerScheduled)
-            hdaR3TimerSet(pThis, pStream,
-                            TMTimerGet(pThis->pTimer[pStream->u8SD])
-                          + TMTimerGetFreq(pThis->pTimer[pStream->u8SD]) / pStream->pHDAState->uTimerHz,
+            hdaR3TimerSet(pDevIns, pThis, pStream,
+                            PDMDevHlpTimerGet(pDevIns, hTimer)
+                          + PDMDevHlpTimerGetFreq(pDevIns, hTimer) / pStream->pHDAState->uTimerHz,
                           true /* fForce */);
     }
@@ -3595,7 +3585,8 @@
  * Does required post processing when loading a saved state.
  *
+ * @param   pDevIns             The device instance.
  * @param   pThis               Pointer to HDA state.
  */
-static int hdaR3LoadExecPost(PHDASTATE pThis)
+static int hdaR3LoadExecPost(PPDMDEVINS pDevIns, PHDASTATE pThis)
 {
     int rc = VINF_SUCCESS;
@@ -3637,6 +3628,6 @@
                 hdaR3StreamRegisterDMAHandlers(pThis, pStream);
 #endif
-                if (hdaR3StreamTransferIsScheduled(pStream))
-                    hdaR3TimerSet(pThis, pStream, hdaR3StreamTransferGetNext(pStream), true /* fForce */);
+                if (hdaR3StreamTransferIsScheduled(pDevIns, pStream))
+                    hdaR3TimerSet(pDevIns, pThis, pStream, hdaR3StreamTransferGetNext(pStream), true /* fForce */);
 
                 /* Also keep track of the currently active streams. */
@@ -3749,5 +3740,5 @@
             /* Output */
             PHDASTREAM pStream = &pThis->aStreams[4];
-            rc = hdaR3StreamInit(pStream, 4 /* Stream descriptor, hardcoded */);
+            rc = hdaR3StreamInit(pDevIns, pStream, 4 /* Stream descriptor, hardcoded */);
             AssertRCReturn(rc, rc);
             rc = pHlp->pfnSSMGetStructEx(pSSM, &pStream->State.BDLE, sizeof(pStream->State.BDLE),
@@ -3758,5 +3749,5 @@
             /* Microphone-In */
             pStream = &pThis->aStreams[2];
-            rc = hdaR3StreamInit(pStream, 2 /* Stream descriptor, hardcoded */);
+            rc = hdaR3StreamInit(pDevIns, pStream, 2 /* Stream descriptor, hardcoded */);
             AssertRCReturn(rc, rc);
             rc = pHlp->pfnSSMGetStructEx(pSSM, &pStream->State.BDLE, sizeof(pStream->State.BDLE),
@@ -3767,5 +3758,5 @@
             /* Line-In */
             pStream = &pThis->aStreams[0];
-            rc = hdaR3StreamInit(pStream, 0 /* Stream descriptor, hardcoded */);
+            rc = hdaR3StreamInit(pDevIns, pStream, 0 /* Stream descriptor, hardcoded */);
             AssertRCReturn(rc, rc);
             rc = pHlp->pfnSSMGetStructEx(pSSM, &pStream->State.BDLE, sizeof(pStream->State.BDLE),
@@ -3805,5 +3796,5 @@
                 }
 
-                rc = hdaR3StreamInit(pStream, idStream);
+                rc = hdaR3StreamInit(pDevIns, pStream, idStream);
                 if (RT_FAILURE(rc))
                 {
@@ -3908,5 +3899,5 @@
         rc = hdaR3LoadExecLegacy(pDevIns, pThis, pSSM, uVersion);
         if (RT_SUCCESS(rc))
-            rc = hdaR3LoadExecPost(pThis);
+            rc = hdaR3LoadExecPost(pDevIns, pThis);
         return rc;
     }
@@ -3982,5 +3973,5 @@
         }
 
-        rc = hdaR3StreamInit(pStream, idStream);
+        rc = hdaR3StreamInit(pDevIns, pStream, idStream);
         if (RT_FAILURE(rc))
         {
@@ -4073,5 +4064,5 @@
     } /* for cStreams */
 
-    rc = hdaR3LoadExecPost(pThis);
+    rc = hdaR3LoadExecPost(pDevIns, pThis);
     AssertRC(rc);
 
@@ -4961,5 +4952,12 @@
 
     /*
-     * Create all hardware streams.
+     * Create the per stream timers and the asso.
+     *
+     * We must the critical section for the timers as the device has a
+     * noop section associated with it.
+     *
+     * Note:  Use TMCLOCK_VIRTUAL_SYNC here, as the guest's HDA driver relies
+     *        on exact (virtual) DMA timing and uses DMA Position Buffers
+     *        instead of the LPIB registers.
      */
     static const char * const s_apszNames[] =
@@ -4969,21 +4967,19 @@
     };
     AssertCompile(RT_ELEMENTS(s_apszNames) == HDA_MAX_STREAMS);
+    for (size_t i = 0; i < HDA_MAX_STREAMS; i++)
+    {
+        rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hdaR3Timer, &pThis->aStreams[i],
+                                  TMTIMER_FLAGS_NO_CRIT_SECT, s_apszNames[i], &pThis->ahTimers[i]);
+        AssertRCReturn(rc, rc);
+
+        rc = PDMDevHlpTimerSetCritSect(pDevIns, pThis->ahTimers[i], &pThis->CritSect);
+        AssertRCReturn(rc, rc);
+    }
+
+    /*
+     * Create all hardware streams.
+     */
     for (uint8_t i = 0; i < HDA_MAX_STREAMS; ++i)
     {
-        /* Create the emulation timer (per stream).
-         *
-         * Note:  Use TMCLOCK_VIRTUAL_SYNC here, as the guest's HDA driver
-         *        relies on exact (virtual) DMA timing and uses DMA Position Buffers
-         *        instead of the LPIB registers.
-         */
-        rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hdaR3Timer, &pThis->aStreams[i],
-                                    TMTIMER_FLAGS_NO_CRIT_SECT, s_apszNames[i], &pThis->pTimer[i]);
-        AssertRCReturn(rc, rc);
-
-        /* Use our own critcal section for the device timer.
-         * That way we can control more fine-grained when to lock what. */
-        rc = TMR3TimerSetCritSect(pThis->pTimer[i], &pThis->CritSect);
-        AssertRCReturn(rc, rc);
-
         rc = hdaR3StreamCreate(&pThis->aStreams[i], pThis, i /* u8SD */);
         AssertRCReturn(rc, rc);
Index: /trunk/src/VBox/Devices/Audio/DevHDA.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevHDA.h	(revision 82330)
+++ /trunk/src/VBox/Devices/Audio/DevHDA.h	(revision 82331)
@@ -138,6 +138,7 @@
     /** Number of active (running) SDn streams. */
     uint8_t                 cStreamsActive;
-    /** The stream timers for pumping data thru the attached LUN drivers. */
-    PTMTIMERR3              pTimer[HDA_MAX_STREAMS];
+    /** The stream timers for pumping data thru the attached LUN drivers.
+     * Duplicated in HDASTREAM::hTimer. */
+    TMTIMERHANDLE           ahTimers[HDA_MAX_STREAMS];
     /** Pointer to HDA codec to use. */
     R3PTRTYPE(PHDACODEC)    pCodec;
Index: /trunk/src/VBox/Devices/Audio/DevHDACommon.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevHDACommon.cpp	(revision 82330)
+++ /trunk/src/VBox/Devices/Audio/DevHDACommon.cpp	(revision 82331)
@@ -2,4 +2,6 @@
 /** @file
  * DevHDACommon.cpp - Shared HDA device functions.
+ *
+ * @todo r=bird: Shared with whom exactly?
  */
 
@@ -662,8 +664,9 @@
  *
  * @returns Whether the new expiration time was set or not.
- * @param   pThis               HDA state.
- * @param   pStream             HDA stream to set timer for.
- * @param   tsExpire            New (virtual) expiration time to set.
- * @param   fForce              Whether to force setting the expiration time or not.
+ * @param   pDevIns     The device instance.
+ * @param   pThis       HDA state.
+ * @param   pStream     HDA stream to set timer for.
+ * @param   tsExpire    New (virtual) expiration time to set.
+ * @param   fForce      Whether to force setting the expiration time or not.
  *
  * @remark  This function takes all active HDA streams and their
@@ -676,8 +679,8 @@
  *          Forcing a new expiration time will override the above mechanism.
  */
-bool hdaR3TimerSet(PHDASTATE pThis, PHDASTREAM pStream, uint64_t tsExpire, bool fForce)
-{
-    AssertPtrReturn(pThis, false);
-    AssertPtrReturn(pStream, false);
+bool hdaR3TimerSet(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStream, uint64_t tsExpire, bool fForce)
+{
+    AssertPtr(pThis);
+    AssertPtr(pStream);
 
     uint64_t tsExpireMin = tsExpire;
@@ -685,11 +688,16 @@
     if (!fForce)
     {
-        if (hdaR3StreamTransferIsScheduled(pStream))
-            tsExpireMin = RT_MIN(tsExpireMin, hdaR3StreamTransferGetNext(pStream));
-    }
-
-    AssertPtr(pThis->pTimer[pStream->u8SD]);
-
-    const uint64_t tsNow = TMTimerGet(pThis->pTimer[pStream->u8SD]);
+        /** @todo r=bird: hdaR3StreamTransferIsScheduled() also does a
+         * PDMDevHlpTimerGet(), so, some callers does one, this does, and then we do
+         * right afterwards == very inefficient! */
+        if (hdaR3StreamTransferIsScheduled(pDevIns, pStream))
+        {
+            uint64_t const tsNext = hdaR3StreamTransferGetNext(pStream);
+            if (tsExpireMin > tsNext)
+                tsExpireMin = tsNext;
+        }
+    }
+
+    const uint64_t tsNow = PDMDevHlpTimerGet(pDevIns, pStream->hTimer);
 
     /*
@@ -700,8 +708,8 @@
         tsExpireMin = tsNow;
 
-    int rc = TMTimerSet(pThis->pTimer[pStream->u8SD], tsExpireMin);
-    AssertRC(rc);
-
-    return RT_SUCCESS(rc);
+    int rc = PDMDevHlpTimerSet(pDevIns, pStream->hTimer, tsExpireMin);
+    AssertRCReturn(rc, false);
+
+    return true;
 }
 
Index: /trunk/src/VBox/Devices/Audio/DevHDACommon.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevHDACommon.h	(revision 82330)
+++ /trunk/src/VBox/Devices/Audio/DevHDACommon.h	(revision 82331)
@@ -653,6 +653,6 @@
  */
 #ifdef IN_RING3
-bool          hdaR3TimerSet(PHDASTATE pThis, PHDASTREAM pStream, uint64_t u64Expire, bool fForce);
-#endif /* IN_RING3 */
+bool          hdaR3TimerSet(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStream, uint64_t u64Expire, bool fForce);
+#endif
 /** @} */
 
Index: /trunk/src/VBox/Devices/Audio/HDAStream.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/HDAStream.cpp	(revision 82330)
+++ /trunk/src/VBox/Devices/Audio/HDAStream.cpp	(revision 82331)
@@ -54,6 +54,5 @@
     pStream->pMixSink       = NULL;
     pStream->pHDAState      = pThis;
-    pStream->pTimer         = pThis->pTimer[u8SD];
-    AssertPtr(pStream->pTimer);
+    pStream->hTimer         = pThis->ahTimers[u8SD];
 
     pStream->State.fInReset = false;
@@ -189,8 +188,9 @@
  * @returns IPRT status code. VINF_NO_CHANGE if the stream does not need (re-)initialization because the stream's (hardware)
  *          parameters did not change.
- * @param   pStream             HDA stream to initialize.
- * @param   uSD                 SD (stream descriptor) number to assign the HDA stream to.
- */
-int hdaR3StreamInit(PHDASTREAM pStream, uint8_t uSD)
+ * @param   pDevIns The device instance.
+ * @param   pStream HDA stream to initialize.
+ * @param   uSD     SD (stream descriptor) number to assign the HDA stream to.
+ */
+int hdaR3StreamInit(PPDMDEVINS pDevIns, PHDASTREAM pStream, uint8_t uSD)
 {
     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
@@ -464,5 +464,5 @@
                     pStream->State.cbTransferChunk = pStream->State.cbTransferSize;
 
-                const uint64_t cTicksPerHz = TMTimerGetFreq(pStream->pTimer) / pStream->State.uTimerHz;
+                const uint64_t cTicksPerHz = PDMDevHlpTimerGetFreq(pDevIns, pStream->hTimer) / pStream->State.uTimerHz;
 
                 /* Calculate the timer ticks per byte for this stream. */
@@ -715,11 +715,13 @@
 /**
  * Returns whether a next transfer for a given stream is scheduled or not.
+ *
  * This takes pending stream interrupts into account as well as the next scheduled
  * transfer timestamp.
  *
  * @returns True if a next transfer is scheduled, false if not.
+ * @param   pDevIns             The device instance.
  * @param   pStream             HDA stream to retrieve schedule status for.
  */
-bool hdaR3StreamTransferIsScheduled(PHDASTREAM pStream)
+bool hdaR3StreamTransferIsScheduled(PPDMDEVINS pDevIns, PHDASTREAM pStream)
 {
     if (pStream)
@@ -735,5 +737,5 @@
             }
 
-            const uint64_t tsNow = TMTimerGet(pStream->pTimer);
+            const uint64_t tsNow = PDMDevHlpTimerGet(pDevIns, pStream->hTimer);
             if (pStream->State.tsTransferNext > tsNow)
             {
@@ -908,8 +910,9 @@
  *
  * @returns IPRT status code.
+ * @param   pDevIns             The device instance.
  * @param   pStream             HDA stream to update.
  * @param   cbToProcessMax      How much data (in bytes) to process as maximum.
  */
-int hdaR3StreamTransfer(PHDASTREAM pStream, uint32_t cbToProcessMax)
+int hdaR3StreamTransfer(PPDMDEVINS pDevIns, PHDASTREAM pStream, uint32_t cbToProcessMax)
 {
     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
@@ -945,5 +948,5 @@
     }
 
-    const uint64_t tsNow = TMTimerGet(pStream->pTimer);
+    const uint64_t tsNow = PDMDevHlpTimerGet(pDevIns, pStream->hTimer);
 
     if (!pStream->State.tsTransferLast)
@@ -1376,5 +1379,5 @@
 
         LogFunc(("Timer set SD%RU8\n", pStream->u8SD));
-        hdaR3TimerSet(pStream->pHDAState, pStream, tsTransferNext, false /* fForce */);
+        hdaR3TimerSet(pDevIns, pStream->pHDAState, pStream, tsTransferNext, false /* fForce */);
 
         pStream->State.tsTransferNext = tsTransferNext;
@@ -1413,9 +1416,10 @@
  * (with fInTimer set to @c false).
  *
- * @param   pStream             HDA stream to update.
- * @param   fInTimer            Whether to this function was called from the timer
- *                              context or an asynchronous I/O stream thread (if supported).
- */
-void hdaR3StreamUpdate(PHDASTREAM pStream, bool fInTimer)
+ * @param   pDevIns     The device instance.
+ * @param   pStream     HDA stream to update.
+ * @param   fInTimer    Whether to this function was called from the timer
+ *                      context or an asynchronous I/O stream thread (if supported).
+ */
+void hdaR3StreamUpdate(PPDMDEVINS pDevIns, PHDASTREAM pStream, bool fInTimer)
 {
     if (!pStream)
@@ -1446,5 +1450,5 @@
             {
                 /* Do the DMA transfer. */
-                rc2 = hdaR3StreamTransfer(pStream, cbStreamFree);
+                rc2 = hdaR3StreamTransfer(pDevIns, pStream, cbStreamFree);
                 AssertRC(rc2);
             }
@@ -1567,5 +1571,5 @@
             if (cbStreamUsed)
             {
-                rc2 = hdaR3StreamTransfer(pStream, cbStreamUsed);
+                rc2 = hdaR3StreamTransfer(pDevIns, pStream, cbStreamUsed);
                 AssertRC(rc2);
             }
@@ -1823,9 +1827,10 @@
     PHDASTREAMTHREADCTX pCtx = (PHDASTREAMTHREADCTX)pvUser;
     AssertPtr(pCtx);
-
     PHDASTREAM pStream = pCtx->pStream;
+
     AssertPtr(pStream);
-
-    PHDASTREAMSTATEAIO pAIO = &pCtx->pStream->State.AIO;
+    PHDASTREAMSTATEAIO pAIO = &pStream->State.AIO;
+
+    PPDMDEVINS pDevIns = pCtx->pThis->pDevInsR3;
 
     ASMAtomicXchgBool(&pAIO->fStarted, true);
@@ -1853,5 +1858,5 @@
             }
 
-            hdaR3StreamUpdate(pStream, false /* fInTimer */);
+            hdaR3StreamUpdate(pDevIns, pStream, false /* fInTimer */);
 
             int rc3 = RTCritSectLeave(&pAIO->CritSect);
Index: /trunk/src/VBox/Devices/Audio/HDAStream.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/HDAStream.h	(revision 82330)
+++ /trunk/src/VBox/Devices/Audio/HDAStream.h	(revision 82331)
@@ -188,16 +188,16 @@
 
 /**
- * Structure for keeping a HDA stream (SDI / SDO).
+ * An HDA stream (SDI / SDO).
  *
- * Note: This HDA stream has nothing to do with a regular audio stream handled
- * by the audio connector or the audio mixer. This HDA stream is a serial data in/out
- * stream (SDI/SDO) defined in hardware and can contain multiple audio streams
- * in one single SDI/SDO (interleaving streams).
+ * @note This HDA stream has nothing to do with a regular audio stream handled
+ *       by the audio connector or the audio mixer. This HDA stream is a serial
+ *       data in/out stream (SDI/SDO) defined in hardware and can contain
+ *       multiple audio streams in one single SDI/SDO (interleaving streams).
  *
  * How a specific SDI/SDO is mapped to our internal audio streams relies on the
  * stream channel mappings.
  *
- * Contains only register values which do *not* change until a
- * stream reset occurs.
+ * Contains only register values which do *not* change until a stream reset
+ * occurs.
  */
 typedef struct HDASTREAM
@@ -235,13 +235,15 @@
     /** Pointer to HDA sink this stream is attached to. */
     R3PTRTYPE(PHDAMIXERSINK) pMixSink;
+    /** Stream's timer (copy of HDASTATE::ahTimers[u8SD]). */
+    TMTIMERHANDLE            hTimer;
     /** The stream'S critical section to serialize access. */
     RTCRITSECT               CritSect;
-    /** Pointer to the stream's timer. */
-    PTMTIMERR3               pTimer;
     /** Internal state of this stream. */
     HDASTREAMSTATE           State;
     /** Debug information. */
     HDASTREAMDBGINFO         Dbg;
-} HDASTREAM, *PHDASTREAM;
+} HDASTREAM;
+/** Pointer to an HDA stream (SDI / SDO).  */
+typedef HDASTREAM *PHDASTREAM;
 
 #ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
@@ -263,5 +265,5 @@
 int               hdaR3StreamCreate(PHDASTREAM pStream, PHDASTATE pThis, uint8_t u8SD);
 void              hdaR3StreamDestroy(PHDASTREAM pStream);
-int               hdaR3StreamInit(PHDASTREAM pStream, uint8_t uSD);
+int               hdaR3StreamInit(PPDMDEVINS pDevIns, PHDASTREAM pStream, uint8_t uSD);
 void              hdaR3StreamReset(PHDASTATE pThis, PHDASTREAM pStream, uint8_t uSD);
 int               hdaR3StreamEnable(PHDASTREAM pStream, bool fEnable);
@@ -270,12 +272,12 @@
 uint32_t          hdaR3StreamGetFree(PHDASTREAM pStream);
 uint32_t          hdaR3StreamGetUsed(PHDASTREAM pStream);
-bool              hdaR3StreamTransferIsScheduled(PHDASTREAM pStream);
+bool              hdaR3StreamTransferIsScheduled(PPDMDEVINS pDevIns, PHDASTREAM pStream);
 uint64_t          hdaR3StreamTransferGetNext(PHDASTREAM pStream);
-int               hdaR3StreamTransfer(PHDASTREAM pStream, uint32_t cbToProcessMax);
+int               hdaR3StreamTransfer(PPDMDEVINS pDevIns, PHDASTREAM pStream, uint32_t cbToProcessMax);
 void              hdaR3StreamLock(PHDASTREAM pStream);
 void              hdaR3StreamUnlock(PHDASTREAM pStream);
 int               hdaR3StreamRead(PHDASTREAM pStream, uint32_t cbToRead, uint32_t *pcbRead);
 int               hdaR3StreamWrite(PHDASTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten);
-void              hdaR3StreamUpdate(PHDASTREAM pStream, bool fAsync);
+void              hdaR3StreamUpdate(PPDMDEVINS pDevIns, PHDASTREAM pStream, bool fAsync);
 # ifdef HDA_USE_DMA_ACCESS_HANDLER
 bool              hdaR3StreamRegisterDMAHandlers(PHDASTREAM pStream);
