Index: /trunk/src/VBox/Devices/Audio/DevHDA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevHDA.cpp	(revision 82344)
+++ /trunk/src/VBox/Devices/Audio/DevHDA.cpp	(revision 82345)
@@ -155,7 +155,7 @@
  * Acquires the TM lock and HDA lock, returns on failure.
  */
-#define DEVHDA_LOCK_BOTH_RETURN(a_pDevIns, a_pThis, a_SD, a_rcBusy) \
+#define DEVHDA_LOCK_BOTH_RETURN(a_pDevIns, a_pThis, a_pStream, a_rcBusy) \
     do { \
-        VBOXSTRICTRC rcLock = PDMDevHlpTimerLockClock2(pDevIns, (a_pThis)->ahTimers[a_SD], &(a_pThis)->CritSect,  (a_rcBusy)); \
+        VBOXSTRICTRC rcLock = PDMDevHlpTimerLockClock2(pDevIns, (a_pStream)->hTimer, &(a_pThis)->CritSect,  (a_rcBusy)); \
         if (RT_LIKELY(rcLock == VINF_SUCCESS)) \
         {  /* likely */ } \
@@ -167,6 +167,6 @@
  * Releases the HDA lock and TM lock.
  */
-#define DEVHDA_UNLOCK_BOTH(a_pDevIns, a_pThis, a_SD) \
-    PDMDevHlpTimerUnlockClock2(pDevIns, (a_pThis)->ahTimers[a_SD], &(a_pThis)->CritSect)
+#define DEVHDA_UNLOCK_BOTH(a_pDevIns, a_pThis, a_pStream) \
+    PDMDevHlpTimerUnlockClock2(pDevIns, (a_pStream)->hTimer, &(a_pThis)->CritSect)
 
 
@@ -1302,5 +1302,5 @@
      *               clock lock here!
      */
-    DEVHDA_LOCK_BOTH_RETURN(pDevIns, pThis, uSD, VINF_IOM_R3_MMIO_WRITE);
+    DEVHDA_LOCK_BOTH_RETURN(pDevIns, pThis, pStream, VINF_IOM_R3_MMIO_WRITE);
 
     const bool fInRun    = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_SDCTL_RUN);
@@ -1457,5 +1457,5 @@
     AssertRC(rc2);
 
-    DEVHDA_UNLOCK_BOTH(pDevIns, pThis, uSD);
+    DEVHDA_UNLOCK_BOTH(pDevIns, pThis, pStream);
     return VINF_SUCCESS; /* Always return success to the MMIO handler. */
 #else  /* !IN_RING3 */
@@ -1477,5 +1477,5 @@
      *               clock lock here!
      */
-    DEVHDA_LOCK_BOTH_RETURN(pDevIns, pThis, uSD, VINF_IOM_R3_MMIO_WRITE);
+    DEVHDA_LOCK_BOTH_RETURN(pDevIns, pThis, pStream, VINF_IOM_R3_MMIO_WRITE);
 
     hdaR3StreamLock(pStream);
@@ -1572,5 +1572,5 @@
     hdaR3StreamUnlock(pStream);
 
-    DEVHDA_UNLOCK_BOTH(pDevIns, pThis, uSD);
+    DEVHDA_UNLOCK_BOTH(pDevIns, pThis, pStream);
     return VINF_SUCCESS;
 #else  /* !IN_RING3 */
@@ -2842,5 +2842,5 @@
     PHDASTATE       pThis   = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
     PHDASTREAM      pStream = (PHDASTREAM)pvUser;
-    TMTIMERHANDLE   hTimer  = RT_SAFE_SUBSCRIPT8(pThis->ahTimers, pStream->u8SD);
+    TMTIMERHANDLE   hTimer  = pStream->hTimer;
     RT_NOREF(pTimer);
 
@@ -4967,8 +4967,8 @@
     {
         rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hdaR3Timer, &pThis->aStreams[i],
-                                  TMTIMER_FLAGS_NO_CRIT_SECT, s_apszNames[i], &pThis->ahTimers[i]);
+                                  TMTIMER_FLAGS_NO_CRIT_SECT, s_apszNames[i], &pThis->aStreams[i].hTimer);
         AssertRCReturn(rc, rc);
 
-        rc = PDMDevHlpTimerSetCritSect(pDevIns, pThis->ahTimers[i], &pThis->CritSect);
+        rc = PDMDevHlpTimerSetCritSect(pDevIns, pThis->aStreams[i].hTimer, &pThis->CritSect);
         AssertRCReturn(rc, rc);
     }
