Index: /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 82356)
+++ /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 82357)
@@ -396,5 +396,5 @@
 
 /**
- * An AC'97 stream.
+ * The shared AC'97 stream state.
  */
 typedef struct AC97STREAM
@@ -405,21 +405,30 @@
     /** Bus master registers of this stream. */
     AC97BMREGS              Regs;
+    /** The timer for pumping data thru the attached LUN drivers. */
+    TMTIMERHANDLE           hTimer;
+} AC97STREAM;
+AssertCompileSizeAlignment(AC97STREAM, 8);
+/** Pointer to a shared AC'97 stream state. */
+typedef AC97STREAM *PAC97STREAM;
+
+
+/**
+ * The ring-3 AC'97 stream state.
+ */
+typedef struct AC97STREAMR3
+{
+    /** Stream number (SDn). */
+    uint8_t                 u8SD;
+    uint8_t                 abPadding0[7];
     /** Internal state of this stream. */
     AC97STREAMSTATE         State;
-    /** Pointer to parent (AC'97 state). */
-    R3PTRTYPE(PAC97STATE)   pAC97State;
-#if HC_ARCH_BITS == 32
-    uint32_t                Padding1;
-#endif
-    /** The timer for pumping data thru the attached LUN drivers. */
-    TMTIMERHANDLE           hTimer;
     /** Debug stuff. */
     AC97STREAMDEBUG         Dbg;
-} AC97STREAM;
-AssertCompileSizeAlignment(AC97STREAM, 8);
-/** Pointer to an AC'97 stream (registers + state). */
-typedef AC97STREAM *PAC97STREAM;
-
-typedef struct AC97STATE *PAC97STATE;
+} AC97STREAMR3;
+AssertCompileSizeAlignment(AC97STREAMR3, 8);
+/** Pointer to an AC'97 stream state for ring-3. */
+typedef AC97STREAMR3 *PAC97STREAMR3;
+
+
 #ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
 /**
@@ -456,6 +465,4 @@
     /** Node for storing this driver in our device driver list of AC97STATE. */
     RTLISTNODER3                    Node;
-    /** Pointer to AC97 controller (state). */
-    R3PTRTYPE(PAC97STATE)           pAC97State;
     /** Driver flags. */
     PDMAUDIODRVFLAGS                fFlags;
@@ -501,6 +508,4 @@
     /** Critical section protecting the AC'97 state. */
     PDMCRITSECT             CritSect;
-    /** R3 pointer to the device instance. */
-    PPDMDEVINSR3            pDevInsR3;
     /** Global Control (Bus Master Control Register). */
     uint32_t                glob_cnt;
@@ -511,9 +516,39 @@
     uint32_t                last_samp;
     uint8_t                 mixer_data[256];
-    /** Array of AC'97 streams. */
+    /** Array of AC'97 streams (parallel to AC97STATER3::aStreams). */
     AC97STREAM              aStreams[AC97_MAX_STREAMS];
     /** The device timer Hz rate. Defaults to AC97_TIMER_HZ_DEFAULT_DEFAULT. */
     uint16_t                uTimerHz;
     uint16_t                au16Padding1[3];
+    uint8_t                 silence[128];
+    int32_t                 bup_flag;
+    /** Codec model. */
+    uint32_t                uCodecModel;
+
+    /** PCI region \#0: NAM I/O ports. */
+    IOMIOPORTHANDLE         hIoPortsNam;
+    /** PCI region \#0: NANM I/O ports. */
+    IOMIOPORTHANDLE         hIoPortsNabm;
+
+#ifdef VBOX_WITH_STATISTICS
+    STAMPROFILE             StatTimer;
+    STAMPROFILE             StatIn;
+    STAMPROFILE             StatOut;
+    STAMCOUNTER             StatBytesRead;
+    STAMCOUNTER             StatBytesWritten;
+#endif
+} AC97STATE;
+AssertCompileMemberAlignment(AC97STATE, aStreams, 8);
+
+
+/**
+ * The ring-3 AC'97 device state.
+ */
+typedef struct AC97STATER3
+{
+    /** Array of AC'97 streams (parallel to AC97STATE:aStreams). */
+    AC97STREAMR3            aStreams[AC97_MAX_STREAMS];
+    /** R3 pointer to the device instance. */
+    PPDMDEVINSR3            pDevIns;
     /** List of associated LUN drivers (AC97DRIVER). */
     RTLISTANCHORR3          lstDrv;
@@ -526,27 +561,12 @@
     /** Audio sink for microphone input. */
     R3PTRTYPE(PAUDMIXSINK)  pSinkMicIn;
-    uint8_t                 silence[128];
-    int32_t                 bup_flag;
-    /** Codec model. */
-    uint32_t                uCodecModel;
     /** The base interface for LUN\#0. */
     PDMIBASE                IBase;
     /** Debug settings. */
     AC97STATEDEBUG          Dbg;
-
-    /** PCI region \#0: NAM I/O ports. */
-    IOMIOPORTHANDLE         hIoPortsNam;
-    /** PCI region \#0: NANM I/O ports. */
-    IOMIOPORTHANDLE         hIoPortsNabm;
-
-#ifdef VBOX_WITH_STATISTICS
-    STAMPROFILE             StatTimer;
-    STAMPROFILE             StatIn;
-    STAMPROFILE             StatOut;
-    STAMCOUNTER             StatBytesRead;
-    STAMCOUNTER             StatBytesWritten;
-#endif
-} AC97STATE;
-AssertCompileMemberAlignment(AC97STATE, aStreams, 8);
+} AC97STATER3;
+AssertCompileMemberAlignment(AC97STATER3, aStreams, 8);
+/** Pointer to the ring-3 AC'97 device state. */
+typedef AC97STATER3 *PAC97STATER3;
 
 
@@ -616,15 +636,14 @@
 #ifdef IN_RING3
 static int                ichac97R3StreamCreate(PAC97STATE pThis, PAC97STREAM pStream, uint8_t u8Strm);
-static void               ichac97R3StreamDestroy(PAC97STATE pThis, PAC97STREAM pStream);
-static int                ichac97R3StreamOpen(PAC97STATE pThis, PAC97STREAM pStream, bool fForce);
-static int                ichac97R3StreamReOpen(PAC97STATE pThis, PAC97STREAM pStream, bool fForce);
-static int                ichac97R3StreamClose(PAC97STATE pThis, PAC97STREAM pStream);
-static void               ichac97R3StreamReset(PAC97STATE pThis, PAC97STREAM pStream);
-static void               ichac97R3StreamLock(PAC97STREAM pStream);
-static void               ichac97R3StreamUnlock(PAC97STREAM pStream);
-static uint32_t           ichac97R3StreamGetUsed(PAC97STREAM pStream);
-static uint32_t           ichac97R3StreamGetFree(PAC97STREAM pStream);
-static int                ichac97R3StreamTransfer(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbToProcessMax);
-static void               ichac97R3StreamUpdate(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream, bool fInTimer);
+static int                ichac97R3StreamOpen(PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fForce);
+static int                ichac97R3StreamClose(PAC97STREAM pStream);
+static void               ichac97R3StreamLock(PAC97STREAMR3 pStreamCC);
+static void               ichac97R3StreamUnlock(PAC97STREAMR3 pStreamCC);
+static uint32_t           ichac97R3StreamGetUsed(PAC97STREAMR3 pStreamCC);
+static uint32_t           ichac97R3StreamGetFree(PAC97STREAMR3 pStreamCC);
+static int                ichac97R3StreamTransfer(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream,
+                                                  PAC97STREAMR3 pStreamCC, uint32_t cbToProcessMax);
+static void               ichac97R3StreamUpdate(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream,
+                                                PAC97STREAMR3 pStreamCC, bool fInTimer);
 
 static DECLCALLBACK(void) ichac97R3Reset(PPDMDEVINS pDevIns);
@@ -632,15 +651,10 @@
 static DECLCALLBACK(void) ichac97R3Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser);
 
-static int                ichac97R3MixerAddDrv(PAC97STATE pThis, PAC97DRIVER pDrv);
-static int                ichac97R3MixerAddDrvStream(PAC97STATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PAC97DRIVER pDrv);
-static int                ichac97R3MixerAddDrvStreams(PAC97STATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg);
-static void               ichac97R3MixerRemoveDrv(PAC97STATE pThis, PAC97DRIVER pDrv);
-static void               ichac97R3MixerRemoveDrvStream(PAC97STATE pThis, PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc, PAC97DRIVER pDrv);
-static void               ichac97R3MixerRemoveDrvStreams(PAC97STATE pThis, PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc);
+static void               ichac97R3MixerRemoveDrvStreams(PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir,
+                                                         PDMAUDIODSTSRCUNION dstSrc);
 
 # ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
 static int                ichac97R3StreamAsyncIOCreate(PAC97STATE pThis, PAC97STREAM pStream);
 static int                ichac97R3StreamAsyncIODestroy(PAC97STATE pThis, PAC97STREAM pStream);
-static int                ichac97R3StreamAsyncIONotify(PAC97STATE pThis, PAC97STREAM pStream);
 static void               ichac97R3StreamAsyncIOLock(PAC97STREAM pStream);
 static void               ichac97R3StreamAsyncIOUnlock(PAC97STREAM pStream);
@@ -649,8 +663,4 @@
 
 DECLINLINE(PDMAUDIODIR)   ichac97GetDirFromSD(uint8_t uSD);
-
-# ifdef LOG_ENABLED
-static void               ichac97R3BDLEDumpAll(PAC97STATE pThis, uint64_t u64BDLBase, uint16_t cBDLE);
-# endif
 DECLINLINE(void)          ichac97R3TimerSet(PPDMDEVINS pDevIns, PAC97STREAM pStream, uint64_t cTicksToDeadline);
 #endif /* IN_RING3 */
@@ -672,19 +682,17 @@
  *
  * @returns Pointer to audio mixer sink if found, or NULL if not found / invalid.
- * @param   pThis               AC'97 state.
+ * @param   pThisCC             The ring-3 AC'97 state.
  * @param   uIndex              Stream index to get audio mixer sink for.
  */
-DECLINLINE(PAUDMIXSINK) ichac97R3IndexToSink(PAC97STATE pThis, uint8_t uIndex)
+DECLINLINE(PAUDMIXSINK) ichac97R3IndexToSink(PAC97STATER3 pThisCC, uint8_t uIndex)
 {
     switch (uIndex)
     {
-        case AC97SOUNDSOURCE_PI_INDEX: return pThis->pSinkLineIn;
-        case AC97SOUNDSOURCE_PO_INDEX: return pThis->pSinkOut;
-        case AC97SOUNDSOURCE_MC_INDEX: return pThis->pSinkMicIn;
-        default: break;
-    }
-
-    AssertMsgFailed(("Wrong index %RU8\n", uIndex));
-    return NULL;
+        case AC97SOUNDSOURCE_PI_INDEX: return pThisCC->pSinkLineIn;
+        case AC97SOUNDSOURCE_PO_INDEX: return pThisCC->pSinkOut;
+        case AC97SOUNDSOURCE_MC_INDEX: return pThisCC->pSinkMicIn;
+        default:
+            AssertMsgFailedReturn(("Wrong index %RU8\n", uIndex), NULL);
+    }
 }
 
@@ -693,13 +701,12 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
+ * @param   pDevIns             The device instance.
  * @param   pStream             AC'97 stream to fetch BDLE for.
  *
  * @remark  Uses CIV as BDLE index.
  */
-static void ichac97R3StreamFetchBDLE(PAC97STATE pThis, PAC97STREAM pStream)
-{
-    PPDMDEVINS  pDevIns = ICHAC97STATE_2_DEVINS(pThis);
-    PAC97BMREGS pRegs   = &pStream->Regs;
+static void ichac97R3StreamFetchBDLE(PPDMDEVINS pDevIns, PAC97STREAM pStream)
+{
+    PAC97BMREGS pRegs = &pStream->Regs;
 
     AC97BDLE BDLE;
@@ -727,5 +734,5 @@
  *
  * @param   pDevIns             The device instance.
- * @param   pThis               AC'97 state.
+ * @param   pThis               The shared AC'97 state.
  * @param   pStream             AC'97 stream to update SR for.
  * @param   new_sr              New value for status register (SR).
@@ -784,5 +791,5 @@
  *
  * @param   pDevIns             The device instance.
- * @param   pThis               AC'97 device state.
+ * @param   pThis               The shared AC'97 device state.
  * @param   pStream             Stream to update SR for.
  * @param   u32Val              New value to set the stream's SR to.
@@ -804,10 +811,10 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 device state.
+ * @param   pThisCC             The ring-3 AC'97 device state.
  * @param   pStream             Stream to return status for.
  */
-static bool ichac97R3StreamIsEnabled(PAC97STATE pThis, PAC97STREAM pStream)
-{
-    PAUDMIXSINK pSink = ichac97R3IndexToSink(pThis, pStream->u8SD);
+static bool ichac97R3StreamIsEnabled(PAC97STATER3 pThisCC, PAC97STREAM pStream)
+{
+    PAUDMIXSINK pSink = ichac97R3IndexToSink(pThisCC, pStream->u8SD);
     bool fIsEnabled = RT_BOOL(AudioMixerSinkGetStatus(pSink) & AUDMIXSINK_STS_RUNNING);
 
@@ -820,12 +827,16 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
- * @param   pStream             AC'97 stream to enable or disable.
+ * @param   pThis               The shared AC'97 state.
+ * @param   pThisCC             The ring-3 AC'97 state.
+ * @param   pStream             The AC'97 stream to enable or disable (shared
+ *                              state).
+ * @param   pStreamCC           The ring-3 stream state (matching to @a pStream).
  * @param   fEnable             Whether to enable or disable the stream.
  *
  */
-static int ichac97R3StreamEnable(PAC97STATE pThis, PAC97STREAM pStream, bool fEnable)
-{
-    ichac97R3StreamLock(pStream);
+static int ichac97R3StreamEnable(PAC97STATE pThis, PAC97STATER3 pThisCC,
+                                 PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fEnable)
+{
+    ichac97R3StreamLock(pStreamCC);
 
     int rc = VINF_SUCCESS;
@@ -840,22 +851,24 @@
     if (fEnable)
     {
-        if (pStream->State.pCircBuf)
-            RTCircBufReset(pStream->State.pCircBuf);
-
-        rc = ichac97R3StreamOpen(pThis, pStream, false /* fForce */);
-
-        if (pStream->Dbg.Runtime.fEnabled)
-        {
-            if (!DrvAudioHlpFileIsOpen(pStream->Dbg.Runtime.pFileStream))
+        if (pStreamCC->State.pCircBuf)
+            RTCircBufReset(pStreamCC->State.pCircBuf);
+
+        rc = ichac97R3StreamOpen(pThis, pThisCC, pStream, pStreamCC, false /* fForce */);
+
+        if (RT_LIKELY(!pStreamCC->Dbg.Runtime.fEnabled))
+        { /* likely */ }
+        else
+        {
+            if (!DrvAudioHlpFileIsOpen(pStreamCC->Dbg.Runtime.pFileStream))
             {
-                int rc2 = DrvAudioHlpFileOpen(pStream->Dbg.Runtime.pFileStream, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS,
-                                              &pStream->State.Cfg.Props);
+                int rc2 = DrvAudioHlpFileOpen(pStreamCC->Dbg.Runtime.pFileStream, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS,
+                                              &pStreamCC->State.Cfg.Props);
                 AssertRC(rc2);
             }
 
-            if (!DrvAudioHlpFileIsOpen(pStream->Dbg.Runtime.pFileDMA))
+            if (!DrvAudioHlpFileIsOpen(pStreamCC->Dbg.Runtime.pFileDMA))
             {
-                int rc2 = DrvAudioHlpFileOpen(pStream->Dbg.Runtime.pFileDMA, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS,
-                                              &pStream->State.Cfg.Props);
+                int rc2 = DrvAudioHlpFileOpen(pStreamCC->Dbg.Runtime.pFileDMA, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS,
+                                              &pStreamCC->State.Cfg.Props);
                 AssertRC(rc2);
             }
@@ -863,10 +876,10 @@
     }
     else
-        rc = ichac97R3StreamClose(pThis, pStream);
+        rc = ichac97R3StreamClose(pStream);
 
     if (RT_SUCCESS(rc))
     {
         /* First, enable or disable the stream and the stream's sink, if any. */
-        rc = AudioMixerSinkCtl(ichac97R3IndexToSink(pThis, pStream->u8SD),
+        rc = AudioMixerSinkCtl(ichac97R3IndexToSink(pThisCC, pStream->u8SD),
                                fEnable ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE);
     }
@@ -877,5 +890,5 @@
 
     /* Make sure to leave the lock before (eventually) starting the timer. */
-    ichac97R3StreamUnlock(pStream);
+    ichac97R3StreamUnlock(pStreamCC);
 
     LogFunc(("[SD%RU8] fEnable=%RTbool, rc=%Rrc\n", pStream->u8SD, fEnable, rc));
@@ -886,16 +899,16 @@
  * Resets an AC'97 stream.
  *
- * @param   pThis               AC'97 state.
- * @param   pStream             AC'97 stream to reset.
- *
- */
-static void ichac97R3StreamReset(PAC97STATE pThis, PAC97STREAM pStream)
-{
-    ichac97R3StreamLock(pStream);
+ * @param   pThis               The shared AC'97 state.
+ * @param   pStream             The AC'97 stream to reset (shared).
+ * @param   pStreamCC           The AC'97 stream to reset (ring-3).
+ */
+static void ichac97R3StreamReset(PAC97STATE pThis, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC)
+{
+    ichac97R3StreamLock(pStreamCC);
 
     LogFunc(("[SD%RU8]\n", pStream->u8SD));
 
-    if (pStream->State.pCircBuf)
-        RTCircBufReset(pStream->State.pCircBuf);
+    if (pStreamCC->State.pCircBuf)
+        RTCircBufReset(pStreamCC->State.pCircBuf);
 
     PAC97BMREGS pRegs = &pStream->Regs;
@@ -912,5 +925,5 @@
     RT_ZERO(pThis->silence);
 
-    ichac97R3StreamUnlock(pStream);
+    ichac97R3StreamUnlock(pStreamCC);
 }
 
@@ -919,24 +932,25 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
- * @param   pStream             AC'97 stream to create.
+ * @param   pThisCC             The ring-3 AC'97 state.
+ * @param   pStream             The AC'97 stream to create (shared).
+ * @param   pStreamCC           The AC'97 stream to create (ring-3).
  * @param   u8SD                Stream descriptor number to assign.
  */
-static int ichac97R3StreamCreate(PAC97STATE pThis, PAC97STREAM pStream, uint8_t u8SD)
-{
-    RT_NOREF(pThis);
-
+static int ichac97R3StreamCreate(PAC97STATER3 pThisCC, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, uint8_t u8SD)
+{
     LogFunc(("[SD%RU8] pStream=%p\n", u8SD, pStream));
 
     AssertReturn(u8SD < AC97_MAX_STREAMS, VERR_INVALID_PARAMETER);
     pStream->u8SD       = u8SD;
-    pStream->pAC97State = pThis;
-
-    int rc = RTCritSectInit(&pStream->State.CritSect);
+    pStreamCC->u8SD     = u8SD;
+
+    int rc = RTCritSectInit(&pStreamCC->State.CritSect);
     AssertRCReturn(rc, rc);
 
-    pStream->Dbg.Runtime.fEnabled = pThis->Dbg.fEnabled;
-
-    if (pStream->Dbg.Runtime.fEnabled)
+    pStreamCC->Dbg.Runtime.fEnabled = pThisCC->Dbg.fEnabled;
+
+    if (RT_LIKELY(!pStreamCC->Dbg.Runtime.fEnabled))
+    { /* likely */ }
+    else
     {
         char szFile[64];
@@ -948,8 +962,8 @@
 
         char szPath[RTPATH_MAX];
-        int rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThis->Dbg.szOutPath, szFile,
+        int rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThisCC->Dbg.szOutPath, szFile,
                                          0 /* uInst */, PDMAUDIOFILETYPE_WAV, PDMAUDIOFILENAME_FLAGS_NONE);
         AssertRC(rc2);
-        rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAGS_NONE, &pStream->Dbg.Runtime.pFileStream);
+        rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAGS_NONE, &pStreamCC->Dbg.Runtime.pFileStream);
         AssertRC(rc2);
 
@@ -959,14 +973,14 @@
             RTStrPrintf(szFile, sizeof(szFile), "ac97DMAReadSD%RU8", pStream->u8SD);
 
-        rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThis->Dbg.szOutPath, szFile,
+        rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThisCC->Dbg.szOutPath, szFile,
                                      0 /* uInst */, PDMAUDIOFILETYPE_WAV, PDMAUDIOFILENAME_FLAGS_NONE);
         AssertRC(rc2);
 
-        rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAGS_NONE, &pStream->Dbg.Runtime.pFileDMA);
+        rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAGS_NONE, &pStreamCC->Dbg.Runtime.pFileDMA);
         AssertRC(rc2);
 
         /* Delete stale debugging files from a former run. */
-        DrvAudioHlpFileDelete(pStream->Dbg.Runtime.pFileStream);
-        DrvAudioHlpFileDelete(pStream->Dbg.Runtime.pFileDMA);
+        DrvAudioHlpFileDelete(pStreamCC->Dbg.Runtime.pFileStream);
+        DrvAudioHlpFileDelete(pStreamCC->Dbg.Runtime.pFileDMA);
     }
 
@@ -978,14 +992,15 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
- * @param   pStream             AC'97 stream to destroy.
- */
-static void ichac97R3StreamDestroy(PAC97STATE pThis, PAC97STREAM pStream)
+ * @param   pThis               The shared AC'97 state.
+ * @param   pStream             The AC'97 stream to destroy (shared).
+ * @param   pStreamCC           The AC'97 stream to destroy (ring-3).
+ */
+static void ichac97R3StreamDestroy(PAC97STATE pThis, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC)
 {
     LogFlowFunc(("[SD%RU8]\n", pStream->u8SD));
 
-    ichac97R3StreamClose(pThis, pStream);
-
-    int rc2 = RTCritSectDelete(&pStream->State.CritSect);
+    ichac97R3StreamClose(pStream);
+
+    int rc2 = RTCritSectDelete(&pStreamCC->State.CritSect);
     AssertRC(rc2);
 
@@ -997,17 +1012,19 @@
 # endif
 
-    if (pStream->Dbg.Runtime.fEnabled)
-    {
-        DrvAudioHlpFileDestroy(pStream->Dbg.Runtime.pFileStream);
-        pStream->Dbg.Runtime.pFileStream = NULL;
-
-        DrvAudioHlpFileDestroy(pStream->Dbg.Runtime.pFileDMA);
-        pStream->Dbg.Runtime.pFileDMA = NULL;
-    }
-
-    if (pStream->State.pCircBuf)
-    {
-        RTCircBufDestroy(pStream->State.pCircBuf);
-        pStream->State.pCircBuf = NULL;
+    if (RT_LIKELY(!pStreamCC->Dbg.Runtime.fEnabled))
+    { /* likely */ }
+    else
+    {
+        DrvAudioHlpFileDestroy(pStreamCC->Dbg.Runtime.pFileStream);
+        pStreamCC->Dbg.Runtime.pFileStream = NULL;
+
+        DrvAudioHlpFileDestroy(pStreamCC->Dbg.Runtime.pFileDMA);
+        pStreamCC->Dbg.Runtime.pFileDMA = NULL;
+    }
+
+    if (pStreamCC->State.pCircBuf)
+    {
+        RTCircBufDestroy(pStreamCC->State.pCircBuf);
+        pStreamCC->State.pCircBuf = NULL;
     }
 
@@ -1018,7 +1035,8 @@
  * Destroys all AC'97 audio streams of the device.
  *
- * @param   pThis               AC'97 state.
- */
-static void ichac97R3StreamsDestroy(PAC97STATE pThis)
+ * @param   pThis               The shared AC'97 state.
+ * @param   pThisCC             The ring-3 AC'97 state.
+ */
+static void ichac97R3StreamsDestroy(PAC97STATE pThis, PAC97STATER3 pThisCC)
 {
     LogFlowFuncEnter();
@@ -1028,5 +1046,5 @@
      */
     for (unsigned i = 0; i < AC97_MAX_STREAMS; i++)
-        ichac97R3StreamDestroy(pThis, &pThis->aStreams[i]);
+        ichac97R3StreamDestroy(pThis, &pThis->aStreams[i], &pThisCC->aStreams[i]);
 
     /*
@@ -1035,29 +1053,29 @@
 
     PDMAUDIODSTSRCUNION dstSrc;
-    if (pThis->pSinkLineIn)
+    if (pThisCC->pSinkLineIn)
     {
         dstSrc.enmSrc = PDMAUDIORECSRC_LINE;
-        ichac97R3MixerRemoveDrvStreams(pThis, pThis->pSinkLineIn, PDMAUDIODIR_IN, dstSrc);
-
-        AudioMixerSinkDestroy(pThis->pSinkLineIn);
-        pThis->pSinkLineIn = NULL;
-    }
-
-    if (pThis->pSinkMicIn)
+        ichac97R3MixerRemoveDrvStreams(pThisCC, pThisCC->pSinkLineIn, PDMAUDIODIR_IN, dstSrc);
+
+        AudioMixerSinkDestroy(pThisCC->pSinkLineIn);
+        pThisCC->pSinkLineIn = NULL;
+    }
+
+    if (pThisCC->pSinkMicIn)
     {
         dstSrc.enmSrc = PDMAUDIORECSRC_MIC;
-        ichac97R3MixerRemoveDrvStreams(pThis, pThis->pSinkMicIn, PDMAUDIODIR_IN, dstSrc);
-
-        AudioMixerSinkDestroy(pThis->pSinkMicIn);
-        pThis->pSinkMicIn = NULL;
-    }
-
-    if (pThis->pSinkOut)
+        ichac97R3MixerRemoveDrvStreams(pThisCC, pThisCC->pSinkMicIn, PDMAUDIODIR_IN, dstSrc);
+
+        AudioMixerSinkDestroy(pThisCC->pSinkMicIn);
+        pThisCC->pSinkMicIn = NULL;
+    }
+
+    if (pThisCC->pSinkOut)
     {
         dstSrc.enmDst = PDMAUDIOPLAYBACKDST_FRONT;
-        ichac97R3MixerRemoveDrvStreams(pThis, pThis->pSinkOut, PDMAUDIODIR_OUT, dstSrc);
-
-        AudioMixerSinkDestroy(pThis->pSinkOut);
-        pThis->pSinkOut = NULL;
+        ichac97R3MixerRemoveDrvStreams(pThisCC, pThisCC->pSinkOut, PDMAUDIODIR_OUT, dstSrc);
+
+        AudioMixerSinkDestroy(pThisCC->pSinkOut);
+        pThisCC->pSinkOut = NULL;
     }
 }
@@ -1067,25 +1085,22 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
- * @param   pDstStream          AC'97 stream to write to.
+ * @param   pDstStreamCC        The AC'97 stream to write to (ring-3).
  * @param   pSrcMixSink         Mixer sink to get audio data to write from.
  * @param   cbToWrite           Number of bytes to write.
  * @param   pcbWritten          Number of bytes written. Optional.
  */
-static int ichac97R3StreamWrite(PAC97STATE pThis, PAC97STREAM pDstStream, PAUDMIXSINK pSrcMixSink, uint32_t cbToWrite,
-                                uint32_t *pcbWritten)
-{
-    RT_NOREF(pThis);
+static int ichac97R3StreamWrite(PAC97STREAMR3 pDstStreamCC, PAUDMIXSINK pSrcMixSink, uint32_t cbToWrite, uint32_t *pcbWritten)
+{
+    AssertPtrReturn(pSrcMixSink, VERR_INVALID_POINTER);
     AssertReturn(cbToWrite > 0,  VERR_INVALID_PARAMETER);
     /* pcbWritten is optional. */
 
-    PRTCIRCBUF pCircBuf = pDstStream->State.pCircBuf;
+    PRTCIRCBUF pCircBuf = pDstStreamCC->State.pCircBuf;
     AssertPtr(pCircBuf);
 
-    void *pvDst;
-    size_t cbDst;
-
     uint32_t cbRead = 0;
 
+    void    *pvDst;
+    size_t   cbDst;
     RTCircBufAcquireWriteBlock(pCircBuf, cbToWrite, &pvDst, &cbDst);
 
@@ -1095,6 +1110,8 @@
         AssertRC(rc2);
 
-        if (pDstStream->Dbg.Runtime.fEnabled)
-            DrvAudioHlpFileWrite(pDstStream->Dbg.Runtime.pFileStream, pvDst, cbRead, 0 /* fFlags */);
+        if (RT_LIKELY(!pDstStreamCC->Dbg.Runtime.fEnabled))
+        { /* likely */ }
+        else
+            DrvAudioHlpFileWrite(pDstStreamCC->Dbg.Runtime.pFileStream, pvDst, cbRead, 0 /* fFlags */);
     }
 
@@ -1111,18 +1128,16 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
- * @param   pSrcStream          AC'97 stream to read audio data from.
+ * @param   pSrcStreamCC        AC'97 stream to read audio data from (ring-3).
  * @param   pDstMixSink         Mixer sink to write audio data to.
  * @param   cbToRead            Number of bytes to read.
  * @param   pcbRead             Number of bytes read. Optional.
  */
-static int ichac97R3StreamRead(PAC97STATE pThis, PAC97STREAM pSrcStream, PAUDMIXSINK pDstMixSink, uint32_t cbToRead,
-                               uint32_t *pcbRead)
-{
-    RT_NOREF(pThis);
+static int ichac97R3StreamRead(PAC97STREAMR3 pSrcStreamCC, PAUDMIXSINK pDstMixSink, uint32_t cbToRead, uint32_t *pcbRead)
+{
+    AssertPtrReturn(pDstMixSink, VERR_INVALID_POINTER);
     AssertReturn(cbToRead > 0, VERR_INVALID_PARAMETER);
     /* pcbRead is optional. */
 
-    PRTCIRCBUF pCircBuf = pSrcStream->State.pCircBuf;
+    PRTCIRCBUF pCircBuf = pSrcStreamCC->State.pCircBuf;
     AssertPtr(pCircBuf);
 
@@ -1143,6 +1158,8 @@
         if (cbSrc)
         {
-            if (pSrcStream->Dbg.Runtime.fEnabled)
-                DrvAudioHlpFileWrite(pSrcStream->Dbg.Runtime.pFileStream, pvSrc, cbSrc, 0 /* fFlags */);
+            if (RT_LIKELY(!pSrcStreamCC->Dbg.Runtime.fEnabled))
+            { /* likely */ }
+            else
+                DrvAudioHlpFileWrite(pSrcStreamCC->Dbg.Runtime.pFileStream, pvSrc, cbSrc, 0 /* fFlags */);
 
             rc = AudioMixerSinkWrite(pDstMixSink, AUDMIXOP_COPY, pvSrc, (uint32_t)cbSrc, &cbWritten);
@@ -1150,5 +1167,5 @@
 
             Assert(cbSrc >= cbWritten);
-            Log3Func(("[SD%RU8] %RU32/%zu bytes read\n", pSrcStream->u8SD, cbWritten, cbSrc));
+            Log3Func(("[SD%RU8] %RU32/%zu bytes read\n", pSrcStreamCC->u8SD, cbWritten, cbSrc));
         }
 
@@ -1192,5 +1209,5 @@
     AssertPtr(pStream);
 
-    PAC97STREAMSTATEAIO pAIO = &pCtx->pStream->State.AIO;
+    PAC97STREAMSTATEAIO pAIO = &pCtx->pStreamCC->State.AIO;
 
     ASMAtomicXchgBool(&pAIO->fStarted, true);
@@ -1224,5 +1241,5 @@
             }
 
-            ichac97R3StreamUpdate(pDevIns, pThis, pStream, false /* fInTimer */);
+            ichac97R3StreamUpdate(pDevIns, pThis, pThisCC, pStream, pStreamCC, false /* fInTimer */);
 
             int rc3 = RTCritSectLeave(&pAIO->CritSect);
@@ -1244,10 +1261,10 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
+ * @param   pThis               The shared AC'97 state.
  * @param   pStream             AC'97 audio stream to create the async I/O thread for.
  */
 static int ichac97R3StreamAsyncIOCreate(PAC97STATE pThis, PAC97STREAM pStream)
 {
-    PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO;
+    PAC97STREAMSTATEAIO pAIO = &pStreamCC->State.AIO;
 
     int rc;
@@ -1298,13 +1315,26 @@
 
 /**
+ * Lets the stream's async I/O thread know that there is some data to process.
+ *
+ * @returns IPRT status code.
+ * @param   pStreamCC             The AC'97 stream to notify async I/O thread
+ *                                for (ring-3).
+ */
+static int ichac97R3StreamAsyncIONotify(PAC97STREAM pStreamCC)
+{
+    LogFunc(("[SD%RU8]\n", pStreamCC->u8SD));
+    return RTSemEventSignal(pStreamCC->State.AIO.Event);
+}
+
+/**
  * Destroys the async I/O thread of a specific AC'97 audio stream.
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
+ * @param   pThis               The shared AC'97 state.
  * @param   pStream             AC'97 audio stream to destroy the async I/O thread for.
  */
 static int ichac97R3StreamAsyncIODestroy(PAC97STATE pThis, PAC97STREAM pStream)
 {
-    PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO;
+    PAC97STREAMSTATEAIO pAIO = &pStreamCC->State.AIO;
 
     if (!ASMAtomicReadBool(&pAIO->fStarted))
@@ -1313,5 +1343,5 @@
     ASMAtomicWriteBool(&pAIO->fShutdown, true);
 
-    int rc = ichac97R3StreamAsyncIONotify(pThis, pStream);
+    int rc = ichac97R3StreamAsyncIONotify(pStreamCC);
     AssertRC(rc);
 
@@ -1338,19 +1368,4 @@
 
 /**
- * Lets the stream's async I/O thread know that there is some data to process.
- *
- * @returns IPRT status code.
- * @param   pThis               AC'97 state.
- * @param   pStream             AC'97 stream to notify async I/O thread for.
- */
-static int ichac97R3StreamAsyncIONotify(PAC97STATE pThis, PAC97STREAM pStream)
-{
-    RT_NOREF(pThis);
-
-    LogFunc(("[SD%RU8]\n", pStream->u8SD));
-    return RTSemEventSignal(pStream->State.AIO.Event);
-}
-
-/**
  * Locks the async I/O thread of a specific AC'97 audio stream.
  *
@@ -1359,5 +1374,5 @@
 static void ichac97R3StreamAsyncIOLock(PAC97STREAM pStream)
 {
-    PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO;
+    PAC97STREAMSTATEAIO pAIO = &pStreamCC->State.AIO;
 
     if (!ASMAtomicReadBool(&pAIO->fStarted))
@@ -1375,5 +1390,5 @@
 static void ichac97R3StreamAsyncIOUnlock(PAC97STREAM pStream)
 {
-    PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO;
+    PAC97STREAMSTATEAIO pAIO = &pStreamCC->State.AIO;
 
     if (!ASMAtomicReadBool(&pAIO->fStarted))
@@ -1395,5 +1410,5 @@
 static void ichac97R3StreamAsyncIOEnable(PAC97STREAM pStream, bool fEnable)
 {
-    PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO;
+    PAC97STREAMSTATEAIO pAIO = &pStreamCC->State.AIO;
     ASMAtomicXchgBool(&pAIO->fEnabled, fEnable);
 }
@@ -1402,5 +1417,5 @@
 
 # ifdef LOG_ENABLED
-static void ichac97R3BDLEDumpAll(PAC97STATE pThis, uint64_t u64BDLBase, uint16_t cBDLE)
+static void ichac97R3BDLEDumpAll(PPDMDEVINS pDevIns, uint64_t u64BDLBase, uint16_t cBDLE)
 {
     LogFlowFunc(("BDLEs @ 0x%x (%RU16):\n", u64BDLBase, cBDLE));
@@ -1412,5 +1427,5 @@
     {
         AC97BDLE BDLE;
-        PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), u64BDLBase + i * sizeof(AC97BDLE), &BDLE, sizeof(AC97BDLE));
+        PDMDevHlpPhysRead(pDevIns, u64BDLBase + i * sizeof(AC97BDLE), &BDLE, sizeof(AC97BDLE));
 
 # ifndef RT_LITTLE_ENDIAN
@@ -1450,14 +1465,17 @@
  *
  * @param   pDevIns             The device instance.
- * @param   pThis               AC'97 state.
- * @param   pStream             AC'97 stream to update.
+ * @param   pThis               The shared AC'97 state.
+ * @param   pThisCC             The ring-3 AC'97 state.
+ * @param   pStream             The AC'97 stream to update (shared).
+ * @param   pStreamCC           The AC'97 stream to update (ring-3).
  * @param   fInTimer            Whether to this function was called from the timer
  *                              context or an asynchronous I/O stream thread (if supported).
  */
-static void ichac97R3StreamUpdate(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream, bool fInTimer)
+static void ichac97R3StreamUpdate(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATER3 pThisCC,
+                                  PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fInTimer)
 {
     RT_NOREF(fInTimer);
 
-    PAUDMIXSINK pSink = ichac97R3IndexToSink(pThis, pStream->u8SD);
+    PAUDMIXSINK pSink = ichac97R3IndexToSink(pThisCC, pStream->u8SD);
     AssertPtr(pSink);
 
@@ -1467,5 +1485,5 @@
     int rc2;
 
-    if (pStream->State.Cfg.enmDir == PDMAUDIODIR_OUT) /* Output (SDO). */
+    if (pStreamCC->State.Cfg.enmDir == PDMAUDIODIR_OUT) /* Output (SDO). */
     {
 # ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
@@ -1473,18 +1491,19 @@
 # endif
         {
-            const uint32_t cbStreamFree = ichac97R3StreamGetFree(pStream);
+            const uint32_t cbStreamFree = ichac97R3StreamGetFree(pStreamCC);
             if (cbStreamFree)
             {
                 Log3Func(("[SD%RU8] PICB=%zu (%RU64ms), cbFree=%zu (%RU64ms), cbTransferChunk=%zu (%RU64ms)\n",
                           pStream->u8SD,
-                          (pStream->Regs.picb << 1), DrvAudioHlpBytesToMilli((pStream->Regs.picb << 1), &pStream->State.Cfg.Props),
-                          cbStreamFree, DrvAudioHlpBytesToMilli(cbStreamFree, &pStream->State.Cfg.Props),
-                          pStream->State.cbTransferChunk, DrvAudioHlpBytesToMilli(pStream->State.cbTransferChunk, &pStream->State.Cfg.Props)));
+                          (pStream->Regs.picb << 1), DrvAudioHlpBytesToMilli((pStream->Regs.picb << 1), &pStreamCC->State.Cfg.Props),
+                          cbStreamFree, DrvAudioHlpBytesToMilli(cbStreamFree, &pStreamCC->State.Cfg.Props),
+                          pStreamCC->State.cbTransferChunk, DrvAudioHlpBytesToMilli(pStreamCC->State.cbTransferChunk, &pStreamCC->State.Cfg.Props)));
 
                 /* Do the DMA transfer. */
-                rc2 = ichac97R3StreamTransfer(pDevIns, pThis, pStream, RT_MIN(pStream->State.cbTransferChunk, cbStreamFree));
+                rc2 = ichac97R3StreamTransfer(pDevIns, pThis, pStream, pStreamCC,
+                                              RT_MIN(pStreamCC->State.cbTransferChunk, cbStreamFree));
                 AssertRC(rc2);
 
-                pStream->State.tsLastUpdateNs = RTTimeNanoTS();
+                pStreamCC->State.tsLastUpdateNs = RTTimeNanoTS();
             }
         }
@@ -1493,5 +1512,5 @@
 
 # ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
-        rc2 = ichac97R3StreamAsyncIONotify(pThis, pStream);
+        rc2 = ichac97R3StreamAsyncIONotify(pStreamCC);
         AssertRC(rc2);
 # endif
@@ -1502,5 +1521,5 @@
 # endif
             const uint32_t cbSinkWritable     = AudioMixerSinkGetWritable(pSink);
-            const uint32_t cbStreamReadable   = ichac97R3StreamGetUsed(pStream);
+            const uint32_t cbStreamReadable   = ichac97R3StreamGetUsed(pStreamCC);
             const uint32_t cbToReadFromStream = RT_MIN(cbStreamReadable, cbSinkWritable);
 
@@ -1510,5 +1529,5 @@
             {
                 /* Read (guest output) data and write it to the stream's sink. */
-                rc2 = ichac97R3StreamRead(pThis, pStream, pSink, cbToReadFromStream, NULL /* pcbRead */);
+                rc2 = ichac97R3StreamRead(pStreamCC, pSink, cbToReadFromStream, NULL /* pcbRead */);
                 AssertRC(rc2);
             }
@@ -1534,5 +1553,5 @@
 
             /* How much (guest input) data is available for writing at the moment for the AC'97 stream? */
-            uint32_t cbStreamFree = ichac97R3StreamGetFree(pStream);
+            uint32_t cbStreamFree = ichac97R3StreamGetFree(pStreamCC);
 
             Log3Func(("[SD%RU8] cbSinkReadable=%RU32, cbStreamFree=%RU32\n", pStream->u8SD, cbSinkReadable, cbStreamFree));
@@ -1546,5 +1565,5 @@
             {
                 /* Write (guest input) data to the stream which was read from stream's sink before. */
-                rc2 = ichac97R3StreamWrite(pThis, pStream, pSink, cbSinkReadable, NULL /* pcbWritten */);
+                rc2 = ichac97R3StreamWrite(pStreamCC, pSink, cbSinkReadable, NULL /* pcbWritten */);
                 AssertRC(rc2);
             }
@@ -1557,19 +1576,19 @@
 # ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
             const uint64_t tsNowNs = RTTimeNanoTS();
-            if (tsNowNs - pStream->State.tsLastUpdateNs >= pStream->State.Cfg.Device.cMsSchedulingHint * RT_NS_1MS)
+            if (tsNowNs - pStreamCC->State.tsLastUpdateNs >= pStreamCC->State.Cfg.Device.cMsSchedulingHint * RT_NS_1MS)
             {
-                rc2 = ichac97R3StreamAsyncIONotify(pThis, pStream);
+                rc2 = ichac97R3StreamAsyncIONotify(pStreamCC);
                 AssertRC(rc2);
 
-                pStream->State.tsLastUpdateNs = tsNowNs;
+                pStreamCC->State.tsLastUpdateNs = tsNowNs;
             }
 # endif
 
-            const uint32_t cbStreamUsed = ichac97R3StreamGetUsed(pStream);
+            const uint32_t cbStreamUsed = ichac97R3StreamGetUsed(pStreamCC);
             if (cbStreamUsed)
             {
                 /* When running synchronously, do the DMA data transfers here.
                  * Otherwise this will be done in the stream's async I/O thread. */
-                rc2 = ichac97R3StreamTransfer(pDevIns, pThis, pStream, cbStreamUsed);
+                rc2 = ichac97R3StreamTransfer(pDevIns, pThis, pStream, pStreamCC, cbStreamUsed);
                 AssertRC(rc2);
             }
@@ -1586,5 +1605,5 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
+ * @param   pThis               The shared AC'97 state.
  * @param   uMixerIdx           Mixer control to set value for.
  * @param   uVal                Value to set.
@@ -1606,5 +1625,5 @@
  *
  * @returns Retrieved mixer control value.
- * @param   pThis               AC'97 state.
+ * @param   pThis               The shared AC'97 state.
  * @param   uMixerIdx           Mixer control to get value for.
  */
@@ -1623,14 +1642,10 @@
  *
  * @returns Pointer to driver stream if found, or NULL if not found.
- * @param   pThis               AC'97 state.
  * @param   pDrv                Driver to retrieve driver stream for.
  * @param   enmDir              Stream direction to retrieve.
  * @param   dstSrc              Stream destination / source to retrieve.
  */
-static PAC97DRIVERSTREAM ichac97R3MixerGetDrvStream(PAC97STATE pThis, PAC97DRIVER pDrv,
-                                                    PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc)
-{
-    RT_NOREF(pThis);
-
+static PAC97DRIVERSTREAM ichac97R3MixerGetDrvStream(PAC97DRIVER pDrv, PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc)
+{
     PAC97DRIVERSTREAM pDrvStream = NULL;
 
@@ -1676,10 +1691,9 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
  * @param   pMixSink            Mixer sink to add driver stream to.
  * @param   pCfg                Stream configuration to use.
  * @param   pDrv                Driver stream to add.
  */
-static int ichac97R3MixerAddDrvStream(PAC97STATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PAC97DRIVER pDrv)
+static int ichac97R3MixerAddDrvStream(PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PAC97DRIVER pDrv)
 {
     AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
@@ -1699,5 +1713,5 @@
     int rc;
 
-    PAC97DRIVERSTREAM pDrvStream = ichac97R3MixerGetDrvStream(pThis, pDrv, pStreamCfg->enmDir, pStreamCfg->u);
+    PAC97DRIVERSTREAM pDrvStream = ichac97R3MixerGetDrvStream(pDrv, pStreamCfg->enmDir, pStreamCfg->u);
     if (pDrvStream)
     {
@@ -1758,9 +1772,9 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
+ * @param   pThis               The shared AC'97 state.
  * @param   pMixSink            Mixer sink to add stream to.
  * @param   pCfg                Stream configuration to use.
  */
-static int ichac97R3MixerAddDrvStreams(PAC97STATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg)
+static int ichac97R3MixerAddDrvStreams(PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg)
 {
     AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
@@ -1774,7 +1788,7 @@
 
     PAC97DRIVER pDrv;
-    RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node)
-    {
-        int rc2 = ichac97R3MixerAddDrvStream(pThis, pMixSink, pCfg, pDrv);
+    RTListForEach(&pThisCC->lstDrv, pDrv, AC97DRIVER, Node)
+    {
+        int rc2 = ichac97R3MixerAddDrvStream(pMixSink, pCfg, pDrv);
         if (RT_FAILURE(rc2))
             LogFunc(("Attaching stream failed with %Rrc\n", rc2));
@@ -1792,35 +1806,28 @@
  *
  * @return IPRT status code.
- * @param  pThis                AC'97 state.
- * @param  pDrv                 AC'97 driver to add.
- */
-static int ichac97R3MixerAddDrv(PAC97STATE pThis, PAC97DRIVER pDrv)
+ * @param  pThis                The ring-3 AC'97 device state.
+ * @param  pDrv                 The AC'97 driver to add.
+ */
+static int ichac97R3MixerAddDrv(PAC97STATER3 pThisCC, PAC97DRIVER pDrv)
 {
     int rc = VINF_SUCCESS;
 
-    if (DrvAudioHlpStreamCfgIsValid(&pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX].State.Cfg))
-    {
-        int rc2 = ichac97R3MixerAddDrvStream(pThis, pThis->pSinkLineIn,
-                                             &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX].State.Cfg, pDrv);
+    if (DrvAudioHlpStreamCfgIsValid(&pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX].State.Cfg))
+        rc = ichac97R3MixerAddDrvStream(pThisCC->pSinkLineIn, &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX].State.Cfg, pDrv);
+
+    if (DrvAudioHlpStreamCfgIsValid(&pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX].State.Cfg))
+    {
+        int rc2 = ichac97R3MixerAddDrvStream(pThisCC->pSinkOut, &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX].State.Cfg, pDrv);
         if (RT_SUCCESS(rc))
             rc = rc2;
     }
 
-    if (DrvAudioHlpStreamCfgIsValid(&pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX].State.Cfg))
-    {
-        int rc2 = ichac97R3MixerAddDrvStream(pThis, pThis->pSinkOut,
-                                             &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX].State.Cfg, pDrv);
+    if (DrvAudioHlpStreamCfgIsValid(&pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX].State.Cfg))
+    {
+        int rc2 = ichac97R3MixerAddDrvStream(pThisCC->pSinkMicIn, &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX].State.Cfg, pDrv);
         if (RT_SUCCESS(rc))
             rc = rc2;
     }
 
-    if (DrvAudioHlpStreamCfgIsValid(&pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX].State.Cfg))
-    {
-        int rc2 = ichac97R3MixerAddDrvStream(pThis, pThis->pSinkMicIn,
-                                             &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX].State.Cfg, pDrv);
-        if (RT_SUCCESS(rc))
-            rc = rc2;
-    }
-
     return rc;
 }
@@ -1830,15 +1837,15 @@
  * associated streams.
  *
- * @param pThis                 AC'97 state.
+ * @param pThis                 The ring-3 AC'97 device state.
  * @param pDrv                  AC'97 driver to remove.
  */
-static void ichac97R3MixerRemoveDrv(PAC97STATE pThis, PAC97DRIVER pDrv)
+static void ichac97R3MixerRemoveDrv(PAC97STATER3 pThisCC, PAC97DRIVER pDrv)
 {
     if (pDrv->MicIn.pMixStrm)
     {
-        if (AudioMixerSinkGetRecordingSource(pThis->pSinkMicIn) == pDrv->MicIn.pMixStrm)
-            AudioMixerSinkSetRecordingSource(pThis->pSinkMicIn, NULL);
-
-        AudioMixerSinkRemoveStream(pThis->pSinkMicIn,  pDrv->MicIn.pMixStrm);
+        if (AudioMixerSinkGetRecordingSource(pThisCC->pSinkMicIn) == pDrv->MicIn.pMixStrm)
+            AudioMixerSinkSetRecordingSource(pThisCC->pSinkMicIn, NULL);
+
+        AudioMixerSinkRemoveStream(pThisCC->pSinkMicIn,  pDrv->MicIn.pMixStrm);
         AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm);
         pDrv->MicIn.pMixStrm = NULL;
@@ -1847,8 +1854,8 @@
     if (pDrv->LineIn.pMixStrm)
     {
-        if (AudioMixerSinkGetRecordingSource(pThis->pSinkLineIn) == pDrv->LineIn.pMixStrm)
-            AudioMixerSinkSetRecordingSource(pThis->pSinkLineIn, NULL);
-
-        AudioMixerSinkRemoveStream(pThis->pSinkLineIn, pDrv->LineIn.pMixStrm);
+        if (AudioMixerSinkGetRecordingSource(pThisCC->pSinkLineIn) == pDrv->LineIn.pMixStrm)
+            AudioMixerSinkSetRecordingSource(pThisCC->pSinkLineIn, NULL);
+
+        AudioMixerSinkRemoveStream(pThisCC->pSinkLineIn, pDrv->LineIn.pMixStrm);
         AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm);
         pDrv->LineIn.pMixStrm = NULL;
@@ -1857,5 +1864,5 @@
     if (pDrv->Out.pMixStrm)
     {
-        AudioMixerSinkRemoveStream(pThis->pSinkOut,    pDrv->Out.pMixStrm);
+        AudioMixerSinkRemoveStream(pThisCC->pSinkOut,    pDrv->Out.pMixStrm);
         AudioMixerStreamDestroy(pDrv->Out.pMixStrm);
         pDrv->Out.pMixStrm = NULL;
@@ -1868,5 +1875,4 @@
  * Removes a driver stream from a specific mixer sink.
  *
- * @param   pThis               AC'97 state.
  * @param   pMixSink            Mixer sink to remove audio streams from.
  * @param   enmDir              Stream direction to remove.
@@ -1874,8 +1880,7 @@
  * @param   pDrv                Driver stream to remove.
  */
-static void ichac97R3MixerRemoveDrvStream(PAC97STATE pThis, PAUDMIXSINK pMixSink,
-                                          PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc, PAC97DRIVER pDrv)
-{
-    PAC97DRIVERSTREAM pDrvStream = ichac97R3MixerGetDrvStream(pThis, pDrv, enmDir, dstSrc);
+static void ichac97R3MixerRemoveDrvStream(PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc, PAC97DRIVER pDrv)
+{
+    PAC97DRIVERSTREAM pDrvStream = ichac97R3MixerGetDrvStream(pDrv, enmDir, dstSrc);
     if (pDrvStream)
     {
@@ -1893,10 +1898,10 @@
  * Removes all driver streams from a specific mixer sink.
  *
- * @param   pThis               AC'97 state.
+ * @param   pThis               The ring-3 AC'97 state.
  * @param   pMixSink            Mixer sink to remove audio streams from.
  * @param   enmDir              Stream direction to remove.
  * @param   dstSrc              Stream destination / source to remove.
  */
-static void ichac97R3MixerRemoveDrvStreams(PAC97STATE pThis, PAUDMIXSINK pMixSink,
+static void ichac97R3MixerRemoveDrvStreams(PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink,
                                            PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc)
 {
@@ -1904,7 +1909,7 @@
 
     PAC97DRIVER pDrv;
-    RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node)
-    {
-        ichac97R3MixerRemoveDrvStream(pThis, pMixSink, enmDir, dstSrc, pDrv);
+    RTListForEach(&pThisCC->lstDrv, pDrv, AC97DRIVER, Node)
+    {
+        ichac97R3MixerRemoveDrvStream(pMixSink, enmDir, dstSrc, pDrv);
     }
 }
@@ -1915,17 +1920,18 @@
  * @returns Calculated ticks
  * @param   pDevIns             The device instance.
- * @param   pStream             AC'97 stream to calculate ticks for.
+ * @param   pStream             AC'97 stream to calculate ticks for (shared).
+ * @param   pStreamCC           AC'97 stream to calculate ticks for (ring-3).
  * @param   cbBytes             Bytes to calculate ticks for.
  */
-static uint64_t ichac97R3StreamTransferCalcNext(PPDMDEVINS pDevIns, PAC97STREAM pStream, uint32_t cbBytes)
+static uint64_t ichac97R3StreamTransferCalcNext(PPDMDEVINS pDevIns, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, uint32_t cbBytes)
 {
     if (!cbBytes)
         return 0;
 
-    const uint64_t usBytes        = DrvAudioHlpBytesToMicro(cbBytes, &pStream->State.Cfg.Props);
+    const uint64_t usBytes        = DrvAudioHlpBytesToMicro(cbBytes, &pStreamCC->State.Cfg.Props);
     const uint64_t cTransferTicks = PDMDevHlpTimerFromMicro(pDevIns, pStream->hTimer, usBytes);
 
     Log3Func(("[SD%RU8] Timer %uHz, cbBytes=%RU32 -> usBytes=%RU64, cTransferTicks=%RU64\n",
-              pStream->u8SD, pStream->State.uTimerHz, cbBytes, usBytes, cTransferTicks));
+              pStream->u8SD, pStreamCC->State.uTimerHz, cbBytes, usBytes, cTransferTicks));
 
     return cTransferTicks;
@@ -1936,8 +1942,9 @@
  *
  * @param   pDevIns             The device instance.
- * @param   pStream             AC'97 stream to update.
+ * @param   pStream             The AC'97 stream to update (shared).
+ * @param   pStreamCC           The AC'97 stream to update (ring-3).
  * @param   cbBytes             Bytes to update next transfer for.
  */
-static void ichac97R3StreamTransferUpdate(PPDMDEVINS pDevIns, PAC97STREAM pStream, uint32_t cbBytes)
+static void ichac97R3StreamTransferUpdate(PPDMDEVINS pDevIns, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, uint32_t cbBytes)
 {
     if (!cbBytes)
@@ -1946,9 +1953,10 @@
     /* Calculate the bytes we need to transfer to / from the stream's DMA per iteration.
      * This is bound to the device's Hz rate and thus to the (virtual) timing the device expects. */
-    pStream->State.cbTransferChunk = cbBytes;
+    pStreamCC->State.cbTransferChunk = cbBytes;
 
     /* Update the transfer ticks. */
-    pStream->State.cTransferTicks = ichac97R3StreamTransferCalcNext(pDevIns, pStream, pStream->State.cbTransferChunk);
-    Assert(pStream->State.cTransferTicks); /* Paranoia. */
+    pStreamCC->State.cTransferTicks = ichac97R3StreamTransferCalcNext(pDevIns, pStream, pStreamCC,
+                                                                      pStreamCC->State.cbTransferChunk);
+    Assert(pStreamCC->State.cTransferTicks); /* Paranoia. */
 }
 
@@ -1960,18 +1968,15 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 device state.
- * @param   pStream             AC'97 stream to open.
+ * @param   pThis               The shared AC'97 device state (shared).
+ * @param   pThisCC             The shared AC'97 device state (ring-3).
+ * @param   pStream             The AC'97 stream to open (shared).
+ * @param   pStreamCC           The AC'97 stream to open (ring-3).
  * @param   fForce              Whether to force re-opening the stream or not.
  *                              Otherwise re-opening only will happen if the PCM properties have changed.
  */
-static int ichac97R3StreamOpen(PAC97STATE pThis, PAC97STREAM pStream, bool fForce)
-{
-    int rc = VINF_SUCCESS;
-
+static int ichac97R3StreamOpen(PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fForce)
+{
     PDMAUDIOSTREAMCFG Cfg;
     RT_ZERO(Cfg);
-
-    PAUDMIXSINK pMixSink = NULL;
-
     Cfg.Props.cChannels = 2;
     Cfg.Props.cbSample  = 2 /* 16-bit */;
@@ -1979,4 +1984,6 @@
     Cfg.Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(Cfg.Props.cbSample, Cfg.Props.cChannels);
 
+    int rc = VINF_SUCCESS;
+    PAUDMIXSINK pMixSink;
     switch (pStream->u8SD)
     {
@@ -1989,5 +1996,5 @@
             RTStrCopy(Cfg.szName, sizeof(Cfg.szName), "Line-In");
 
-            pMixSink        = pThis->pSinkLineIn;
+            pMixSink        = pThisCC->pSinkLineIn;
             break;
         }
@@ -2001,5 +2008,5 @@
             RTStrCopy(Cfg.szName, sizeof(Cfg.szName), "Mic-In");
 
-            pMixSink        = pThis->pSinkMicIn;
+            pMixSink        = pThisCC->pSinkMicIn;
             break;
         }
@@ -2013,5 +2020,5 @@
             RTStrCopy(Cfg.szName, sizeof(Cfg.szName), "Output");
 
-            pMixSink        = pThis->pSinkOut;
+            pMixSink        = pThisCC->pSinkOut;
             break;
         }
@@ -2019,4 +2026,5 @@
         default:
             rc = VERR_NOT_SUPPORTED;
+            pMixSink = NULL;
             break;
     }
@@ -2026,5 +2034,5 @@
         /* Only (re-)create the stream (and driver chain) if we really have to.
          * Otherwise avoid this and just reuse it, as this costs performance. */
-        if (   !DrvAudioHlpPCMPropsAreEqual(&Cfg.Props, &pStream->State.Cfg.Props)
+        if (   !DrvAudioHlpPCMPropsAreEqual(&Cfg.Props, &pStreamCC->State.Cfg.Props)
             || fForce)
         {
@@ -2044,29 +2052,29 @@
                 {
                     if (Cfg.Props.uHz > 44100) /* E.g. 48000 Hz. */
-                        pStream->State.uTimerHz = 200;
+                        pStreamCC->State.uTimerHz = 200;
                     else /* Just take the global Hz rate otherwise. */
-                        pStream->State.uTimerHz = pThis->uTimerHz;
+                        pStreamCC->State.uTimerHz = pThis->uTimerHz;
                 }
                 else
-                    pStream->State.uTimerHz = pThis->uTimerHz;
+                    pStreamCC->State.uTimerHz = pThis->uTimerHz;
 
                 /* Set scheduling hint (if available). */
-                if (pStream->State.uTimerHz)
-                    Cfg.Device.cMsSchedulingHint = 1000 /* ms */ / pStream->State.uTimerHz;
-
-                if (pStream->State.pCircBuf)
+                if (pStreamCC->State.uTimerHz)
+                    Cfg.Device.cMsSchedulingHint = 1000 /* ms */ / pStreamCC->State.uTimerHz;
+
+                if (pStreamCC->State.pCircBuf)
                 {
-                    RTCircBufDestroy(pStream->State.pCircBuf);
-                    pStream->State.pCircBuf = NULL;
+                    RTCircBufDestroy(pStreamCC->State.pCircBuf);
+                    pStreamCC->State.pCircBuf = NULL;
                 }
 
-                rc = RTCircBufCreate(&pStream->State.pCircBuf, DrvAudioHlpMilliToBytes(100 /* ms */, &Cfg.Props)); /** @todo Make this configurable. */
+                rc = RTCircBufCreate(&pStreamCC->State.pCircBuf, DrvAudioHlpMilliToBytes(100 /* ms */, &Cfg.Props)); /** @todo Make this configurable. */
                 if (RT_SUCCESS(rc))
                 {
-                    ichac97R3MixerRemoveDrvStreams(pThis, pMixSink, Cfg.enmDir, Cfg.u);
-
-                    rc = ichac97R3MixerAddDrvStreams(pThis, pMixSink, &Cfg);
+                    ichac97R3MixerRemoveDrvStreams(pThisCC, pMixSink, Cfg.enmDir, Cfg.u);
+
+                    rc = ichac97R3MixerAddDrvStreams(pThisCC, pMixSink, &Cfg);
                     if (RT_SUCCESS(rc))
-                        rc = DrvAudioHlpStreamCfgCopy(&pStream->State.Cfg, &Cfg);
+                        rc = DrvAudioHlpStreamCfgCopy(&pStreamCC->State.Cfg, &Cfg);
                 }
             }
@@ -2084,13 +2092,10 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
- * @param   pStream             AC'97 stream to close.
- */
-static int ichac97R3StreamClose(PAC97STATE pThis, PAC97STREAM pStream)
-{
-    RT_NOREF(pThis, pStream);
-
+ * @param   pStream             The AC'97 stream to close (shared).
+ */
+static int ichac97R3StreamClose(PAC97STREAM pStream)
+{
+    RT_NOREF(pStream);
     LogFlowFunc(("[SD%RU8]\n", pStream->u8SD));
-
     return VINF_SUCCESS;
 }
@@ -2101,16 +2106,22 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 device state.
- * @param   pStream             AC'97 stream to re-open.
+ * @param   pThis               The shared AC'97 device state.
+ * @param   pThisCC             The ring-3 AC'97 device state.
+ * @param   pStream             The AC'97 stream to re-open (shared).
+ * @param   pStreamCC           The AC'97 stream to re-open (ring-3).
  * @param   fForce              Whether to force re-opening the stream or not.
  *                              Otherwise re-opening only will happen if the PCM properties have changed.
  */
-static int ichac97R3StreamReOpen(PAC97STATE pThis, PAC97STREAM pStream, bool fForce)
+static int ichac97R3StreamReOpen(PAC97STATE pThis, PAC97STATER3 pThisCC,
+                                 PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fForce)
 {
     LogFlowFunc(("[SD%RU8]\n", pStream->u8SD));
-
-    int rc = ichac97R3StreamClose(pThis, pStream);
+    Assert(pStream->u8SD == pStreamCC->u8SD);
+    Assert(pStream   - &pThis->aStreams[0]   == pStream->u8SD);
+    Assert(pStreamCC - &pThisCC->aStreams[0] == pStream->u8SD);
+
+    int rc = ichac97R3StreamClose(pStream);
     if (RT_SUCCESS(rc))
-        rc = ichac97R3StreamOpen(pThis, pStream, fForce);
+        rc = ichac97R3StreamOpen(pThis, pThisCC, pStream, pStreamCC, fForce);
 
     return rc;
@@ -2121,9 +2132,9 @@
  *
  * @returns IPRT status code.
- * @param   pStream             AC'97 stream to lock.
- */
-static void ichac97R3StreamLock(PAC97STREAM pStream)
-{
-    int rc2 = RTCritSectEnter(&pStream->State.CritSect);
+ * @param   pStreamCC           The AC'97 stream to lock (ring-3).
+ */
+static void ichac97R3StreamLock(PAC97STREAMR3 pStreamCC)
+{
+    int rc2 = RTCritSectEnter(&pStreamCC->State.CritSect);
     AssertRC(rc2);
 }
@@ -2133,9 +2144,9 @@
  *
  * @returns IPRT status code.
- * @param   pStream             AC'97 stream to unlock.
- */
-static void ichac97R3StreamUnlock(PAC97STREAM pStream)
-{
-    int rc2 = RTCritSectLeave(&pStream->State.CritSect);
+ * @param   pStreamCC           The AC'97 stream to unlock (ring-3).
+ */
+static void ichac97R3StreamUnlock(PAC97STREAMR3 pStreamCC)
+{
+    int rc2 = RTCritSectLeave(&pStreamCC->State.CritSect);
     AssertRC(rc2);
 }
@@ -2145,12 +2156,12 @@
  *
  * @returns Available data (in bytes).
- * @param   pStream             AC'97 stream to retrieve size for.
- */
-static uint32_t ichac97R3StreamGetUsed(PAC97STREAM pStream)
-{
-    if (!pStream->State.pCircBuf)
+ * @param   pStreamCC           The AC'97 stream to retrieve size for (ring-3).
+ */
+static uint32_t ichac97R3StreamGetUsed(PAC97STREAMR3 pStreamCC)
+{
+    if (!pStreamCC->State.pCircBuf)
         return 0;
 
-    return (uint32_t)RTCircBufUsed(pStream->State.pCircBuf);
+    return (uint32_t)RTCircBufUsed(pStreamCC->State.pCircBuf);
 }
 
@@ -2161,10 +2172,10 @@
  * @param   pStream             AC'97 stream to retrieve size for.
  */
-static uint32_t ichac97R3StreamGetFree(PAC97STREAM pStream)
-{
-    if (!pStream->State.pCircBuf)
+static uint32_t ichac97R3StreamGetFree(PAC97STREAMR3 pStreamCC)
+{
+    if (!pStreamCC->State.pCircBuf)
         return 0;
 
-    return (uint32_t)RTCircBufFree(pStream->State.pCircBuf);
+    return (uint32_t)RTCircBufFree(pStreamCC->State.pCircBuf);
 }
 
@@ -2175,10 +2186,11 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
+ * @param   pThis               The shared AC'97 state.
+ * @param   pThisCC             The ring-3 AC'97 state.
  * @param   index               AC'97 mixer index to set volume for.
  * @param   enmMixerCtl         Corresponding audio mixer sink.
  * @param   uVal                Volume value to set.
  */
-static int ichac97R3MixerSetVolume(PAC97STATE pThis, int index, PDMAUDIOMIXERCTL enmMixerCtl, uint32_t uVal)
+static int ichac97R3MixerSetVolume(PAC97STATE pThis, PAC97STATER3 pThisCC, int index, PDMAUDIOMIXERCTL enmMixerCtl, uint32_t uVal)
 {
     /*
@@ -2234,5 +2246,5 @@
     int rc = VINF_SUCCESS;
 
-    if (pThis->pMixer) /* Device can be in reset state, so no mixer available. */
+    if (pThisCC->pMixer) /* Device can be in reset state, so no mixer available. */
     {
         PDMAUDIOVOLUME Vol   = { fCtlMuted, lVol, rVol };
@@ -2242,9 +2254,9 @@
         {
             case PDMAUDIOMIXERCTL_VOLUME_MASTER:
-                rc = AudioMixerSetMasterVolume(pThis->pMixer, &Vol);
+                rc = AudioMixerSetMasterVolume(pThisCC->pMixer, &Vol);
                 break;
 
             case PDMAUDIOMIXERCTL_FRONT:
-                pSink = pThis->pSinkOut;
+                pSink = pThisCC->pSinkOut;
                 break;
 
@@ -2278,10 +2290,11 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
+ * @param   pThis               The shared AC'97 state.
+ * @param   pThisCC             The ring-3 AC'97 state.
  * @param   index               AC'97 mixer index to set volume for.
  * @param   enmMixerCtl         Corresponding audio mixer sink.
  * @param   uVal                Volume value to set.
  */
-static int ichac97R3MixerSetGain(PAC97STATE pThis, int index, PDMAUDIOMIXERCTL enmMixerCtl, uint32_t uVal)
+static int ichac97R3MixerSetGain(PAC97STATE pThis, PAC97STATER3 pThisCC, int index, PDMAUDIOMIXERCTL enmMixerCtl, uint32_t uVal)
 {
     /*
@@ -2317,5 +2330,5 @@
     int rc = VINF_SUCCESS;
 
-    if (pThis->pMixer) /* Device can be in reset state, so no mixer available. */
+    if (pThisCC->pMixer) /* Device can be in reset state, so no mixer available. */
     {
         PDMAUDIOVOLUME Vol   = { fCtlMuted, lVol, rVol };
@@ -2325,9 +2338,9 @@
         {
             case PDMAUDIOMIXERCTL_MIC_IN:
-                pSink = pThis->pSinkMicIn;
+                pSink = pThisCC->pSinkMicIn;
                 break;
 
             case PDMAUDIOMIXERCTL_LINE_IN:
-                pSink = pThis->pSinkLineIn;
+                pSink = pThisCC->pSinkLineIn;
                 break;
 
@@ -2345,5 +2358,5 @@
              * NB: The codecs we support do not have the dedicated microphone control.
              */
-            if ((pSink == pThis->pSinkLineIn) && pThis->pSinkMicIn)
+            if ((pSink == pThisCC->pSinkLineIn) && pThisCC->pSinkMicIn)
                 rc = AudioMixerSinkSetVolume(pSink, &Vol);
         }
@@ -2432,5 +2445,5 @@
  * source.
  *
- * @param   pThis               AC'97 state.
+ * @param   pThis               The shared AC'97 state.
  * @param   val                 AC'97 recording source index to set.
  */
@@ -2455,7 +2468,8 @@
  *
  * @returns IPRT status code.
- * @param   pThis               AC'97 state.
- */
-static int ichac97R3MixerReset(PAC97STATE pThis)
+ * @param   pThis               The shared AC'97 state.
+ * @param   pThisCC             The ring-3 AC'97 state.
+ */
+static int ichac97R3MixerReset(PAC97STATE pThis, PAC97STATER3 pThisCC)
 {
     LogFlowFuncEnter();
@@ -2515,14 +2529,14 @@
 
     /* The default value is 8000h, which corresponds to 0 dB attenuation with mute on. */
-    ichac97R3MixerSetVolume(pThis, AC97_Master_Volume_Mute,  PDMAUDIOMIXERCTL_VOLUME_MASTER, 0x8000);
+    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_Master_Volume_Mute,  PDMAUDIOMIXERCTL_VOLUME_MASTER, 0x8000);
 
     /* The default value for stereo registers is 8808h, which corresponds to 0 dB gain with mute on.*/
-    ichac97R3MixerSetVolume(pThis, AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_FRONT,         0x8808);
-    ichac97R3MixerSetVolume(pThis, AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN,       0x8808);
-    ichac97R3MixerSetVolume(pThis, AC97_Mic_Volume_Mute,     PDMAUDIOMIXERCTL_MIC_IN,        0x8008);
+    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_FRONT,         0x8808);
+    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN,       0x8808);
+    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_Mic_Volume_Mute,     PDMAUDIOMIXERCTL_MIC_IN,        0x8008);
 
     /* The default for record controls is 0 dB gain with mute on. */
-    ichac97R3MixerSetGain(pThis, AC97_Record_Gain_Mute,      PDMAUDIOMIXERCTL_LINE_IN,       0x8000);
-    ichac97R3MixerSetGain(pThis, AC97_Record_Gain_Mic_Mute,  PDMAUDIOMIXERCTL_MIC_IN,        0x8000);
+    ichac97R3MixerSetGain(pThis, pThisCC, AC97_Record_Gain_Mute,      PDMAUDIOMIXERCTL_LINE_IN,       0x8000);
+    ichac97R3MixerSetGain(pThis, pThisCC, AC97_Record_Gain_Mic_Mute,  PDMAUDIOMIXERCTL_MIC_IN,        0x8000);
 
     return VINF_SUCCESS;
@@ -2554,5 +2568,5 @@
         uint32_t cbWrittenToStream;
 
-        int rc2 = AudioMixerSinkWrite(pThis->pSinkOut, AUDMIXOP_COPY,
+        int rc2 = AudioMixerSinkWrite(pThisCC->pSinkOut, AUDMIXOP_COPY,
                                       pThis->silence, cbToWrite, &cbWrittenToStream);
         if (RT_SUCCESS(rc2))
@@ -2576,20 +2590,22 @@
 static DECLCALLBACK(void) ichac97R3Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
 {
-    PAC97STATE  pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATE      pThis     = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     STAM_PROFILE_START(&pThis->StatTimer, a);
-    PAC97STREAM pStream = (PAC97STREAM)pvUser;
+    PAC97STATER3    pThisCC   = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
+    PAC97STREAM     pStream   = (PAC97STREAM)pvUser;
+    PAC97STREAMR3   pStreamCC = &RT_SAFE_SUBSCRIPT8(pThisCC->aStreams, pStream->u8SD);
     RT_NOREF(pTimer);
 
-    AssertPtr(pStream);
+    Assert(pStream - &pThis->aStreams[0] == pStream->u8SD);
     Assert(PDMDevHlpCritSectIsOwner(pDevIns, &pThis->CritSect));
     Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pStream->hTimer));
 
-    ichac97R3StreamUpdate(pDevIns, pThis, pStream, true /* fInTimer */);
-
-    PAUDMIXSINK pSink = ichac97R3IndexToSink(pThis, pStream->u8SD);
+    ichac97R3StreamUpdate(pDevIns, pThis, pThisCC, pStream, pStreamCC, true /* fInTimer */);
+
+    PAUDMIXSINK pSink = ichac97R3IndexToSink(pThisCC, pStream->u8SD);
     if (pSink && AudioMixerSinkIsActive(pSink))
     {
-        ichac97R3StreamTransferUpdate(pDevIns, pStream, pStream->Regs.picb << 1); /** @todo r=andy Assumes 16-bit samples. */
-        ichac97R3TimerSet(pDevIns, pStream, pStream->State.cTransferTicks);
+        ichac97R3StreamTransferUpdate(pDevIns, pStream, pStreamCC, pStream->Regs.picb << 1); /** @todo r=andy Assumes 16-bit samples. */
+        ichac97R3TimerSet(pDevIns, pStream, pStreamCC->State.cTransferTicks);
     }
 
@@ -2602,5 +2618,5 @@
  *
  * @param   pDevIns             The device instance.
- * @param   pThis               AC'97 state.
+ * @param   pThis               The shared AC'97 state.
  * @param   pStream             AC'97 stream to set timer for.
  * @param   cTicksToDeadline    The number of ticks to the new deadline.
@@ -2626,9 +2642,11 @@
  * @returns IPRT status code.
  * @param   pDevIns             The device instance.
- * @param   pThis               AC'97 state.
- * @param   pStream             AC'97 stream to update.
+ * @param   pThis               The shared AC'97 state.
+ * @param   pStream             The AC'97 stream to update (shared).
+ * @param   pStreamCC           The AC'97 stream to update (ring-3).
  * @param   cbToProcessMax      Maximum of data (in bytes) to process.
  */
-static int ichac97R3StreamTransfer(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbToProcessMax)
+static int ichac97R3StreamTransfer(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream,
+                                   PAC97STREAMR3 pStreamCC, uint32_t cbToProcessMax)
 {
     if (!cbToProcessMax)
@@ -2636,5 +2654,5 @@
 
 #ifdef VBOX_STRICT
-    const unsigned cbFrame = DrvAudioHlpPCMPropsBytesPerFrame(&pStream->State.Cfg.Props);
+    const unsigned cbFrame = DrvAudioHlpPCMPropsBytesPerFrame(&pStreamCC->State.Cfg.Props);
 #endif
 
@@ -2642,5 +2660,5 @@
     Assert(cbToProcessMax % cbFrame == 0);
 
-    ichac97R3StreamLock(pStream);
+    ichac97R3StreamLock(pStreamCC);
 
     PAC97BMREGS pRegs = &pStream->Regs;
@@ -2661,5 +2679,5 @@
         }
 
-        ichac97R3StreamUnlock(pStream);
+        ichac97R3StreamUnlock(pStreamCC);
         return VINF_SUCCESS;
     }
@@ -2670,5 +2688,5 @@
         Log3Func(("[SD%RU8] BCIS set\n", pStream->u8SD));
 
-        ichac97R3StreamUnlock(pStream);
+        ichac97R3StreamUnlock(pStreamCC);
         return VINF_SUCCESS;
     }
@@ -2677,5 +2695,5 @@
     uint32_t cbProcessedTotal = 0;
 
-    PRTCIRCBUF pCircBuf = pStream->State.pCircBuf;
+    PRTCIRCBUF pCircBuf = pStreamCC->State.pCircBuf;
     AssertPtr(pCircBuf);
 
@@ -2703,5 +2721,5 @@
             pRegs->piv = (pRegs->piv + 1) % AC97_MAX_BDLE;
 
-            ichac97R3StreamFetchBDLE(pThis, pStream);
+            ichac97R3StreamFetchBDLE(pDevIns, pStream);
             continue;
         }
@@ -2720,9 +2738,11 @@
                 if (cbDst)
                 {
-                    int rc2 = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), pRegs->bd.addr, (uint8_t *)pvDst, cbDst);
+                    int rc2 = PDMDevHlpPhysRead(pDevIns, pRegs->bd.addr, (uint8_t *)pvDst, cbDst);
                     AssertRC(rc2);
 
-                    if (pStream->Dbg.Runtime.fEnabled)
-                        DrvAudioHlpFileWrite(pStream->Dbg.Runtime.pFileDMA, pvDst, cbDst, 0 /* fFlags */);
+                    if (RT_LIKELY(!pStreamCC->Dbg.Runtime.fEnabled))
+                    { /* likely */ }
+                    else
+                        DrvAudioHlpFileWrite(pStreamCC->Dbg.Runtime.pFileDMA, pvDst, cbDst, 0 /* fFlags */);
                 }
 
@@ -2745,9 +2765,11 @@
 /** @todo r=bird: Just curious, DevHDA uses PDMDevHlpPCIPhysWrite here.  So,
  *        is AC97 not subject to PCI busmaster enable/disable? */
-                    int rc2 = PDMDevHlpPhysWrite(pThis->CTX_SUFF(pDevIns), pRegs->bd.addr, (uint8_t *)pvSrc, cbSrc);
+                    int rc2 = PDMDevHlpPhysWrite(pDevIns, pRegs->bd.addr, (uint8_t *)pvSrc, cbSrc);
                     AssertRC(rc2);
 
-                    if (pStream->Dbg.Runtime.fEnabled)
-                        DrvAudioHlpFileWrite(pStream->Dbg.Runtime.pFileDMA, pvSrc, cbSrc, 0 /* fFlags */);
+                    if (RT_LIKELY(!pStreamCC->Dbg.Runtime.fEnabled))
+                    { /* likely */ }
+                    else
+                        DrvAudioHlpFileWrite(pStreamCC->Dbg.Runtime.pFileDMA, pvSrc, cbSrc, 0 /* fFlags */);
                 }
 
@@ -2805,5 +2827,5 @@
                 pRegs->civ = pRegs->piv;
                 pRegs->piv = (pRegs->piv + 1) % AC97_MAX_BDLE;
-                ichac97R3StreamFetchBDLE(pThis, pStream);
+                ichac97R3StreamFetchBDLE(pDevIns, pStream);
             }
 
@@ -2820,5 +2842,5 @@
     }
 
-    ichac97R3StreamUnlock(pStream);
+    ichac97R3StreamUnlock(pStreamCC);
 
     LogFlowFuncLeaveRC(rc);
@@ -2999,13 +3021,22 @@
 ichac97IoPortNabmWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t u32, unsigned cb)
 {
-    PAC97STATE  pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATE      pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+#ifdef IN_RING3
+    PAC97STATER3    pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
+#endif
     RT_NOREF(pvUser);
 
-    PAC97STREAM pStream = NULL;
-    PAC97BMREGS pRegs   = NULL;
+#ifdef IN_RING3
+    PAC97STREAMR3   pStreamCC = NULL;
+#endif
+    PAC97STREAM     pStream   = NULL;
+    PAC97BMREGS     pRegs     = NULL;
     if (AC97_PORT2IDX(offPort) < AC97_MAX_STREAMS)
     {
-        pStream = &pThis->aStreams[AC97_PORT2IDX(offPort)];
-        pRegs   = &pStream->Regs;
+#ifdef IN_RING3
+        pStreamCC = &pThisCC->aStreams[AC97_PORT2IDX(offPort)];
+#endif
+        pStream   = &pThis->aStreams[AC97_PORT2IDX(offPort)];
+        pRegs     = &pStream->Regs;
 
         DEVAC97_LOCK_BOTH_RETURN(pDevIns, pThis, pStream, VINF_IOM_R3_IOPORT_WRITE);
@@ -3062,6 +3093,6 @@
                         Assert((pRegs->cr & AC97_CR_RPBM) == 0);
 
-                        ichac97R3StreamEnable(pThis, pStream, false /* fEnable */);
-                        ichac97R3StreamReset(pThis, pStream);
+                        ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, false /* fEnable */);
+                        ichac97R3StreamReset(pThis, pStream, pStreamCC);
 
                         ichac97StreamUpdateSR(pDevIns, pThis, pStream, AC97_SR_DCH); /** @todo Do we need to do that? */
@@ -3075,5 +3106,5 @@
                             Log3Func(("[SD%RU8] Disable\n", pStream->u8SD));
 
-                            ichac97R3StreamEnable(pThis, pStream, false /* fEnable */);
+                            ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, false /* fEnable */);
 
                             pRegs->sr |= AC97_SR_DCH;
@@ -3089,13 +3120,13 @@
 
                             /* Fetch the initial BDLE descriptor. */
-                            ichac97R3StreamFetchBDLE(pThis, pStream);
+                            ichac97R3StreamFetchBDLE(pDevIns, pStream);
 # ifdef LOG_ENABLED
-                            ichac97R3BDLEDumpAll(pThis, pStream->Regs.bdbar, pStream->Regs.lvi + 1);
+                            ichac97R3BDLEDumpAll(pDevIns, pStream->Regs.bdbar, pStream->Regs.lvi + 1);
 # endif
-                            ichac97R3StreamEnable(pThis, pStream, true /* fEnable */);
+                            ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, true /* fEnable */);
 
                             /* Arm the timer for this stream. */
                             /** @todo r=bird: This function returns bool, not VBox status! */
-                            ichac97R3TimerSet(pDevIns, pStream, pStream->State.cTransferTicks);
+                            ichac97R3TimerSet(pDevIns, pStream, pStreamCC->State.cTransferTicks);
                         }
                     }
@@ -3242,5 +3273,8 @@
 ichac97IoPortNamWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t u32, unsigned cb)
 {
-    PAC97STATE pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+#ifdef IN_RING3
+    PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
+#endif
     RT_NOREF(pvUser);
 
@@ -3264,5 +3298,5 @@
                 case AC97_Reset:
 #ifdef IN_RING3
-                    ichac97R3Reset(pThis->CTX_SUFF(pDevIns));
+                    ichac97R3Reset(pDevIns);
 #else
                     rc = VINF_IOM_R3_IOPORT_WRITE;
@@ -3281,5 +3315,5 @@
                     }
 #ifdef IN_RING3
-                    ichac97R3MixerSetVolume(pThis, offPort, PDMAUDIOMIXERCTL_VOLUME_MASTER, u32);
+                    ichac97R3MixerSetVolume(pThis, pThisCC, offPort, PDMAUDIOMIXERCTL_VOLUME_MASTER, u32);
 #else
                     rc = VINF_IOM_R3_IOPORT_WRITE;
@@ -3293,5 +3327,5 @@
                             /* Register controls PCM (front) outputs. */
 #ifdef IN_RING3
-                            ichac97R3MixerSetVolume(pThis, offPort, PDMAUDIOMIXERCTL_VOLUME_MASTER, u32);
+                            ichac97R3MixerSetVolume(pThis, pThisCC, offPort, PDMAUDIOMIXERCTL_VOLUME_MASTER, u32);
 #else
                             rc = VINF_IOM_R3_IOPORT_WRITE;
@@ -3302,5 +3336,5 @@
                 case AC97_PCM_Out_Volume_Mute:
 #ifdef IN_RING3
-                    ichac97R3MixerSetVolume(pThis, offPort, PDMAUDIOMIXERCTL_FRONT, u32);
+                    ichac97R3MixerSetVolume(pThis, pThisCC, offPort, PDMAUDIOMIXERCTL_FRONT, u32);
 #else
                     rc = VINF_IOM_R3_IOPORT_WRITE;
@@ -3309,5 +3343,5 @@
                 case AC97_Line_In_Volume_Mute:
 #ifdef IN_RING3
-                    ichac97R3MixerSetVolume(pThis, offPort, PDMAUDIOMIXERCTL_LINE_IN, u32);
+                    ichac97R3MixerSetVolume(pThis, pThisCC, offPort, PDMAUDIOMIXERCTL_LINE_IN, u32);
 #else
                     rc = VINF_IOM_R3_IOPORT_WRITE;
@@ -3325,5 +3359,5 @@
                     /* Newer Ubuntu guests rely on that when controlling gain and muting
                      * the recording (capturing) levels. */
-                    ichac97R3MixerSetGain(pThis, offPort, PDMAUDIOMIXERCTL_LINE_IN, u32);
+                    ichac97R3MixerSetGain(pThis, pThisCC, offPort, PDMAUDIOMIXERCTL_LINE_IN, u32);
 #else
                     rc = VINF_IOM_R3_IOPORT_WRITE;
@@ -3333,5 +3367,5 @@
 #ifdef IN_RING3
                     /* Ditto; see note above. */
-                    ichac97R3MixerSetGain(pThis, offPort, PDMAUDIOMIXERCTL_MIC_IN,  u32);
+                    ichac97R3MixerSetGain(pThis, pThisCC, offPort, PDMAUDIOMIXERCTL_MIC_IN,  u32);
 #else
                     rc = VINF_IOM_R3_IOPORT_WRITE;
@@ -3353,8 +3387,10 @@
                     {
                         ichac97MixerSet(pThis, AC97_PCM_Front_DAC_Rate, 0xbb80); /* Set default (48000 Hz). */
-                        ichac97R3StreamReOpen(pThis, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX], true /* fForce */);
+                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX],
+                                              &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX], true /* fForce */);
 
                         ichac97MixerSet(pThis, AC97_PCM_LR_ADC_Rate, 0xbb80); /* Set default (48000 Hz). */
-                        ichac97R3StreamReOpen(pThis, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX], true /* fForce */);
+                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX],
+                                              &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX], true /* fForce */);
                     }
                     else