Index: /trunk/src/VBox/Devices/Audio/DevHDA.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevHDA.h	(revision 82344)
+++ /trunk/src/VBox/Devices/Audio/DevHDA.h	(revision 82345)
@@ -138,7 +138,4 @@
     /** Number of active (running) SDn streams. */
     uint8_t                 cStreamsActive;
-    /** 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/DevIchAc97.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 82344)
+++ /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 82345)
@@ -412,4 +412,6 @@
     uint32_t              Padding1;
 #endif
+    /** The timer for pumping data thru the attached LUN drivers. */
+    TMTIMERHANDLE           hTimer;
     /** Debug stuff. */
     AC97STREAMDEBUG         Dbg;
@@ -501,9 +503,4 @@
     /** R3 pointer to the device instance. */
     PPDMDEVINSR3            pDevInsR3;
-//    /** R0 pointer to the device instance. */
-//    PPDMDEVINSR0            pDevInsR0;
-//    /** RC pointer to the device instance. */
-//    PPDMDEVINSRC            pDevInsRC;
-//    bool                    afPadding0[4];
     /** Global Control (Bus Master Control Register). */
     uint32_t                glob_cnt;
@@ -519,6 +516,4 @@
     uint16_t                uTimerHz;
     uint16_t                au16Padding1[3];
-    /** The timer for pumping data thru the attached LUN drivers. */
-    TMTIMERHANDLE           ahTimers[AC97_MAX_STREAMS];
     /** List of associated LUN drivers (AC97DRIVER). */
     RTLISTANCHORR3          lstDrv;
@@ -589,8 +584,7 @@
  * Acquires the TM lock and AC'97 lock, returns on failure.
  */