@@ -3367,5 +3403,6 @@
                     {
                         ichac97MixerSet(pThis, AC97_MIC_ADC_Rate, 0xbb80); /* Set default (48000 Hz). */
-                        ichac97R3StreamReOpen(pThis, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX], true /* fForce */);
+                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX],
+                                              &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX], true /* fForce */);
                     }
                     else
@@ -3384,5 +3421,6 @@
                         LogRel2(("AC97: Setting front DAC rate to 0x%x\n", u32));
                         ichac97MixerSet(pThis, offPort, u32);
-                        ichac97R3StreamReOpen(pThis, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX], true /* fForce */);
+                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX],
+                                              &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX], true /* fForce */);
                     }
                     else
@@ -3398,5 +3436,6 @@
                         LogRel2(("AC97: Setting microphone ADC rate to 0x%x\n", u32));
                         ichac97MixerSet(pThis, offPort, u32);
-                        ichac97R3StreamReOpen(pThis, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX], true /* fForce */);
+                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX],
+                                              &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX], true /* fForce */);
                     }
                     else
@@ -3412,5 +3451,6 @@
                         LogRel2(("AC97: Setting line-in ADC rate to 0x%x\n", u32));
                         ichac97MixerSet(pThis, offPort, u32);
-                        ichac97R3StreamReOpen(pThis, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX], true /* fForce */);
+                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX],
+                                              &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX], true /* fForce */);
                     }
                     else
@@ -3478,6 +3518,7 @@
 static DECLCALLBACK(int) ichac97R3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
 {
-    PAC97STATE    pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
-    PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
+    PAC97STATE      pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATER3    pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
+    PCPDMDEVHLPR3   pHlp    = pDevIns->pHlpR3;
 
     LogFlowFuncEnter();
@@ -3499,7 +3540,7 @@
     uint8_t active[AC97SOUNDSOURCE_END_INDEX];
 
-    active[AC97SOUNDSOURCE_PI_INDEX] = ichac97R3StreamIsEnabled(pThis, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX]) ? 1 : 0;
-    active[AC97SOUNDSOURCE_PO_INDEX] = ichac97R3StreamIsEnabled(pThis, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX]) ? 1 : 0;
-    active[AC97SOUNDSOURCE_MC_INDEX] = ichac97R3StreamIsEnabled(pThis, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX]) ? 1 : 0;
+    active[AC97SOUNDSOURCE_PI_INDEX] = ichac97R3StreamIsEnabled(pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX]) ? 1 : 0;
+    active[AC97SOUNDSOURCE_PO_INDEX] = ichac97R3StreamIsEnabled(pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX]) ? 1 : 0;
+    active[AC97SOUNDSOURCE_MC_INDEX] = ichac97R3StreamIsEnabled(pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX]) ? 1 : 0;
 
     pHlp->pfnSSMPutMem(pSSM, active, sizeof(active));