-#define DEVAC97_LOCK_BOTH_RETURN(a_pDevIns, a_pThis, a_SD, a_rcBusy) \
+#define DEVAC97_LOCK_BOTH_RETURN(a_pDevIns, a_pThis, a_pStream, a_rcBusy) \
     do { \
-        VBOXSTRICTRC rcLock = PDMDevHlpTimerLockClock2((a_pDevIns), RT_SAFE_SUBSCRIPT8((a_pThis)->ahTimers, (a_SD)), \
-                                                       &(a_pThis)->CritSect, (a_rcBusy)); \
+        VBOXSTRICTRC rcLock = PDMDevHlpTimerLockClock2((a_pDevIns), (a_pStream)->hTimer, &(a_pThis)->CritSect, (a_rcBusy)); \
         if (RT_LIKELY(rcLock == VINF_SUCCESS)) \
         { /* likely */ } \
@@ -605,6 +599,6 @@
  * Releases the AC'97 lock and TM lock.
  */
-#define DEVAC97_UNLOCK_BOTH(a_pDevIns, a_pThis, a_SD) \
-    PDMDevHlpTimerUnlockClock2((a_pDevIns), RT_SAFE_SUBSCRIPT8((a_pThis)->ahTimers, (a_SD)), &(a_pThis)->CritSect)
+#define DEVAC97_UNLOCK_BOTH(a_pDevIns, a_pThis, a_pStream) \
+    PDMDevHlpTimerUnlockClock2((a_pDevIns), (a_pStream)->hTimer, &(a_pThis)->CritSect)
 
 #ifdef VBOX_WITH_STATISTICS
@@ -659,5 +653,5 @@
 static void               ichac97R3BDLEDumpAll(PAC97STATE pThis, uint64_t u64BDLBase, uint16_t cBDLE);
 # endif
-DECLINLINE(void)          ichac97R3TimerSet(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream, uint64_t cTicksToDeadline);
+DECLINLINE(void)          ichac97R3TimerSet(PPDMDEVINS pDevIns, PAC97STREAM pStream, uint64_t cTicksToDeadline);
 #endif /* IN_RING3 */
 
@@ -953,4 +947,5 @@
 
     int rc = RTCritSectInit(&pStream->State.CritSect);
+    AssertRCReturn(rc, rc);
 
     pStream->Dbg.Runtime.fEnabled = pThis->Dbg.fEnabled;
@@ -1948,9 +1943,8 @@
  * @returns Calculated ticks
  * @param   pDevIns             The device instance.
- * @param   pThis               AC'97 device state.
  * @param   pStream             AC'97 stream to calculate ticks for.
  * @param   cbBytes             Bytes to calculate ticks for.
  */
-static uint64_t ichac97R3StreamTransferCalcNext(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbBytes)
+static uint64_t ichac97R3StreamTransferCalcNext(PPDMDEVINS pDevIns, PAC97STREAM pStream, uint32_t cbBytes)
 {
     if (!cbBytes)
@@ -1958,5 +1952,5 @@
 
     const uint64_t usBytes        = DrvAudioHlpBytesToMicro(cbBytes, &pStream->State.Cfg.Props);
-    const uint64_t cTransferTicks = PDMDevHlpTimerFromMicro(pDevIns, RT_SAFE_SUBSCRIPT8(pThis->ahTimers, pStream->u8SD), usBytes);
+    const uint64_t cTransferTicks = PDMDevHlpTimerFromMicro(pDevIns, pStream->hTimer, usBytes);
 
     Log3Func(("[SD%RU8] Timer %uHz, cbBytes=%RU32 -> usBytes=%RU64, cTransferTicks=%RU64\n",
@@ -1970,9 +1964,8 @@
  *
  * @param   pDevIns             The device instance.
- * @param   pThis               AC'97 device state.
  * @param   pStream             AC'97 stream to update.
  * @param   cbBytes             Bytes to update next transfer for.
  */
-static void ichac97R3StreamTransferUpdate(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbBytes)
+static void ichac97R3StreamTransferUpdate(PPDMDEVINS pDevIns, PAC97STREAM pStream, uint32_t cbBytes)
 {
     if (!cbBytes)
@@ -1984,5 +1977,5 @@
 
     /* Update the transfer ticks. */
-    pStream->State.cTransferTicks = ichac97R3StreamTransferCalcNext(pDevIns, pThis, pStream, pStream->State.cbTransferChunk);
+    pStream->State.cTransferTicks = ichac97R3StreamTransferCalcNext(pDevIns, pStream, pStream->State.cbTransferChunk);
     Assert(pStream->State.cTransferTicks); /* Paranoia. */
 }
@@ -2626,5 +2619,5 @@
     AssertPtr(pStream);
     Assert(PDMDevHlpCritSectIsOwner(pDevIns, &pThis->CritSect));
-    Assert(PDMDevHlpTimerIsLockOwner(pDevIns, RT_SAFE_SUBSCRIPT8(pThis->ahTimers, pStream->u8SD)));
+    Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pStream->hTimer));
 
     ichac97R3StreamUpdate(pDevIns, pThis, pStream, true /* fInTimer */);
@@ -2633,6 +2626,6 @@
     if (pSink && AudioMixerSinkIsActive(pSink))
     {
-        ichac97R3StreamTransferUpdate(pDevIns, pThis, pStream, pStream->Regs.picb << 1); /** @todo r=andy Assumes 16-bit samples. */
-        ichac97R3TimerSet(pDevIns, pThis, pStream, pStream->State.cTransferTicks);
+        ichac97R3StreamTransferUpdate(pDevIns, pStream, pStream->Regs.picb << 1); /** @todo r=andy Assumes 16-bit samples. */
+        ichac97R3TimerSet(pDevIns, pStream, pStream->State.cTransferTicks);
     }
 
@@ -2651,8 +2644,7 @@
  * @remarks This used to be more complicated a long time ago...
  */
-DECLINLINE(void) ichac97R3TimerSet(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream, uint64_t cTicksToDeadline)
-{
-    int rc = PDMDevHlpTimerSetRelative(pDevIns, RT_SAFE_SUBSCRIPT8(pThis->ahTimers, pStream->u8SD),
-                                       cTicksToDeadline, NULL /*pu64Now*/);
+DECLINLINE(void) ichac97R3TimerSet(PPDMDEVINS pDevIns, PAC97STREAM pStream, uint64_t cTicksToDeadline)
+{
+    int rc = PDMDevHlpTimerSetRelative(pDevIns, pStream->hTimer, cTicksToDeadline, NULL /*pu64Now*/);
     AssertRC(rc);
 }
@@ -3056,5 +3048,5 @@
         pRegs   = &pStream->Regs;
 
-        DEVAC97_LOCK_BOTH_RETURN(pDevIns, pThis, pStream->u8SD, VINF_IOM_R3_IOPORT_WRITE);
+        DEVAC97_LOCK_BOTH_RETURN(pDevIns, pThis, pStream, VINF_IOM_R3_IOPORT_WRITE);
     }
 
@@ -3144,5 +3136,5 @@
                             /* Arm the timer for this stream. */
                             /** @todo r=bird: This function returns bool, not VBox status! */
-                            ichac97R3TimerSet(pDevIns, pThis, pStream, pStream->State.cTransferTicks);
+                            ichac97R3TimerSet(pDevIns, pStream, pStream->State.cTransferTicks);
                         }
                     }