@@ -3539,6 +3580,7 @@
 static DECLCALLBACK(int) ichac97R3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
 {
-    PAC97STATE    pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
-    PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
+    PAC97STATE    pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATER3  pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
+    PCPDMDEVHLPR3 pHlp    = pDevIns->pHlpR3;
 
     LogRel2(("ichac97LoadExec: uVersion=%RU32, uPass=0x%x\n", uVersion, uPass));
@@ -3567,13 +3609,19 @@
 
     ichac97R3MixerRecordSelect(pThis, ichac97MixerGet(pThis, AC97_Record_Select));
-    ichac97R3MixerSetVolume(pThis, AC97_Master_Volume_Mute, PDMAUDIOMIXERCTL_VOLUME_MASTER, ichac97MixerGet(pThis, AC97_Master_Volume_Mute));
-    ichac97R3MixerSetVolume(pThis, AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_FRONT, ichac97MixerGet(pThis, AC97_PCM_Out_Volume_Mute));
-    ichac97R3MixerSetVolume(pThis, AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN, ichac97MixerGet(pThis, AC97_Line_In_Volume_Mute));
-    ichac97R3MixerSetVolume(pThis, AC97_Mic_Volume_Mute, PDMAUDIOMIXERCTL_MIC_IN, ichac97MixerGet(pThis, AC97_Mic_Volume_Mute));
-    ichac97R3MixerSetGain(pThis, AC97_Record_Gain_Mic_Mute, PDMAUDIOMIXERCTL_MIC_IN, ichac97MixerGet(pThis, AC97_Record_Gain_Mic_Mute));
-    ichac97R3MixerSetGain(pThis, AC97_Record_Gain_Mute, PDMAUDIOMIXERCTL_LINE_IN, ichac97MixerGet(pThis, AC97_Record_Gain_Mute));
+    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_Master_Volume_Mute,    PDMAUDIOMIXERCTL_VOLUME_MASTER,
+                            ichac97MixerGet(pThis, AC97_Master_Volume_Mute));
+    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_PCM_Out_Volume_Mute,   PDMAUDIOMIXERCTL_FRONT,
+                            ichac97MixerGet(pThis, AC97_PCM_Out_Volume_Mute));
+    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_Line_In_Volume_Mute,   PDMAUDIOMIXERCTL_LINE_IN,
+                            ichac97MixerGet(pThis, AC97_Line_In_Volume_Mute));
+    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_Mic_Volume_Mute,       PDMAUDIOMIXERCTL_MIC_IN,
+                            ichac97MixerGet(pThis, AC97_Mic_Volume_Mute));
+    ichac97R3MixerSetGain(pThis, pThisCC, AC97_Record_Gain_Mic_Mute,    PDMAUDIOMIXERCTL_MIC_IN,
+                          ichac97MixerGet(pThis, AC97_Record_Gain_Mic_Mute));
+    ichac97R3MixerSetGain(pThis, pThisCC, AC97_Record_Gain_Mute,        PDMAUDIOMIXERCTL_LINE_IN,
+                          ichac97MixerGet(pThis, AC97_Record_Gain_Mute));
     if (pThis->uCodecModel == AC97_CODEC_AD1980)
         if (ichac97MixerGet(pThis, AC97_AD_Misc) & AC97_AD_MISC_HPSEL)
-            ichac97R3MixerSetVolume(pThis, AC97_Headphone_Volume_Mute, PDMAUDIOMIXERCTL_VOLUME_MASTER,
+            ichac97R3MixerSetVolume(pThis, pThisCC, AC97_Headphone_Volume_Mute, PDMAUDIOMIXERCTL_VOLUME_MASTER,
                                     ichac97MixerGet(pThis, AC97_Headphone_Volume_Mute));
 
@@ -3581,8 +3629,9 @@
     for (unsigned i = 0; i < AC97_MAX_STREAMS; i++)
     {
-        const bool        fEnable = RT_BOOL(uaStrmsActive[i]);
-        const PAC97STREAM pStream = &pThis->aStreams[i];
-
-        rc2 = ichac97R3StreamEnable(pThis, pStream, fEnable);
+        const bool          fEnable   = RT_BOOL(uaStrmsActive[i]);
+        const PAC97STREAM   pStream   = &pThis->aStreams[i];
+        const PAC97STREAMR3 pStreamCC = &pThisCC->aStreams[i];
+
+        rc2 = ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, fEnable);
         AssertRC(rc2);
         if (   fEnable
@@ -3590,5 +3639,5 @@
         {
             /* Re-arm the timer for this stream. */
-            ichac97R3TimerSet(pDevIns, pStream, pStream->State.cTransferTicks);
+            ichac97R3TimerSet(pDevIns, pStream, pStreamCC->State.cTransferTicks);
         }
 
@@ -3608,8 +3657,6 @@
 static DECLCALLBACK(void *) ichac97R3QueryInterface(struct PDMIBASE *pInterface, const char *pszIID)
 {
-    PAC97STATE pThis = RT_FROM_MEMBER(pInterface, AC97STATE, IBase);
-    Assert(&pThis->IBase == pInterface);
-
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->IBase);
+    PAC97STATER3 pThisCC = RT_FROM_MEMBER(pInterface, AC97STATER3, IBase);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThisCC->IBase);
     return NULL;
 }