@@ -3229,5 +3221,5 @@
 
     if (pStream)
-        DEVAC97_UNLOCK_BOTH(pDevIns, pThis, pStream->u8SD);
+        DEVAC97_UNLOCK_BOTH(pDevIns, pThis, pStream);
 
     return rc;
@@ -3637,6 +3629,5 @@
         {
             /* Re-arm the timer for this stream. */
-            /** @todo r=bird: This function returns bool, not VBox status! */
-            ichac97R3TimerSet(pDevIns, pThis, pStream, pStream->State.cTransferTicks);
+            ichac97R3TimerSet(pDevIns, pStream, pStream->State.cTransferTicks);
         }
 
@@ -4139,11 +4130,33 @@
      * Create all hardware streams.
      */
+    AssertCompile(RT_ELEMENTS(pThis->aStreams) == AC97_MAX_STREAMS);
     for (unsigned i = 0; i < AC97_MAX_STREAMS; i++)
     {
-        int rc2 = ichac97R3StreamCreate(pThis, &pThis->aStreams[i], i /* SD# */);
-        AssertRC(rc2);
-        if (RT_SUCCESS(rc))
-            rc = rc2;
-    }
+        rc = ichac97R3StreamCreate(pThis, &pThis->aStreams[i], i /* SD# */);
+        AssertRCReturn(rc, rc);
+    }
+
+    /*
+     * Create the emulation timers (one per stream).
+     *
+     * 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 AC'97 driver
+     *        relies on exact (virtual) DMA timing and uses DMA Position Buffers
+     *        instead of the LPIB registers.
+     */
+    static const char * const s_apszNames[] = { "AC97 PI", "AC97 PO", "AC97 MC" };
+    AssertCompile(RT_ELEMENTS(s_apszNames) == AC97_MAX_STREAMS);
+    for (unsigned i = 0; i < AC97_MAX_STREAMS; i++)
+    {
+        rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, ichac97R3Timer, &pThis->aStreams[i],
+                                  TMTIMER_FLAGS_NO_CRIT_SECT, s_apszNames[i], &pThis->aStreams[i].hTimer);
+        AssertRCReturn(rc, rc);
+
+        rc = PDMDevHlpTimerSetCritSect(pDevIns, pThis->aStreams[i].hTimer, &pThis->CritSect);
+        AssertRCReturn(rc, rc);
+    }
+
 
 # ifdef VBOX_WITH_AUDIO_AC97_ONETIME_INIT
@@ -4243,27 +4256,4 @@
 
     ichac97R3Reset(pDevIns);
-
-    /*
-     * Create the emulation timers (one per stream).
-     *
-     * 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 AC'97 driver
-     *        relies on exact (virtual) DMA timing and uses DMA Position Buffers
-     *        instead of the LPIB registers.
-     */
-    static const char * const s_apszNames[] = { "AC97 PI", "AC97 PO", "AC97 MC" };
-    AssertCompile(RT_ELEMENTS(s_apszNames) == AC97_MAX_STREAMS);
-    AssertCompile(RT_ELEMENTS(pThis->ahTimers) == AC97_MAX_STREAMS);
-    for (unsigned i = 0; i < AC97_MAX_STREAMS; i++)
-    {
-        rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, ichac97R3Timer, &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);
-    }
 
     /*
Index: /trunk/src/VBox/Devices/Audio/HDAStream.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/HDAStream.cpp	(revision 82344)
+++ /trunk/src/VBox/Devices/Audio/HDAStream.cpp	(revision 82345)
@@ -54,5 +54,5 @@
     pStream->pMixSink       = NULL;
     pStream->pHDAState      = pThis;
-    pStream->hTimer         = pThis->ahTimers[u8SD];
+    Assert(pStream->hTimer != NIL_TMTIMERHANDLE); /* hdaR3Construct initalized this one already. */
 
     pStream->State.fInReset = false;
Index: /trunk/src/VBox/Devices/Audio/HDAStream.h
===================================================================
--- /trunk/src/VBox/Devices/Audio/HDAStream.h	(revision 82344)
+++ /trunk/src/VBox/Devices/Audio/HDAStream.h	(revision 82345)
@@ -235,5 +235,5 @@
     /** Pointer to HDA sink this stream is attached to. */
     R3PTRTYPE(PHDAMIXERSINK) pMixSink;
-    /** Stream's timer (copy of HDASTATE::ahTimers[u8SD]). */
+    /** The timer for pumping data thru the attached LUN drivers. */
     TMTIMERHANDLE            hTimer;
     /** The stream'S critical section to serialize access. */