@@ -3623,5 +3670,6 @@
 static DECLCALLBACK(void) ichac97R3PowerOff(PPDMDEVINS pDevIns)
 {
-    PAC97STATE pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
 
     LogRel2(("AC97: Powering off ...\n"));
@@ -3629,15 +3677,15 @@
     /* Note: Involves mixer stream / sink destruction, so also do this here
      *       instead of in ichac97R3Destruct(). */
-    ichac97R3StreamsDestroy(pThis);
-
-    /**
+    ichac97R3StreamsDestroy(pThis, pThisCC);
+
+    /*
      * Note: Destroy the mixer while powering off and *not* in ichac97R3Destruct,
      *       giving the mixer the chance to release any references held to
      *       PDM audio streams it maintains.
      */
-    if (pThis->pMixer)
-    {
-        AudioMixerDestroy(pThis->pMixer);
-        pThis->pMixer = NULL;
+    if (pThisCC->pMixer)
+    {
+        AudioMixerDestroy(pThisCC->pMixer);
+        pThisCC->pMixer = NULL;
     }
 }
@@ -3652,5 +3700,6 @@
 static DECLCALLBACK(void) ichac97R3Reset(PPDMDEVINS pDevIns)
 {
-    PAC97STATE pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
 
     LogRel(("AC97: Reset\n"));
@@ -3661,5 +3710,5 @@
      * the codec manually.
      */
-    ichac97R3MixerReset(pThis);
+    ichac97R3MixerReset(pThis, pThisCC);
 
     /*
@@ -3668,6 +3717,6 @@
     for (unsigned i = 0; i < AC97_MAX_STREAMS; i++)
     {
-        ichac97R3StreamEnable(pThis, &pThis->aStreams[i], false /* fEnable */);
-        ichac97R3StreamReset(pThis, &pThis->aStreams[i]);
+        ichac97R3StreamEnable(pThis, pThisCC, &pThis->aStreams[i], &pThisCC->aStreams[i], false /* fEnable */);
+        ichac97R3StreamReset(pThis, &pThis->aStreams[i], &pThisCC->aStreams[i]);
     }
 
@@ -3678,7 +3727,7 @@
      * the mixer sink(s) might still have data to be processed when an audio stream gets reset.
      */
-    AudioMixerSinkReset(pThis->pSinkLineIn);
-    AudioMixerSinkReset(pThis->pSinkMicIn);
-    AudioMixerSinkReset(pThis->pSinkOut);
+    AudioMixerSinkReset(pThisCC->pSinkLineIn);
+    AudioMixerSinkReset(pThisCC->pSinkMicIn);
+    AudioMixerSinkReset(pThisCC->pSinkOut);
 }
 
@@ -3692,10 +3741,11 @@
  *
  * @returns VBox status code.
- * @param   pThis       AC'97 state.
+ * @param   pDevIns     The device instance.
+ * @param   pThisCC     The ring-3 AC'97 device state.
  * @param   iLun        The logical unit which is being attached.
  * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
  * @param   ppDrv       Attached driver instance on success. Optional.
  */
-static int ichac97R3AttachInternal(PAC97STATE pThis, unsigned iLun, uint32_t fFlags, PAC97DRIVER *ppDrv)
+static int ichac97R3AttachInternal(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, unsigned iLun, uint32_t fFlags, PAC97DRIVER *ppDrv)
 {
     RT_NOREF(fFlags);
@@ -3709,5 +3759,5 @@
 
     PPDMIBASE pDrvBase;
-    int rc = PDMDevHlpDriverAttach(pThis->pDevInsR3, iLun, &pThis->IBase, &pDrvBase, pszDesc);
+    int rc = PDMDevHlpDriverAttach(pDevIns, iLun, &pThisCC->IBase, &pDrvBase, pszDesc);
     if (RT_SUCCESS(rc))
     {
@@ -3718,5 +3768,4 @@
             pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR);
             AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n", iLun, rc));
-            pDrv->pAC97State = pThis;
             pDrv->uLUN       = iLun;
             pDrv->pszDesc    = pszDesc;
@@ -3734,5 +3783,5 @@
             if (!pDrv->fAttached)
             {
-                RTListAppend(&pThis->lstDrv, &pDrv->Node);
+                RTListAppend(&pThisCC->lstDrv, &pDrv->Node);
                 pDrv->fAttached = true;
             }
@@ -3765,9 +3814,9 @@
  *
  * @returns VBox status code.
- * @param   pThis       AC'97 state.
+ * @param   pThisCC     The ring-3 AC'97 device state.
  * @param   pDrv        Driver to detach from device.
  * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
  */
-static int ichac97R3DetachInternal(PAC97STATE pThis, PAC97DRIVER pDrv, uint32_t fFlags)
+static int ichac97R3DetachInternal(PAC97STATER3 pThisCC, PAC97DRIVER pDrv, uint32_t fFlags)
 {
     RT_NOREF(fFlags);
@@ -3775,5 +3824,5 @@
     /* First, remove the driver from our list and destory it's associated streams.
      * This also will un-set the driver as a recording source (if associated). */
-    ichac97R3MixerRemoveDrv(pThis, pDrv);
+    ichac97R3MixerRemoveDrv(pThisCC, pDrv);
 
     /* Next, search backwards for a capable (attached) driver which now will be the
@@ -3781,5 +3830,5 @@
     PDMAUDIODSTSRCUNION dstSrc;
     PAC97DRIVER pDrvCur;
-    RTListForEachReverse(&pThis->lstDrv, pDrvCur, AC97DRIVER, Node)
+    RTListForEachReverse(&pThisCC->lstDrv, pDrvCur, AC97DRIVER, Node)
     {
         if (!pDrvCur->pConnector)
@@ -3792,9 +3841,9 @@
 
         dstSrc.enmSrc = PDMAUDIORECSRC_MIC;
-        PAC97DRIVERSTREAM pDrvStrm = ichac97R3MixerGetDrvStream(pThis, pDrvCur, PDMAUDIODIR_IN, dstSrc);
+        PAC97DRIVERSTREAM pDrvStrm = ichac97R3MixerGetDrvStream(pDrvCur, PDMAUDIODIR_IN, dstSrc);
         if (   pDrvStrm
             && pDrvStrm->pMixStrm)
         {
-            rc2 = AudioMixerSinkSetRecordingSource(pThis->pSinkMicIn, pDrvStrm->pMixStrm);
+            rc2 = AudioMixerSinkSetRecordingSource(pThisCC->pSinkMicIn, pDrvStrm->pMixStrm);
             if (RT_SUCCESS(rc2))
                 LogRel2(("AC97: Set new recording source for 'Mic In' to '%s'\n", Cfg.szName));
@@ -3802,9 +3851,9 @@
 
         dstSrc.enmSrc = PDMAUDIORECSRC_LINE;
-        pDrvStrm = ichac97R3MixerGetDrvStream(pThis, pDrvCur, PDMAUDIODIR_IN, dstSrc);
+        pDrvStrm = ichac97R3MixerGetDrvStream(pDrvCur, PDMAUDIODIR_IN, dstSrc);
         if (   pDrvStrm
             && pDrvStrm->pMixStrm)
         {
-            rc2 = AudioMixerSinkSetRecordingSource(pThis->pSinkLineIn, pDrvStrm->pMixStrm);
+            rc2 = AudioMixerSinkSetRecordingSource(pThisCC->pSinkLineIn, pDrvStrm->pMixStrm);
             if (RT_SUCCESS(rc2))
                 LogRel2(("AC97: Set new recording source for 'Line In' to '%s'\n", Cfg.szName));
@@ -3821,5 +3870,6 @@
 static DECLCALLBACK(int) ichac97R3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
 {
-    PAC97STATE pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
 
     LogFunc(("iLUN=%u, fFlags=0x%x\n", iLUN, fFlags));
@@ -3828,7 +3878,7 @@
 
     PAC97DRIVER pDrv;
-    int rc2 = ichac97R3AttachInternal(pThis, iLUN, fFlags, &pDrv);
+    int rc2 = ichac97R3AttachInternal(pDevIns, pThisCC, iLUN, fFlags, &pDrv);
     if (RT_SUCCESS(rc2))
-        rc2 = ichac97R3MixerAddDrv(pThis, pDrv);
+        rc2 = ichac97R3MixerAddDrv(pThisCC, pDrv);
 
     if (RT_FAILURE(rc2))
@@ -3845,5 +3895,6 @@
 static DECLCALLBACK(void) ichac97R3Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
 {
-    PAC97STATE pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
 
     LogFunc(("iLUN=%u, fFlags=0x%x\n", iLUN, fFlags));
@@ -3852,9 +3903,9 @@
 
     PAC97DRIVER pDrv, pDrvNext;
-    RTListForEachSafe(&pThis->lstDrv, pDrv, pDrvNext, AC97DRIVER, Node)
+    RTListForEachSafe(&pThisCC->lstDrv, pDrv, pDrvNext, AC97DRIVER, Node)
     {
         if (pDrv->uLUN == iLUN)
         {
-            int rc2 = ichac97R3DetachInternal(pThis, pDrv, fFlags);
+            int rc2 = ichac97R3DetachInternal(pThisCC, pDrv, fFlags);
             if (RT_SUCCESS(rc2))
             {
@@ -3875,13 +3926,14 @@
  *
  * @returns VBox status code.
- * @param   pThis       Device instance.
+ * @param   pDevIns     The device instance.
+ * @param   pThis       The ring-3 AC'97 device state.
  * @param   iLun        The logical unit which is being replaced.
  */
-static int ichac97R3ReconfigLunWithNullAudio(PAC97STATE pThis, unsigned iLun)
-{
-    int rc = PDMDevHlpDriverReconfigure2(pThis->pDevInsR3, iLun, "AUDIO", "NullAudio");
+static int ichac97R3ReconfigLunWithNullAudio(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, unsigned iLun)
+{
+    int rc = PDMDevHlpDriverReconfigure2(pDevIns, iLun, "AUDIO", "NullAudio");
     if (RT_SUCCESS(rc))
-        rc = ichac97R3AttachInternal(pThis, iLun, 0 /* fFlags */, NULL /* ppDrv */);
-    LogFunc(("pThis=%p, iLun=%u, rc=%Rrc\n", pThis, iLun, rc));
+        rc = ichac97R3AttachInternal(pDevIns,  pThisCC, iLun, 0 /* fFlags */, NULL /* ppDrv */);
+    LogFunc(("pThisCC=%p, iLun=%u, rc=%Rrc\n", pThisCC, iLun, rc));
     return rc;
 }
@@ -3893,10 +3945,10 @@
 {
     PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns); /* this shall come first */
-    PAC97STATE pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
 
     LogFlowFuncEnter();
 
     PAC97DRIVER pDrv, pDrvNext;
-    RTListForEachSafe(&pThis->lstDrv, pDrv, pDrvNext, AC97DRIVER, Node)
+    RTListForEachSafe(&pThisCC->lstDrv, pDrv, pDrvNext, AC97DRIVER, Node)
     {
         RTListNodeRemove(&pDrv->Node);
@@ -3906,5 +3958,5 @@
 
     /* Sanity. */
-    Assert(RTListIsEmpty(&pThis->lstDrv));
+    Assert(RTListIsEmpty(&pThisCC->lstDrv));
 
     return VINF_SUCCESS;
@@ -3918,4 +3970,5 @@
     PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); /* this shall come first */
     PAC97STATE      pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATER3    pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
     PCPDMDEVHLPR3   pHlp    = pDevIns->pHlpR3;
     Assert(iInstance == 0); RT_NOREF(iInstance);
@@ -3924,7 +3977,7 @@
      * Initialize data so we can run the destructor without scewing up.
      */
-    pThis->pDevInsR3                = pDevIns;
-    pThis->IBase.pfnQueryInterface  = ichac97R3QueryInterface;
-    RTListInit(&pThis->lstDrv);
+    pThisCC->pDevIns                  = pDevIns;
+    pThisCC->IBase.pfnQueryInterface  = ichac97R3QueryInterface;
+    RTListInit(&pThisCC->lstDrv);
 
     /*
@@ -3947,10 +4000,10 @@
         LogRel(("AC97: Using custom device timer rate (%RU16Hz)\n", pThis->uTimerHz));
 
-    rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "DebugEnabled", &pThis->Dbg.fEnabled, false);
+    rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "DebugEnabled", &pThisCC->Dbg.fEnabled, false);
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("AC97 configuration error: failed to read debugging enabled flag as boolean"));
 
-    rc = pHlp->pfnCFGMQueryStringDef(pCfg, "DebugPathOut", pThis->Dbg.szOutPath, sizeof(pThis->Dbg.szOutPath),
+    rc = pHlp->pfnCFGMQueryStringDef(pCfg, "DebugPathOut", pThisCC->Dbg.szOutPath, sizeof(pThisCC->Dbg.szOutPath),
                                      VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH);
     if (RT_FAILURE(rc))
@@ -3958,6 +4011,6 @@
                                 N_("AC97 configuration error: failed to read debugging output path flag as string"));
 
-    if (pThis->Dbg.fEnabled)
-        LogRel2(("AC97: Debug output will be saved to '%s'\n", pThis->Dbg.szOutPath));
+    if (pThisCC->Dbg.fEnabled)
+        LogRel2(("AC97: Debug output will be saved to '%s'\n", pThisCC->Dbg.szOutPath));
 
     /*
@@ -4062,5 +4115,5 @@
         AssertBreak(iLun < UINT8_MAX);
         LogFunc(("Trying to attach driver for LUN#%u ...\n", iLun));
-        rc = ichac97R3AttachInternal(pThis, iLun, 0 /* fFlags */, NULL /* ppDrv */);
+        rc = ichac97R3AttachInternal(pDevIns, pThisCC, iLun, 0 /* fFlags */, NULL /* ppDrv */);
         if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
         {
@@ -4070,5 +4123,5 @@
         if (rc == VERR_AUDIO_BACKEND_INIT_FAILED)
         {
-            ichac97R3ReconfigLunWithNullAudio(pThis, iLun); /* Pretend attaching to the NULL audio backend will never fail. */
+            ichac97R3ReconfigLunWithNullAudio(pDevIns, pThisCC, iLun); /* Pretend attaching to the NULL audio backend will never fail. */
             PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
                                        N_("Host audio backend initialization has failed. "
@@ -4079,11 +4132,11 @@
     }
 
-    rc = AudioMixerCreate("AC'97 Mixer", 0 /* uFlags */, &pThis->pMixer);
+    rc = AudioMixerCreate("AC'97 Mixer", 0 /* uFlags */, &pThisCC->pMixer);
     AssertRCReturn(rc, rc);
-    rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThis->pSinkLineIn);
+    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThisCC->pSinkLineIn);
     AssertRCReturn(rc, rc);
-    rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThis->pSinkMicIn);
+    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThisCC->pSinkMicIn);
     AssertRCReturn(rc, rc);
-    rc = AudioMixerCreateSink(pThis->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThis->pSinkOut);
+    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThisCC->pSinkOut);
     AssertRCReturn(rc, rc);
 
@@ -4094,5 +4147,5 @@
     for (unsigned i = 0; i < AC97_MAX_STREAMS; i++)
     {
-        rc = ichac97R3StreamCreate(pThis, &pThis->aStreams[i], i /* SD# */);
+        rc = ichac97R3StreamCreate(pThisCC, &pThis->aStreams[i], &pThisCC->aStreams[i], i /* SD# */);
         AssertRCReturn(rc, rc);
     }
@@ -4123,5 +4176,5 @@
 # ifdef VBOX_WITH_AUDIO_AC97_ONETIME_INIT
     PAC97DRIVER pDrv;
-    RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node)
+    RTListForEach(&pThisCC->lstDrv, pDrv, AC97DRIVER, Node)
     {
         /*
@@ -4145,5 +4198,5 @@
             LogRel(("AC97: Falling back to NULL backend (no sound audible)\n"));
             ichac97R3Reset(pDevIns);
-            ichac97R3ReconfigLunWithNullAudio(pThis, iLun);
+            ichac97R3ReconfigLunWithNullAudio(pdEvIns, pThsiCC, iLun);
             PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
                                        N_("No audio devices could be opened. "
@@ -4269,5 +4322,5 @@
     /* .uSharedVersion = */         42,
     /* .cbInstanceShared = */       sizeof(AC97STATE),
-    /* .cbInstanceCC = */           0,
+    /* .cbInstanceCC = */           CTX_EXPR(sizeof(AC97STATER3), 0, 0),
     /* .cbInstanceRC = */           0,
     /* .cMaxPciDevices = */         1,
