VirtualBox

Changeset 82357 in vbox


Ignore:
Timestamp:
Dec 3, 2019 10:30:50 PM (5 years ago)
Author:
vboxsync
Message:

DevIchAc97: Split up the state structures. bugref:9218

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r82356 r82357  
    396396
    397397/**
    398  * An AC'97 stream.
     398 * The shared AC'97 stream state.
    399399 */
    400400typedef struct AC97STREAM
     
    405405    /** Bus master registers of this stream. */
    406406    AC97BMREGS              Regs;
     407    /** The timer for pumping data thru the attached LUN drivers. */
     408    TMTIMERHANDLE           hTimer;
     409} AC97STREAM;
     410AssertCompileSizeAlignment(AC97STREAM, 8);
     411/** Pointer to a shared AC'97 stream state. */
     412typedef AC97STREAM *PAC97STREAM;
     413
     414
     415/**
     416 * The ring-3 AC'97 stream state.
     417 */
     418typedef struct AC97STREAMR3
     419{
     420    /** Stream number (SDn). */
     421    uint8_t                 u8SD;
     422    uint8_t                 abPadding0[7];
    407423    /** Internal state of this stream. */
    408424    AC97STREAMSTATE         State;
    409     /** Pointer to parent (AC'97 state). */
    410     R3PTRTYPE(PAC97STATE)   pAC97State;
    411 #if HC_ARCH_BITS == 32
    412     uint32_t                Padding1;
    413 #endif
    414     /** The timer for pumping data thru the attached LUN drivers. */
    415     TMTIMERHANDLE           hTimer;
    416425    /** Debug stuff. */
    417426    AC97STREAMDEBUG         Dbg;
    418 } AC97STREAM;
    419 AssertCompileSizeAlignment(AC97STREAM, 8);
    420 /** Pointer to an AC'97 stream (registers + state). */
    421 typedef AC97STREAM *PAC97STREAM;
    422 
    423 typedef struct AC97STATE *PAC97STATE;
     427} AC97STREAMR3;
     428AssertCompileSizeAlignment(AC97STREAMR3, 8);
     429/** Pointer to an AC'97 stream state for ring-3. */
     430typedef AC97STREAMR3 *PAC97STREAMR3;
     431
     432
    424433#ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
    425434/**
     
    456465    /** Node for storing this driver in our device driver list of AC97STATE. */
    457466    RTLISTNODER3                    Node;
    458     /** Pointer to AC97 controller (state). */
    459     R3PTRTYPE(PAC97STATE)           pAC97State;
    460467    /** Driver flags. */
    461468    PDMAUDIODRVFLAGS                fFlags;
     
    501508    /** Critical section protecting the AC'97 state. */
    502509    PDMCRITSECT             CritSect;
    503     /** R3 pointer to the device instance. */
    504     PPDMDEVINSR3            pDevInsR3;
    505510    /** Global Control (Bus Master Control Register). */
    506511    uint32_t                glob_cnt;
     
    511516    uint32_t                last_samp;
    512517    uint8_t                 mixer_data[256];
    513     /** Array of AC'97 streams. */
     518    /** Array of AC'97 streams (parallel to AC97STATER3::aStreams). */
    514519    AC97STREAM              aStreams[AC97_MAX_STREAMS];
    515520    /** The device timer Hz rate. Defaults to AC97_TIMER_HZ_DEFAULT_DEFAULT. */
    516521    uint16_t                uTimerHz;
    517522    uint16_t                au16Padding1[3];
     523    uint8_t                 silence[128];
     524    int32_t                 bup_flag;
     525    /** Codec model. */
     526    uint32_t                uCodecModel;
     527
     528    /** PCI region \#0: NAM I/O ports. */
     529    IOMIOPORTHANDLE         hIoPortsNam;
     530    /** PCI region \#0: NANM I/O ports. */
     531    IOMIOPORTHANDLE         hIoPortsNabm;
     532
     533#ifdef VBOX_WITH_STATISTICS
     534    STAMPROFILE             StatTimer;
     535    STAMPROFILE             StatIn;
     536    STAMPROFILE             StatOut;
     537    STAMCOUNTER             StatBytesRead;
     538    STAMCOUNTER             StatBytesWritten;
     539#endif
     540} AC97STATE;
     541AssertCompileMemberAlignment(AC97STATE, aStreams, 8);
     542
     543
     544/**
     545 * The ring-3 AC'97 device state.
     546 */
     547typedef struct AC97STATER3
     548{
     549    /** Array of AC'97 streams (parallel to AC97STATE:aStreams). */
     550    AC97STREAMR3            aStreams[AC97_MAX_STREAMS];
     551    /** R3 pointer to the device instance. */
     552    PPDMDEVINSR3            pDevIns;
    518553    /** List of associated LUN drivers (AC97DRIVER). */
    519554    RTLISTANCHORR3          lstDrv;
     
    526561    /** Audio sink for microphone input. */
    527562    R3PTRTYPE(PAUDMIXSINK)  pSinkMicIn;
    528     uint8_t                 silence[128];
    529     int32_t                 bup_flag;
    530     /** Codec model. */
    531     uint32_t                uCodecModel;
    532563    /** The base interface for LUN\#0. */
    533564    PDMIBASE                IBase;
    534565    /** Debug settings. */
    535566    AC97STATEDEBUG          Dbg;
    536 
    537     /** PCI region \#0: NAM I/O ports. */
    538     IOMIOPORTHANDLE         hIoPortsNam;
    539     /** PCI region \#0: NANM I/O ports. */
    540     IOMIOPORTHANDLE         hIoPortsNabm;
    541 
    542 #ifdef VBOX_WITH_STATISTICS
    543     STAMPROFILE             StatTimer;
    544     STAMPROFILE             StatIn;
    545     STAMPROFILE             StatOut;
    546     STAMCOUNTER             StatBytesRead;
    547     STAMCOUNTER             StatBytesWritten;
    548 #endif
    549 } AC97STATE;
    550 AssertCompileMemberAlignment(AC97STATE, aStreams, 8);
     567} AC97STATER3;
     568AssertCompileMemberAlignment(AC97STATER3, aStreams, 8);
     569/** Pointer to the ring-3 AC'97 device state. */
     570typedef AC97STATER3 *PAC97STATER3;
    551571
    552572
     
    616636#ifdef IN_RING3
    617637static int                ichac97R3StreamCreate(PAC97STATE pThis, PAC97STREAM pStream, uint8_t u8Strm);
    618 static void               ichac97R3StreamDestroy(PAC97STATE pThis, PAC97STREAM pStream);
    619 static int                ichac97R3StreamOpen(PAC97STATE pThis, PAC97STREAM pStream, bool fForce);
    620 static int                ichac97R3StreamReOpen(PAC97STATE pThis, PAC97STREAM pStream, bool fForce);
    621 static int                ichac97R3StreamClose(PAC97STATE pThis, PAC97STREAM pStream);
    622 static void               ichac97R3StreamReset(PAC97STATE pThis, PAC97STREAM pStream);
    623 static void               ichac97R3StreamLock(PAC97STREAM pStream);
    624 static void               ichac97R3StreamUnlock(PAC97STREAM pStream);
    625 static uint32_t           ichac97R3StreamGetUsed(PAC97STREAM pStream);
    626 static uint32_t           ichac97R3StreamGetFree(PAC97STREAM pStream);
    627 static int                ichac97R3StreamTransfer(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbToProcessMax);
    628 static void               ichac97R3StreamUpdate(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream, bool fInTimer);
     638static int                ichac97R3StreamOpen(PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fForce);
     639static int                ichac97R3StreamClose(PAC97STREAM pStream);
     640static void               ichac97R3StreamLock(PAC97STREAMR3 pStreamCC);
     641static void               ichac97R3StreamUnlock(PAC97STREAMR3 pStreamCC);
     642static uint32_t           ichac97R3StreamGetUsed(PAC97STREAMR3 pStreamCC);
     643static uint32_t           ichac97R3StreamGetFree(PAC97STREAMR3 pStreamCC);
     644static int                ichac97R3StreamTransfer(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream,
     645                                                  PAC97STREAMR3 pStreamCC, uint32_t cbToProcessMax);
     646static void               ichac97R3StreamUpdate(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream,
     647                                                PAC97STREAMR3 pStreamCC, bool fInTimer);
    629648
    630649static DECLCALLBACK(void) ichac97R3Reset(PPDMDEVINS pDevIns);
     
    632651static DECLCALLBACK(void) ichac97R3Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser);
    633652
    634 static int                ichac97R3MixerAddDrv(PAC97STATE pThis, PAC97DRIVER pDrv);
    635 static int                ichac97R3MixerAddDrvStream(PAC97STATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PAC97DRIVER pDrv);
    636 static int                ichac97R3MixerAddDrvStreams(PAC97STATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg);
    637 static void               ichac97R3MixerRemoveDrv(PAC97STATE pThis, PAC97DRIVER pDrv);
    638 static void               ichac97R3MixerRemoveDrvStream(PAC97STATE pThis, PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc, PAC97DRIVER pDrv);
    639 static void               ichac97R3MixerRemoveDrvStreams(PAC97STATE pThis, PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc);
     653static void               ichac97R3MixerRemoveDrvStreams(PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir,
     654                                                         PDMAUDIODSTSRCUNION dstSrc);
    640655
    641656# ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
    642657static int                ichac97R3StreamAsyncIOCreate(PAC97STATE pThis, PAC97STREAM pStream);
    643658static int                ichac97R3StreamAsyncIODestroy(PAC97STATE pThis, PAC97STREAM pStream);
    644 static int                ichac97R3StreamAsyncIONotify(PAC97STATE pThis, PAC97STREAM pStream);
    645659static void               ichac97R3StreamAsyncIOLock(PAC97STREAM pStream);
    646660static void               ichac97R3StreamAsyncIOUnlock(PAC97STREAM pStream);
     
    649663
    650664DECLINLINE(PDMAUDIODIR)   ichac97GetDirFromSD(uint8_t uSD);
    651 
    652 # ifdef LOG_ENABLED
    653 static void               ichac97R3BDLEDumpAll(PAC97STATE pThis, uint64_t u64BDLBase, uint16_t cBDLE);
    654 # endif
    655665DECLINLINE(void)          ichac97R3TimerSet(PPDMDEVINS pDevIns, PAC97STREAM pStream, uint64_t cTicksToDeadline);
    656666#endif /* IN_RING3 */
     
    672682 *
    673683 * @returns Pointer to audio mixer sink if found, or NULL if not found / invalid.
    674  * @param   pThis              AC'97 state.
     684 * @param   pThisCC             The ring-3 AC'97 state.
    675685 * @param   uIndex              Stream index to get audio mixer sink for.
    676686 */
    677 DECLINLINE(PAUDMIXSINK) ichac97R3IndexToSink(PAC97STATE pThis, uint8_t uIndex)
     687DECLINLINE(PAUDMIXSINK) ichac97R3IndexToSink(PAC97STATER3 pThisCC, uint8_t uIndex)
    678688{
    679689    switch (uIndex)
    680690    {
    681         case AC97SOUNDSOURCE_PI_INDEX: return pThis->pSinkLineIn;
    682         case AC97SOUNDSOURCE_PO_INDEX: return pThis->pSinkOut;
    683         case AC97SOUNDSOURCE_MC_INDEX: return pThis->pSinkMicIn;
    684         default: break;
    685     }
    686 
    687     AssertMsgFailed(("Wrong index %RU8\n", uIndex));
    688     return NULL;
     691        case AC97SOUNDSOURCE_PI_INDEX: return pThisCC->pSinkLineIn;
     692        case AC97SOUNDSOURCE_PO_INDEX: return pThisCC->pSinkOut;
     693        case AC97SOUNDSOURCE_MC_INDEX: return pThisCC->pSinkMicIn;
     694        default:
     695            AssertMsgFailedReturn(("Wrong index %RU8\n", uIndex), NULL);
     696    }
    689697}
    690698
     
    693701 *
    694702 * @returns IPRT status code.
    695  * @param   pThis               AC'97 state.
     703 * @param   pDevIns             The device instance.
    696704 * @param   pStream             AC'97 stream to fetch BDLE for.
    697705 *
    698706 * @remark  Uses CIV as BDLE index.
    699707 */
    700 static void ichac97R3StreamFetchBDLE(PAC97STATE pThis, PAC97STREAM pStream)
    701 {
    702     PPDMDEVINS  pDevIns = ICHAC97STATE_2_DEVINS(pThis);
    703     PAC97BMREGS pRegs   = &pStream->Regs;
     708static void ichac97R3StreamFetchBDLE(PPDMDEVINS pDevIns, PAC97STREAM pStream)
     709{
     710    PAC97BMREGS pRegs = &pStream->Regs;
    704711
    705712    AC97BDLE BDLE;
     
    727734 *
    728735 * @param   pDevIns             The device instance.
    729  * @param   pThis               AC'97 state.
     736 * @param   pThis               The shared AC'97 state.
    730737 * @param   pStream             AC'97 stream to update SR for.
    731738 * @param   new_sr              New value for status register (SR).
     
    784791 *
    785792 * @param   pDevIns             The device instance.
    786  * @param   pThis               AC'97 device state.
     793 * @param   pThis               The shared AC'97 device state.
    787794 * @param   pStream             Stream to update SR for.
    788795 * @param   u32Val              New value to set the stream's SR to.
     
    804811 *
    805812 * @returns IPRT status code.
    806  * @param   pThis              AC'97 device state.
     813 * @param   pThisCC             The ring-3 AC'97 device state.
    807814 * @param   pStream             Stream to return status for.
    808815 */
    809 static bool ichac97R3StreamIsEnabled(PAC97STATE pThis, PAC97STREAM pStream)
    810 {
    811     PAUDMIXSINK pSink = ichac97R3IndexToSink(pThis, pStream->u8SD);
     816static bool ichac97R3StreamIsEnabled(PAC97STATER3 pThisCC, PAC97STREAM pStream)
     817{
     818    PAUDMIXSINK pSink = ichac97R3IndexToSink(pThisCC, pStream->u8SD);
    812819    bool fIsEnabled = RT_BOOL(AudioMixerSinkGetStatus(pSink) & AUDMIXSINK_STS_RUNNING);
    813820
     
    820827 *
    821828 * @returns IPRT status code.
    822  * @param   pThis               AC'97 state.
    823  * @param   pStream             AC'97 stream to enable or disable.
     829 * @param   pThis               The shared AC'97 state.
     830 * @param   pThisCC             The ring-3 AC'97 state.
     831 * @param   pStream             The AC'97 stream to enable or disable (shared
     832 *                              state).
     833 * @param   pStreamCC           The ring-3 stream state (matching to @a pStream).
    824834 * @param   fEnable             Whether to enable or disable the stream.
    825835 *
    826836 */
    827 static int ichac97R3StreamEnable(PAC97STATE pThis, PAC97STREAM pStream, bool fEnable)
    828 {
    829     ichac97R3StreamLock(pStream);
     837static int ichac97R3StreamEnable(PAC97STATE pThis, PAC97STATER3 pThisCC,
     838                                 PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fEnable)
     839{
     840    ichac97R3StreamLock(pStreamCC);
    830841
    831842    int rc = VINF_SUCCESS;
     
    840851    if (fEnable)
    841852    {
    842         if (pStream->State.pCircBuf)
    843             RTCircBufReset(pStream->State.pCircBuf);
    844 
    845         rc = ichac97R3StreamOpen(pThis, pStream, false /* fForce */);
    846 
    847         if (pStream->Dbg.Runtime.fEnabled)
    848         {
    849             if (!DrvAudioHlpFileIsOpen(pStream->Dbg.Runtime.pFileStream))
     853        if (pStreamCC->State.pCircBuf)
     854            RTCircBufReset(pStreamCC->State.pCircBuf);
     855
     856        rc = ichac97R3StreamOpen(pThis, pThisCC, pStream, pStreamCC, false /* fForce */);
     857
     858        if (RT_LIKELY(!pStreamCC->Dbg.Runtime.fEnabled))
     859        { /* likely */ }
     860        else
     861        {
     862            if (!DrvAudioHlpFileIsOpen(pStreamCC->Dbg.Runtime.pFileStream))
    850863            {
    851                 int rc2 = DrvAudioHlpFileOpen(pStream->Dbg.Runtime.pFileStream, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS,
    852                                               &pStream->State.Cfg.Props);
     864                int rc2 = DrvAudioHlpFileOpen(pStreamCC->Dbg.Runtime.pFileStream, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS,
     865                                              &pStreamCC->State.Cfg.Props);
    853866                AssertRC(rc2);
    854867            }
    855868
    856             if (!DrvAudioHlpFileIsOpen(pStream->Dbg.Runtime.pFileDMA))
     869            if (!DrvAudioHlpFileIsOpen(pStreamCC->Dbg.Runtime.pFileDMA))
    857870            {
    858                 int rc2 = DrvAudioHlpFileOpen(pStream->Dbg.Runtime.pFileDMA, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS,
    859                                               &pStream->State.Cfg.Props);
     871                int rc2 = DrvAudioHlpFileOpen(pStreamCC->Dbg.Runtime.pFileDMA, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS,
     872                                              &pStreamCC->State.Cfg.Props);
    860873                AssertRC(rc2);
    861874            }
     
    863876    }
    864877    else
    865         rc = ichac97R3StreamClose(pThis, pStream);
     878        rc = ichac97R3StreamClose(pStream);
    866879
    867880    if (RT_SUCCESS(rc))
    868881    {
    869882        /* First, enable or disable the stream and the stream's sink, if any. */
    870         rc = AudioMixerSinkCtl(ichac97R3IndexToSink(pThis, pStream->u8SD),
     883        rc = AudioMixerSinkCtl(ichac97R3IndexToSink(pThisCC, pStream->u8SD),
    871884                               fEnable ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE);
    872885    }
     
    877890
    878891    /* Make sure to leave the lock before (eventually) starting the timer. */
    879     ichac97R3StreamUnlock(pStream);
     892    ichac97R3StreamUnlock(pStreamCC);
    880893
    881894    LogFunc(("[SD%RU8] fEnable=%RTbool, rc=%Rrc\n", pStream->u8SD, fEnable, rc));
     
    886899 * Resets an AC'97 stream.
    887900 *
    888  * @param   pThis               AC'97 state.
    889  * @param   pStream             AC'97 stream to reset.
    890  *
    891  */
    892 static void ichac97R3StreamReset(PAC97STATE pThis, PAC97STREAM pStream)
    893 {
    894     ichac97R3StreamLock(pStream);
     901 * @param   pThis               The shared AC'97 state.
     902 * @param   pStream             The AC'97 stream to reset (shared).
     903 * @param   pStreamCC           The AC'97 stream to reset (ring-3).
     904 */
     905static void ichac97R3StreamReset(PAC97STATE pThis, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC)
     906{
     907    ichac97R3StreamLock(pStreamCC);
    895908
    896909    LogFunc(("[SD%RU8]\n", pStream->u8SD));
    897910
    898     if (pStream->State.pCircBuf)
    899         RTCircBufReset(pStream->State.pCircBuf);
     911    if (pStreamCC->State.pCircBuf)
     912        RTCircBufReset(pStreamCC->State.pCircBuf);
    900913
    901914    PAC97BMREGS pRegs = &pStream->Regs;
     
    912925    RT_ZERO(pThis->silence);
    913926
    914     ichac97R3StreamUnlock(pStream);
     927    ichac97R3StreamUnlock(pStreamCC);
    915928}
    916929
     
    919932 *
    920933 * @returns IPRT status code.
    921  * @param   pThis               AC'97 state.
    922  * @param   pStream             AC'97 stream to create.
     934 * @param   pThisCC             The ring-3 AC'97 state.
     935 * @param   pStream             The AC'97 stream to create (shared).
     936 * @param   pStreamCC           The AC'97 stream to create (ring-3).
    923937 * @param   u8SD                Stream descriptor number to assign.
    924938 */
    925 static int ichac97R3StreamCreate(PAC97STATE pThis, PAC97STREAM pStream, uint8_t u8SD)
    926 {
    927     RT_NOREF(pThis);
    928 
     939static int ichac97R3StreamCreate(PAC97STATER3 pThisCC, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, uint8_t u8SD)
     940{
    929941    LogFunc(("[SD%RU8] pStream=%p\n", u8SD, pStream));
    930942
    931943    AssertReturn(u8SD < AC97_MAX_STREAMS, VERR_INVALID_PARAMETER);
    932944    pStream->u8SD       = u8SD;
    933     pStream->pAC97State = pThis;
    934 
    935     int rc = RTCritSectInit(&pStream->State.CritSect);
     945    pStreamCC->u8SD     = u8SD;
     946
     947    int rc = RTCritSectInit(&pStreamCC->State.CritSect);
    936948    AssertRCReturn(rc, rc);
    937949
    938     pStream->Dbg.Runtime.fEnabled = pThis->Dbg.fEnabled;
    939 
    940     if (pStream->Dbg.Runtime.fEnabled)
     950    pStreamCC->Dbg.Runtime.fEnabled = pThisCC->Dbg.fEnabled;
     951
     952    if (RT_LIKELY(!pStreamCC->Dbg.Runtime.fEnabled))
     953    { /* likely */ }
     954    else
    941955    {
    942956        char szFile[64];
     
    948962
    949963        char szPath[RTPATH_MAX];
    950         int rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThis->Dbg.szOutPath, szFile,
     964        int rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThisCC->Dbg.szOutPath, szFile,
    951965                                         0 /* uInst */, PDMAUDIOFILETYPE_WAV, PDMAUDIOFILENAME_FLAGS_NONE);
    952966        AssertRC(rc2);
    953         rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAGS_NONE, &pStream->Dbg.Runtime.pFileStream);
     967        rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAGS_NONE, &pStreamCC->Dbg.Runtime.pFileStream);
    954968        AssertRC(rc2);
    955969
     
    959973            RTStrPrintf(szFile, sizeof(szFile), "ac97DMAReadSD%RU8", pStream->u8SD);
    960974
    961         rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThis->Dbg.szOutPath, szFile,
     975        rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThisCC->Dbg.szOutPath, szFile,
    962976                                     0 /* uInst */, PDMAUDIOFILETYPE_WAV, PDMAUDIOFILENAME_FLAGS_NONE);
    963977        AssertRC(rc2);
    964978
    965         rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAGS_NONE, &pStream->Dbg.Runtime.pFileDMA);
     979        rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAGS_NONE, &pStreamCC->Dbg.Runtime.pFileDMA);
    966980        AssertRC(rc2);
    967981
    968982        /* Delete stale debugging files from a former run. */
    969         DrvAudioHlpFileDelete(pStream->Dbg.Runtime.pFileStream);
    970         DrvAudioHlpFileDelete(pStream->Dbg.Runtime.pFileDMA);
     983        DrvAudioHlpFileDelete(pStreamCC->Dbg.Runtime.pFileStream);
     984        DrvAudioHlpFileDelete(pStreamCC->Dbg.Runtime.pFileDMA);
    971985    }
    972986
     
    978992 *
    979993 * @returns IPRT status code.
    980  * @param   pThis               AC'97 state.
    981  * @param   pStream             AC'97 stream to destroy.
    982  */
    983 static void ichac97R3StreamDestroy(PAC97STATE pThis, PAC97STREAM pStream)
     994 * @param   pThis               The shared AC'97 state.
     995 * @param   pStream             The AC'97 stream to destroy (shared).
     996 * @param   pStreamCC           The AC'97 stream to destroy (ring-3).
     997 */
     998static void ichac97R3StreamDestroy(PAC97STATE pThis, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC)
    984999{
    9851000    LogFlowFunc(("[SD%RU8]\n", pStream->u8SD));
    9861001
    987     ichac97R3StreamClose(pThis, pStream);
    988 
    989     int rc2 = RTCritSectDelete(&pStream->State.CritSect);
     1002    ichac97R3StreamClose(pStream);
     1003
     1004    int rc2 = RTCritSectDelete(&pStreamCC->State.CritSect);
    9901005    AssertRC(rc2);
    9911006
     
    9971012# endif
    9981013
    999     if (pStream->Dbg.Runtime.fEnabled)
    1000     {
    1001         DrvAudioHlpFileDestroy(pStream->Dbg.Runtime.pFileStream);
    1002         pStream->Dbg.Runtime.pFileStream = NULL;
    1003 
    1004         DrvAudioHlpFileDestroy(pStream->Dbg.Runtime.pFileDMA);
    1005         pStream->Dbg.Runtime.pFileDMA = NULL;
    1006     }
    1007 
    1008     if (pStream->State.pCircBuf)
    1009     {
    1010         RTCircBufDestroy(pStream->State.pCircBuf);
    1011         pStream->State.pCircBuf = NULL;
     1014    if (RT_LIKELY(!pStreamCC->Dbg.Runtime.fEnabled))
     1015    { /* likely */ }
     1016    else
     1017    {
     1018        DrvAudioHlpFileDestroy(pStreamCC->Dbg.Runtime.pFileStream);
     1019        pStreamCC->Dbg.Runtime.pFileStream = NULL;
     1020
     1021        DrvAudioHlpFileDestroy(pStreamCC->Dbg.Runtime.pFileDMA);
     1022        pStreamCC->Dbg.Runtime.pFileDMA = NULL;
     1023    }
     1024
     1025    if (pStreamCC->State.pCircBuf)
     1026    {
     1027        RTCircBufDestroy(pStreamCC->State.pCircBuf);
     1028        pStreamCC->State.pCircBuf = NULL;
    10121029    }
    10131030
     
    10181035 * Destroys all AC'97 audio streams of the device.
    10191036 *
    1020  * @param   pThis               AC'97 state.
    1021  */
    1022 static void ichac97R3StreamsDestroy(PAC97STATE pThis)
     1037 * @param   pThis               The shared AC'97 state.
     1038 * @param   pThisCC             The ring-3 AC'97 state.
     1039 */
     1040static void ichac97R3StreamsDestroy(PAC97STATE pThis, PAC97STATER3 pThisCC)
    10231041{
    10241042    LogFlowFuncEnter();
     
    10281046     */
    10291047    for (unsigned i = 0; i < AC97_MAX_STREAMS; i++)
    1030         ichac97R3StreamDestroy(pThis, &pThis->aStreams[i]);
     1048        ichac97R3StreamDestroy(pThis, &pThis->aStreams[i], &pThisCC->aStreams[i]);
    10311049
    10321050    /*
     
    10351053
    10361054    PDMAUDIODSTSRCUNION dstSrc;
    1037     if (pThis->pSinkLineIn)
     1055    if (pThisCC->pSinkLineIn)
    10381056    {
    10391057        dstSrc.enmSrc = PDMAUDIORECSRC_LINE;
    1040         ichac97R3MixerRemoveDrvStreams(pThis, pThis->pSinkLineIn, PDMAUDIODIR_IN, dstSrc);
    1041 
    1042         AudioMixerSinkDestroy(pThis->pSinkLineIn);
    1043         pThis->pSinkLineIn = NULL;
    1044     }
    1045 
    1046     if (pThis->pSinkMicIn)
     1058        ichac97R3MixerRemoveDrvStreams(pThisCC, pThisCC->pSinkLineIn, PDMAUDIODIR_IN, dstSrc);
     1059
     1060        AudioMixerSinkDestroy(pThisCC->pSinkLineIn);
     1061        pThisCC->pSinkLineIn = NULL;
     1062    }
     1063
     1064    if (pThisCC->pSinkMicIn)
    10471065    {
    10481066        dstSrc.enmSrc = PDMAUDIORECSRC_MIC;
    1049         ichac97R3MixerRemoveDrvStreams(pThis, pThis->pSinkMicIn, PDMAUDIODIR_IN, dstSrc);
    1050 
    1051         AudioMixerSinkDestroy(pThis->pSinkMicIn);
    1052         pThis->pSinkMicIn = NULL;
    1053     }
    1054 
    1055     if (pThis->pSinkOut)
     1067        ichac97R3MixerRemoveDrvStreams(pThisCC, pThisCC->pSinkMicIn, PDMAUDIODIR_IN, dstSrc);
     1068
     1069        AudioMixerSinkDestroy(pThisCC->pSinkMicIn);
     1070        pThisCC->pSinkMicIn = NULL;
     1071    }
     1072
     1073    if (pThisCC->pSinkOut)
    10561074    {
    10571075        dstSrc.enmDst = PDMAUDIOPLAYBACKDST_FRONT;
    1058         ichac97R3MixerRemoveDrvStreams(pThis, pThis->pSinkOut, PDMAUDIODIR_OUT, dstSrc);
    1059 
    1060         AudioMixerSinkDestroy(pThis->pSinkOut);
    1061         pThis->pSinkOut = NULL;
     1076        ichac97R3MixerRemoveDrvStreams(pThisCC, pThisCC->pSinkOut, PDMAUDIODIR_OUT, dstSrc);
     1077
     1078        AudioMixerSinkDestroy(pThisCC->pSinkOut);
     1079        pThisCC->pSinkOut = NULL;
    10621080    }
    10631081}
     
    10671085 *
    10681086 * @returns IPRT status code.
    1069  * @param   pThis               AC'97 state.
    1070  * @param   pDstStream          AC'97 stream to write to.
     1087 * @param   pDstStreamCC        The AC'97 stream to write to (ring-3).
    10711088 * @param   pSrcMixSink         Mixer sink to get audio data to write from.
    10721089 * @param   cbToWrite           Number of bytes to write.
    10731090 * @param   pcbWritten          Number of bytes written. Optional.
    10741091 */
    1075 static int ichac97R3StreamWrite(PAC97STATE pThis, PAC97STREAM pDstStream, PAUDMIXSINK pSrcMixSink, uint32_t cbToWrite,
    1076                                 uint32_t *pcbWritten)
    1077 {
    1078     RT_NOREF(pThis);
     1092static int ichac97R3StreamWrite(PAC97STREAMR3 pDstStreamCC, PAUDMIXSINK pSrcMixSink, uint32_t cbToWrite, uint32_t *pcbWritten)
     1093{
     1094    AssertPtrReturn(pSrcMixSink, VERR_INVALID_POINTER);
    10791095    AssertReturn(cbToWrite > 0,  VERR_INVALID_PARAMETER);
    10801096    /* pcbWritten is optional. */
    10811097
    1082     PRTCIRCBUF pCircBuf = pDstStream->State.pCircBuf;
     1098    PRTCIRCBUF pCircBuf = pDstStreamCC->State.pCircBuf;
    10831099    AssertPtr(pCircBuf);
    10841100
    1085     void *pvDst;
    1086     size_t cbDst;
    1087 
    10881101    uint32_t cbRead = 0;
    10891102
     1103    void    *pvDst;
     1104    size_t   cbDst;
    10901105    RTCircBufAcquireWriteBlock(pCircBuf, cbToWrite, &pvDst, &cbDst);
    10911106
     
    10951110        AssertRC(rc2);
    10961111
    1097         if (pDstStream->Dbg.Runtime.fEnabled)
    1098             DrvAudioHlpFileWrite(pDstStream->Dbg.Runtime.pFileStream, pvDst, cbRead, 0 /* fFlags */);
     1112        if (RT_LIKELY(!pDstStreamCC->Dbg.Runtime.fEnabled))
     1113        { /* likely */ }
     1114        else
     1115            DrvAudioHlpFileWrite(pDstStreamCC->Dbg.Runtime.pFileStream, pvDst, cbRead, 0 /* fFlags */);
    10991116    }
    11001117
     
    11111128 *
    11121129 * @returns IPRT status code.
    1113  * @param   pThis               AC'97 state.
    1114  * @param   pSrcStream          AC'97 stream to read audio data from.
     1130 * @param   pSrcStreamCC        AC'97 stream to read audio data from (ring-3).
    11151131 * @param   pDstMixSink         Mixer sink to write audio data to.
    11161132 * @param   cbToRead            Number of bytes to read.
    11171133 * @param   pcbRead             Number of bytes read. Optional.
    11181134 */
    1119 static int ichac97R3StreamRead(PAC97STATE pThis, PAC97STREAM pSrcStream, PAUDMIXSINK pDstMixSink, uint32_t cbToRead,
    1120                                uint32_t *pcbRead)
    1121 {
    1122     RT_NOREF(pThis);
     1135static int ichac97R3StreamRead(PAC97STREAMR3 pSrcStreamCC, PAUDMIXSINK pDstMixSink, uint32_t cbToRead, uint32_t *pcbRead)
     1136{
     1137    AssertPtrReturn(pDstMixSink, VERR_INVALID_POINTER);
    11231138    AssertReturn(cbToRead > 0, VERR_INVALID_PARAMETER);
    11241139    /* pcbRead is optional. */
    11251140
    1126     PRTCIRCBUF pCircBuf = pSrcStream->State.pCircBuf;
     1141    PRTCIRCBUF pCircBuf = pSrcStreamCC->State.pCircBuf;
    11271142    AssertPtr(pCircBuf);
    11281143
     
    11431158        if (cbSrc)
    11441159        {
    1145             if (pSrcStream->Dbg.Runtime.fEnabled)
    1146                 DrvAudioHlpFileWrite(pSrcStream->Dbg.Runtime.pFileStream, pvSrc, cbSrc, 0 /* fFlags */);
     1160            if (RT_LIKELY(!pSrcStreamCC->Dbg.Runtime.fEnabled))
     1161            { /* likely */ }
     1162            else
     1163                DrvAudioHlpFileWrite(pSrcStreamCC->Dbg.Runtime.pFileStream, pvSrc, cbSrc, 0 /* fFlags */);
    11471164
    11481165            rc = AudioMixerSinkWrite(pDstMixSink, AUDMIXOP_COPY, pvSrc, (uint32_t)cbSrc, &cbWritten);
     
    11501167
    11511168            Assert(cbSrc >= cbWritten);
    1152             Log3Func(("[SD%RU8] %RU32/%zu bytes read\n", pSrcStream->u8SD, cbWritten, cbSrc));
     1169            Log3Func(("[SD%RU8] %RU32/%zu bytes read\n", pSrcStreamCC->u8SD, cbWritten, cbSrc));
    11531170        }
    11541171
     
    11921209    AssertPtr(pStream);
    11931210
    1194     PAC97STREAMSTATEAIO pAIO = &pCtx->pStream->State.AIO;
     1211    PAC97STREAMSTATEAIO pAIO = &pCtx->pStreamCC->State.AIO;
    11951212
    11961213    ASMAtomicXchgBool(&pAIO->fStarted, true);
     
    12241241            }
    12251242
    1226             ichac97R3StreamUpdate(pDevIns, pThis, pStream, false /* fInTimer */);
     1243            ichac97R3StreamUpdate(pDevIns, pThis, pThisCC, pStream, pStreamCC, false /* fInTimer */);
    12271244
    12281245            int rc3 = RTCritSectLeave(&pAIO->CritSect);
     
    12441261 *
    12451262 * @returns IPRT status code.
    1246  * @param   pThis               AC'97 state.
     1263 * @param   pThis               The shared AC'97 state.
    12471264 * @param   pStream             AC'97 audio stream to create the async I/O thread for.
    12481265 */
    12491266static int ichac97R3StreamAsyncIOCreate(PAC97STATE pThis, PAC97STREAM pStream)
    12501267{
    1251     PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO;
     1268    PAC97STREAMSTATEAIO pAIO = &pStreamCC->State.AIO;
    12521269
    12531270    int rc;
     
    12981315
    12991316/**
     1317 * Lets the stream's async I/O thread know that there is some data to process.
     1318 *
     1319 * @returns IPRT status code.
     1320 * @param   pStreamCC             The AC'97 stream to notify async I/O thread
     1321 *                                for (ring-3).
     1322 */
     1323static int ichac97R3StreamAsyncIONotify(PAC97STREAM pStreamCC)
     1324{
     1325    LogFunc(("[SD%RU8]\n", pStreamCC->u8SD));
     1326    return RTSemEventSignal(pStreamCC->State.AIO.Event);
     1327}
     1328
     1329/**
    13001330 * Destroys the async I/O thread of a specific AC'97 audio stream.
    13011331 *
    13021332 * @returns IPRT status code.
    1303  * @param   pThis               AC'97 state.
     1333 * @param   pThis               The shared AC'97 state.
    13041334 * @param   pStream             AC'97 audio stream to destroy the async I/O thread for.
    13051335 */
    13061336static int ichac97R3StreamAsyncIODestroy(PAC97STATE pThis, PAC97STREAM pStream)
    13071337{
    1308     PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO;
     1338    PAC97STREAMSTATEAIO pAIO = &pStreamCC->State.AIO;
    13091339
    13101340    if (!ASMAtomicReadBool(&pAIO->fStarted))
     
    13131343    ASMAtomicWriteBool(&pAIO->fShutdown, true);
    13141344
    1315     int rc = ichac97R3StreamAsyncIONotify(pThis, pStream);
     1345    int rc = ichac97R3StreamAsyncIONotify(pStreamCC);
    13161346    AssertRC(rc);
    13171347
     
    13381368
    13391369/**
    1340  * Lets the stream's async I/O thread know that there is some data to process.
    1341  *
    1342  * @returns IPRT status code.
    1343  * @param   pThis               AC'97 state.
    1344  * @param   pStream             AC'97 stream to notify async I/O thread for.
    1345  */
    1346 static int ichac97R3StreamAsyncIONotify(PAC97STATE pThis, PAC97STREAM pStream)
    1347 {
    1348     RT_NOREF(pThis);
    1349 
    1350     LogFunc(("[SD%RU8]\n", pStream->u8SD));
    1351     return RTSemEventSignal(pStream->State.AIO.Event);
    1352 }
    1353 
    1354 /**
    13551370 * Locks the async I/O thread of a specific AC'97 audio stream.
    13561371 *
     
    13591374static void ichac97R3StreamAsyncIOLock(PAC97STREAM pStream)
    13601375{
    1361     PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO;
     1376    PAC97STREAMSTATEAIO pAIO = &pStreamCC->State.AIO;
    13621377
    13631378    if (!ASMAtomicReadBool(&pAIO->fStarted))
     
    13751390static void ichac97R3StreamAsyncIOUnlock(PAC97STREAM pStream)
    13761391{
    1377     PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO;
     1392    PAC97STREAMSTATEAIO pAIO = &pStreamCC->State.AIO;
    13781393
    13791394    if (!ASMAtomicReadBool(&pAIO->fStarted))
     
    13951410static void ichac97R3StreamAsyncIOEnable(PAC97STREAM pStream, bool fEnable)
    13961411{
    1397     PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO;
     1412    PAC97STREAMSTATEAIO pAIO = &pStreamCC->State.AIO;
    13981413    ASMAtomicXchgBool(&pAIO->fEnabled, fEnable);
    13991414}
     
    14021417
    14031418# ifdef LOG_ENABLED
    1404 static void ichac97R3BDLEDumpAll(PAC97STATE pThis, uint64_t u64BDLBase, uint16_t cBDLE)
     1419static void ichac97R3BDLEDumpAll(PPDMDEVINS pDevIns, uint64_t u64BDLBase, uint16_t cBDLE)
    14051420{
    14061421    LogFlowFunc(("BDLEs @ 0x%x (%RU16):\n", u64BDLBase, cBDLE));
     
    14121427    {
    14131428        AC97BDLE BDLE;
    1414         PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), u64BDLBase + i * sizeof(AC97BDLE), &BDLE, sizeof(AC97BDLE));
     1429        PDMDevHlpPhysRead(pDevIns, u64BDLBase + i * sizeof(AC97BDLE), &BDLE, sizeof(AC97BDLE));
    14151430
    14161431# ifndef RT_LITTLE_ENDIAN
     
    14501465 *
    14511466 * @param   pDevIns             The device instance.
    1452  * @param   pThis               AC'97 state.
    1453  * @param   pStream             AC'97 stream to update.
     1467 * @param   pThis               The shared AC'97 state.
     1468 * @param   pThisCC             The ring-3 AC'97 state.
     1469 * @param   pStream             The AC'97 stream to update (shared).
     1470 * @param   pStreamCC           The AC'97 stream to update (ring-3).
    14541471 * @param   fInTimer            Whether to this function was called from the timer
    14551472 *                              context or an asynchronous I/O stream thread (if supported).
    14561473 */
    1457 static void ichac97R3StreamUpdate(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream, bool fInTimer)
     1474static void ichac97R3StreamUpdate(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATER3 pThisCC,
     1475                                  PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fInTimer)
    14581476{
    14591477    RT_NOREF(fInTimer);
    14601478
    1461     PAUDMIXSINK pSink = ichac97R3IndexToSink(pThis, pStream->u8SD);
     1479    PAUDMIXSINK pSink = ichac97R3IndexToSink(pThisCC, pStream->u8SD);
    14621480    AssertPtr(pSink);
    14631481
     
    14671485    int rc2;
    14681486
    1469     if (pStream->State.Cfg.enmDir == PDMAUDIODIR_OUT) /* Output (SDO). */
     1487    if (pStreamCC->State.Cfg.enmDir == PDMAUDIODIR_OUT) /* Output (SDO). */
    14701488    {
    14711489# ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
     
    14731491# endif
    14741492        {
    1475             const uint32_t cbStreamFree = ichac97R3StreamGetFree(pStream);
     1493            const uint32_t cbStreamFree = ichac97R3StreamGetFree(pStreamCC);
    14761494            if (cbStreamFree)
    14771495            {
    14781496                Log3Func(("[SD%RU8] PICB=%zu (%RU64ms), cbFree=%zu (%RU64ms), cbTransferChunk=%zu (%RU64ms)\n",
    14791497                          pStream->u8SD,
    1480                           (pStream->Regs.picb << 1), DrvAudioHlpBytesToMilli((pStream->Regs.picb << 1), &pStream->State.Cfg.Props),
    1481                           cbStreamFree, DrvAudioHlpBytesToMilli(cbStreamFree, &pStream->State.Cfg.Props),
    1482                           pStream->State.cbTransferChunk, DrvAudioHlpBytesToMilli(pStream->State.cbTransferChunk, &pStream->State.Cfg.Props)));
     1498                          (pStream->Regs.picb << 1), DrvAudioHlpBytesToMilli((pStream->Regs.picb << 1), &pStreamCC->State.Cfg.Props),
     1499                          cbStreamFree, DrvAudioHlpBytesToMilli(cbStreamFree, &pStreamCC->State.Cfg.Props),
     1500                          pStreamCC->State.cbTransferChunk, DrvAudioHlpBytesToMilli(pStreamCC->State.cbTransferChunk, &pStreamCC->State.Cfg.Props)));
    14831501
    14841502                /* Do the DMA transfer. */
    1485                 rc2 = ichac97R3StreamTransfer(pDevIns, pThis, pStream, RT_MIN(pStream->State.cbTransferChunk, cbStreamFree));
     1503                rc2 = ichac97R3StreamTransfer(pDevIns, pThis, pStream, pStreamCC,
     1504                                              RT_MIN(pStreamCC->State.cbTransferChunk, cbStreamFree));
    14861505                AssertRC(rc2);
    14871506
    1488                 pStream->State.tsLastUpdateNs = RTTimeNanoTS();
     1507                pStreamCC->State.tsLastUpdateNs = RTTimeNanoTS();
    14891508            }
    14901509        }
     
    14931512
    14941513# ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
    1495         rc2 = ichac97R3StreamAsyncIONotify(pThis, pStream);
     1514        rc2 = ichac97R3StreamAsyncIONotify(pStreamCC);
    14961515        AssertRC(rc2);
    14971516# endif
     
    15021521# endif
    15031522            const uint32_t cbSinkWritable     = AudioMixerSinkGetWritable(pSink);
    1504             const uint32_t cbStreamReadable   = ichac97R3StreamGetUsed(pStream);
     1523            const uint32_t cbStreamReadable   = ichac97R3StreamGetUsed(pStreamCC);
    15051524            const uint32_t cbToReadFromStream = RT_MIN(cbStreamReadable, cbSinkWritable);
    15061525
     
    15101529            {
    15111530                /* Read (guest output) data and write it to the stream's sink. */
    1512                 rc2 = ichac97R3StreamRead(pThis, pStream, pSink, cbToReadFromStream, NULL /* pcbRead */);
     1531                rc2 = ichac97R3StreamRead(pStreamCC, pSink, cbToReadFromStream, NULL /* pcbRead */);
    15131532                AssertRC(rc2);
    15141533            }
     
    15341553
    15351554            /* How much (guest input) data is available for writing at the moment for the AC'97 stream? */
    1536             uint32_t cbStreamFree = ichac97R3StreamGetFree(pStream);
     1555            uint32_t cbStreamFree = ichac97R3StreamGetFree(pStreamCC);
    15371556
    15381557            Log3Func(("[SD%RU8] cbSinkReadable=%RU32, cbStreamFree=%RU32\n", pStream->u8SD, cbSinkReadable, cbStreamFree));
     
    15461565            {
    15471566                /* Write (guest input) data to the stream which was read from stream's sink before. */
    1548                 rc2 = ichac97R3StreamWrite(pThis, pStream, pSink, cbSinkReadable, NULL /* pcbWritten */);
     1567                rc2 = ichac97R3StreamWrite(pStreamCC, pSink, cbSinkReadable, NULL /* pcbWritten */);
    15491568                AssertRC(rc2);
    15501569            }
     
    15571576# ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
    15581577            const uint64_t tsNowNs = RTTimeNanoTS();
    1559             if (tsNowNs - pStream->State.tsLastUpdateNs >= pStream->State.Cfg.Device.cMsSchedulingHint * RT_NS_1MS)
     1578            if (tsNowNs - pStreamCC->State.tsLastUpdateNs >= pStreamCC->State.Cfg.Device.cMsSchedulingHint * RT_NS_1MS)
    15601579            {
    1561                 rc2 = ichac97R3StreamAsyncIONotify(pThis, pStream);
     1580                rc2 = ichac97R3StreamAsyncIONotify(pStreamCC);
    15621581                AssertRC(rc2);
    15631582
    1564                 pStream->State.tsLastUpdateNs = tsNowNs;
     1583                pStreamCC->State.tsLastUpdateNs = tsNowNs;
    15651584            }
    15661585# endif
    15671586
    1568             const uint32_t cbStreamUsed = ichac97R3StreamGetUsed(pStream);
     1587            const uint32_t cbStreamUsed = ichac97R3StreamGetUsed(pStreamCC);
    15691588            if (cbStreamUsed)
    15701589            {
    15711590                /* When running synchronously, do the DMA data transfers here.
    15721591                 * Otherwise this will be done in the stream's async I/O thread. */
    1573                 rc2 = ichac97R3StreamTransfer(pDevIns, pThis, pStream, cbStreamUsed);
     1592                rc2 = ichac97R3StreamTransfer(pDevIns, pThis, pStream, pStreamCC, cbStreamUsed);
    15741593                AssertRC(rc2);
    15751594            }
     
    15861605 *
    15871606 * @returns IPRT status code.
    1588  * @param   pThis               AC'97 state.
     1607 * @param   pThis               The shared AC'97 state.
    15891608 * @param   uMixerIdx           Mixer control to set value for.
    15901609 * @param   uVal                Value to set.
     
    16061625 *
    16071626 * @returns Retrieved mixer control value.
    1608  * @param   pThis               AC'97 state.
     1627 * @param   pThis               The shared AC'97 state.
    16091628 * @param   uMixerIdx           Mixer control to get value for.
    16101629 */
     
    16231642 *
    16241643 * @returns Pointer to driver stream if found, or NULL if not found.
    1625  * @param   pThis               AC'97 state.
    16261644 * @param   pDrv                Driver to retrieve driver stream for.
    16271645 * @param   enmDir              Stream direction to retrieve.
    16281646 * @param   dstSrc              Stream destination / source to retrieve.
    16291647 */
    1630 static PAC97DRIVERSTREAM ichac97R3MixerGetDrvStream(PAC97STATE pThis, PAC97DRIVER pDrv,
    1631                                                     PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc)
    1632 {
    1633     RT_NOREF(pThis);
    1634 
     1648static PAC97DRIVERSTREAM ichac97R3MixerGetDrvStream(PAC97DRIVER pDrv, PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc)
     1649{
    16351650    PAC97DRIVERSTREAM pDrvStream = NULL;
    16361651
     
    16761691 *
    16771692 * @returns IPRT status code.
    1678  * @param   pThis               AC'97 state.
    16791693 * @param   pMixSink            Mixer sink to add driver stream to.
    16801694 * @param   pCfg                Stream configuration to use.
    16811695 * @param   pDrv                Driver stream to add.
    16821696 */
    1683 static int ichac97R3MixerAddDrvStream(PAC97STATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PAC97DRIVER pDrv)
     1697static int ichac97R3MixerAddDrvStream(PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PAC97DRIVER pDrv)
    16841698{
    16851699    AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
     
    16991713    int rc;
    17001714
    1701     PAC97DRIVERSTREAM pDrvStream = ichac97R3MixerGetDrvStream(pThis, pDrv, pStreamCfg->enmDir, pStreamCfg->u);
     1715    PAC97DRIVERSTREAM pDrvStream = ichac97R3MixerGetDrvStream(pDrv, pStreamCfg->enmDir, pStreamCfg->u);
    17021716    if (pDrvStream)
    17031717    {
     
    17581772 *
    17591773 * @returns IPRT status code.
    1760  * @param   pThis               AC'97 state.
     1774 * @param   pThis               The shared AC'97 state.
    17611775 * @param   pMixSink            Mixer sink to add stream to.
    17621776 * @param   pCfg                Stream configuration to use.
    17631777 */
    1764 static int ichac97R3MixerAddDrvStreams(PAC97STATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg)
     1778static int ichac97R3MixerAddDrvStreams(PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg)
    17651779{
    17661780    AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
     
    17741788
    17751789    PAC97DRIVER pDrv;
    1776     RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node)
    1777     {
    1778         int rc2 = ichac97R3MixerAddDrvStream(pThis, pMixSink, pCfg, pDrv);
     1790    RTListForEach(&pThisCC->lstDrv, pDrv, AC97DRIVER, Node)
     1791    {
     1792        int rc2 = ichac97R3MixerAddDrvStream(pMixSink, pCfg, pDrv);
    17791793        if (RT_FAILURE(rc2))
    17801794            LogFunc(("Attaching stream failed with %Rrc\n", rc2));
     
    17921806 *
    17931807 * @return IPRT status code.
    1794  * @param  pThis                AC'97 state.
    1795  * @param  pDrv                 AC'97 driver to add.
    1796  */
    1797 static int ichac97R3MixerAddDrv(PAC97STATE pThis, PAC97DRIVER pDrv)
     1808 * @param  pThis                The ring-3 AC'97 device state.
     1809 * @param  pDrv                 The AC'97 driver to add.
     1810 */
     1811static int ichac97R3MixerAddDrv(PAC97STATER3 pThisCC, PAC97DRIVER pDrv)
    17981812{
    17991813    int rc = VINF_SUCCESS;
    18001814
    1801     if (DrvAudioHlpStreamCfgIsValid(&pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX].State.Cfg))
    1802     {
    1803         int rc2 = ichac97R3MixerAddDrvStream(pThis, pThis->pSinkLineIn,
    1804                                              &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX].State.Cfg, pDrv);
     1815    if (DrvAudioHlpStreamCfgIsValid(&pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX].State.Cfg))
     1816        rc = ichac97R3MixerAddDrvStream(pThisCC->pSinkLineIn, &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX].State.Cfg, pDrv);
     1817
     1818    if (DrvAudioHlpStreamCfgIsValid(&pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX].State.Cfg))
     1819    {
     1820        int rc2 = ichac97R3MixerAddDrvStream(pThisCC->pSinkOut, &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX].State.Cfg, pDrv);
    18051821        if (RT_SUCCESS(rc))
    18061822            rc = rc2;
    18071823    }
    18081824
    1809     if (DrvAudioHlpStreamCfgIsValid(&pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX].State.Cfg))
    1810     {
    1811         int rc2 = ichac97R3MixerAddDrvStream(pThis, pThis->pSinkOut,
    1812                                              &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX].State.Cfg, pDrv);
     1825    if (DrvAudioHlpStreamCfgIsValid(&pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX].State.Cfg))
     1826    {
     1827        int rc2 = ichac97R3MixerAddDrvStream(pThisCC->pSinkMicIn, &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX].State.Cfg, pDrv);
    18131828        if (RT_SUCCESS(rc))
    18141829            rc = rc2;
    18151830    }
    18161831
    1817     if (DrvAudioHlpStreamCfgIsValid(&pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX].State.Cfg))
    1818     {
    1819         int rc2 = ichac97R3MixerAddDrvStream(pThis, pThis->pSinkMicIn,
    1820                                              &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX].State.Cfg, pDrv);
    1821         if (RT_SUCCESS(rc))
    1822             rc = rc2;
    1823     }
    1824 
    18251832    return rc;
    18261833}
     
    18301837 * associated streams.
    18311838 *
    1832  * @param pThis                 AC'97 state.
     1839 * @param pThis                 The ring-3 AC'97 device state.
    18331840 * @param pDrv                  AC'97 driver to remove.
    18341841 */
    1835 static void ichac97R3MixerRemoveDrv(PAC97STATE pThis, PAC97DRIVER pDrv)
     1842static void ichac97R3MixerRemoveDrv(PAC97STATER3 pThisCC, PAC97DRIVER pDrv)
    18361843{
    18371844    if (pDrv->MicIn.pMixStrm)
    18381845    {
    1839         if (AudioMixerSinkGetRecordingSource(pThis->pSinkMicIn) == pDrv->MicIn.pMixStrm)
    1840             AudioMixerSinkSetRecordingSource(pThis->pSinkMicIn, NULL);
    1841 
    1842         AudioMixerSinkRemoveStream(pThis->pSinkMicIn,  pDrv->MicIn.pMixStrm);
     1846        if (AudioMixerSinkGetRecordingSource(pThisCC->pSinkMicIn) == pDrv->MicIn.pMixStrm)
     1847            AudioMixerSinkSetRecordingSource(pThisCC->pSinkMicIn, NULL);
     1848
     1849        AudioMixerSinkRemoveStream(pThisCC->pSinkMicIn,  pDrv->MicIn.pMixStrm);
    18431850        AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm);
    18441851        pDrv->MicIn.pMixStrm = NULL;
     
    18471854    if (pDrv->LineIn.pMixStrm)
    18481855    {
    1849         if (AudioMixerSinkGetRecordingSource(pThis->pSinkLineIn) == pDrv->LineIn.pMixStrm)
    1850             AudioMixerSinkSetRecordingSource(pThis->pSinkLineIn, NULL);
    1851 
    1852         AudioMixerSinkRemoveStream(pThis->pSinkLineIn, pDrv->LineIn.pMixStrm);
     1856        if (AudioMixerSinkGetRecordingSource(pThisCC->pSinkLineIn) == pDrv->LineIn.pMixStrm)
     1857            AudioMixerSinkSetRecordingSource(pThisCC->pSinkLineIn, NULL);
     1858
     1859        AudioMixerSinkRemoveStream(pThisCC->pSinkLineIn, pDrv->LineIn.pMixStrm);
    18531860        AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm);
    18541861        pDrv->LineIn.pMixStrm = NULL;
     
    18571864    if (pDrv->Out.pMixStrm)
    18581865    {
    1859         AudioMixerSinkRemoveStream(pThis->pSinkOut,    pDrv->Out.pMixStrm);
     1866        AudioMixerSinkRemoveStream(pThisCC->pSinkOut,    pDrv->Out.pMixStrm);
    18601867        AudioMixerStreamDestroy(pDrv->Out.pMixStrm);
    18611868        pDrv->Out.pMixStrm = NULL;
     
    18681875 * Removes a driver stream from a specific mixer sink.
    18691876 *
    1870  * @param   pThis               AC'97 state.
    18711877 * @param   pMixSink            Mixer sink to remove audio streams from.
    18721878 * @param   enmDir              Stream direction to remove.
     
    18741880 * @param   pDrv                Driver stream to remove.
    18751881 */
    1876 static void ichac97R3MixerRemoveDrvStream(PAC97STATE pThis, PAUDMIXSINK pMixSink,
    1877                                           PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc, PAC97DRIVER pDrv)
    1878 {
    1879     PAC97DRIVERSTREAM pDrvStream = ichac97R3MixerGetDrvStream(pThis, pDrv, enmDir, dstSrc);
     1882static void ichac97R3MixerRemoveDrvStream(PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc, PAC97DRIVER pDrv)
     1883{
     1884    PAC97DRIVERSTREAM pDrvStream = ichac97R3MixerGetDrvStream(pDrv, enmDir, dstSrc);
    18801885    if (pDrvStream)
    18811886    {
     
    18931898 * Removes all driver streams from a specific mixer sink.
    18941899 *
    1895  * @param   pThis               AC'97 state.
     1900 * @param   pThis               The ring-3 AC'97 state.
    18961901 * @param   pMixSink            Mixer sink to remove audio streams from.
    18971902 * @param   enmDir              Stream direction to remove.
    18981903 * @param   dstSrc              Stream destination / source to remove.
    18991904 */
    1900 static void ichac97R3MixerRemoveDrvStreams(PAC97STATE pThis, PAUDMIXSINK pMixSink,
     1905static void ichac97R3MixerRemoveDrvStreams(PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink,
    19011906                                           PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc)
    19021907{
     
    19041909
    19051910    PAC97DRIVER pDrv;
    1906     RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node)
    1907     {
    1908         ichac97R3MixerRemoveDrvStream(pThis, pMixSink, enmDir, dstSrc, pDrv);
     1911    RTListForEach(&pThisCC->lstDrv, pDrv, AC97DRIVER, Node)
     1912    {
     1913        ichac97R3MixerRemoveDrvStream(pMixSink, enmDir, dstSrc, pDrv);
    19091914    }
    19101915}
     
    19151920 * @returns Calculated ticks
    19161921 * @param   pDevIns             The device instance.
    1917  * @param   pStream             AC'97 stream to calculate ticks for.
     1922 * @param   pStream             AC'97 stream to calculate ticks for (shared).
     1923 * @param   pStreamCC           AC'97 stream to calculate ticks for (ring-3).
    19181924 * @param   cbBytes             Bytes to calculate ticks for.
    19191925 */
    1920 static uint64_t ichac97R3StreamTransferCalcNext(PPDMDEVINS pDevIns, PAC97STREAM pStream, uint32_t cbBytes)
     1926static uint64_t ichac97R3StreamTransferCalcNext(PPDMDEVINS pDevIns, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, uint32_t cbBytes)
    19211927{
    19221928    if (!cbBytes)
    19231929        return 0;
    19241930
    1925     const uint64_t usBytes        = DrvAudioHlpBytesToMicro(cbBytes, &pStream->State.Cfg.Props);
     1931    const uint64_t usBytes        = DrvAudioHlpBytesToMicro(cbBytes, &pStreamCC->State.Cfg.Props);
    19261932    const uint64_t cTransferTicks = PDMDevHlpTimerFromMicro(pDevIns, pStream->hTimer, usBytes);
    19271933
    19281934    Log3Func(("[SD%RU8] Timer %uHz, cbBytes=%RU32 -> usBytes=%RU64, cTransferTicks=%RU64\n",
    1929               pStream->u8SD, pStream->State.uTimerHz, cbBytes, usBytes, cTransferTicks));
     1935              pStream->u8SD, pStreamCC->State.uTimerHz, cbBytes, usBytes, cTransferTicks));
    19301936
    19311937    return cTransferTicks;
     
    19361942 *
    19371943 * @param   pDevIns             The device instance.
    1938  * @param   pStream             AC'97 stream to update.
     1944 * @param   pStream             The AC'97 stream to update (shared).
     1945 * @param   pStreamCC           The AC'97 stream to update (ring-3).
    19391946 * @param   cbBytes             Bytes to update next transfer for.
    19401947 */
    1941 static void ichac97R3StreamTransferUpdate(PPDMDEVINS pDevIns, PAC97STREAM pStream, uint32_t cbBytes)
     1948static void ichac97R3StreamTransferUpdate(PPDMDEVINS pDevIns, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, uint32_t cbBytes)
    19421949{
    19431950    if (!cbBytes)
     
    19461953    /* Calculate the bytes we need to transfer to / from the stream's DMA per iteration.
    19471954     * This is bound to the device's Hz rate and thus to the (virtual) timing the device expects. */
    1948     pStream->State.cbTransferChunk = cbBytes;
     1955    pStreamCC->State.cbTransferChunk = cbBytes;
    19491956
    19501957    /* Update the transfer ticks. */
    1951     pStream->State.cTransferTicks = ichac97R3StreamTransferCalcNext(pDevIns, pStream, pStream->State.cbTransferChunk);
    1952     Assert(pStream->State.cTransferTicks); /* Paranoia. */
     1958    pStreamCC->State.cTransferTicks = ichac97R3StreamTransferCalcNext(pDevIns, pStream, pStreamCC,
     1959                                                                      pStreamCC->State.cbTransferChunk);
     1960    Assert(pStreamCC->State.cTransferTicks); /* Paranoia. */
    19531961}
    19541962
     
    19601968 *
    19611969 * @returns IPRT status code.
    1962  * @param   pThis               AC'97 device state.
    1963  * @param   pStream             AC'97 stream to open.
     1970 * @param   pThis               The shared AC'97 device state (shared).
     1971 * @param   pThisCC             The shared AC'97 device state (ring-3).
     1972 * @param   pStream             The AC'97 stream to open (shared).
     1973 * @param   pStreamCC           The AC'97 stream to open (ring-3).
    19641974 * @param   fForce              Whether to force re-opening the stream or not.
    19651975 *                              Otherwise re-opening only will happen if the PCM properties have changed.
    19661976 */
    1967 static int ichac97R3StreamOpen(PAC97STATE pThis, PAC97STREAM pStream, bool fForce)
    1968 {
    1969     int rc = VINF_SUCCESS;
    1970 
     1977static int ichac97R3StreamOpen(PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fForce)
     1978{
    19711979    PDMAUDIOSTREAMCFG Cfg;
    19721980    RT_ZERO(Cfg);
    1973 
    1974     PAUDMIXSINK pMixSink = NULL;
    1975 
    19761981    Cfg.Props.cChannels = 2;
    19771982    Cfg.Props.cbSample  = 2 /* 16-bit */;
     
    19791984    Cfg.Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(Cfg.Props.cbSample, Cfg.Props.cChannels);
    19801985
     1986    int rc = VINF_SUCCESS;
     1987    PAUDMIXSINK pMixSink;
    19811988    switch (pStream->u8SD)
    19821989    {
     
    19891996            RTStrCopy(Cfg.szName, sizeof(Cfg.szName), "Line-In");
    19901997
    1991             pMixSink        = pThis->pSinkLineIn;
     1998            pMixSink        = pThisCC->pSinkLineIn;
    19921999            break;
    19932000        }
     
    20012008            RTStrCopy(Cfg.szName, sizeof(Cfg.szName), "Mic-In");
    20022009
    2003             pMixSink        = pThis->pSinkMicIn;
     2010            pMixSink        = pThisCC->pSinkMicIn;
    20042011            break;
    20052012        }
     
    20132020            RTStrCopy(Cfg.szName, sizeof(Cfg.szName), "Output");
    20142021
    2015             pMixSink        = pThis->pSinkOut;
     2022            pMixSink        = pThisCC->pSinkOut;
    20162023            break;
    20172024        }
     
    20192026        default:
    20202027            rc = VERR_NOT_SUPPORTED;
     2028            pMixSink = NULL;
    20212029            break;
    20222030    }
     
    20262034        /* Only (re-)create the stream (and driver chain) if we really have to.
    20272035         * Otherwise avoid this and just reuse it, as this costs performance. */
    2028         if (   !DrvAudioHlpPCMPropsAreEqual(&Cfg.Props, &pStream->State.Cfg.Props)
     2036        if (   !DrvAudioHlpPCMPropsAreEqual(&Cfg.Props, &pStreamCC->State.Cfg.Props)
    20292037            || fForce)
    20302038        {
     
    20442052                {
    20452053                    if (Cfg.Props.uHz > 44100) /* E.g. 48000 Hz. */
    2046                         pStream->State.uTimerHz = 200;
     2054                        pStreamCC->State.uTimerHz = 200;
    20472055                    else /* Just take the global Hz rate otherwise. */
    2048                         pStream->State.uTimerHz = pThis->uTimerHz;
     2056                        pStreamCC->State.uTimerHz = pThis->uTimerHz;
    20492057                }
    20502058                else
    2051                     pStream->State.uTimerHz = pThis->uTimerHz;
     2059                    pStreamCC->State.uTimerHz = pThis->uTimerHz;
    20522060
    20532061                /* Set scheduling hint (if available). */
    2054                 if (pStream->State.uTimerHz)
    2055                     Cfg.Device.cMsSchedulingHint = 1000 /* ms */ / pStream->State.uTimerHz;
    2056 
    2057                 if (pStream->State.pCircBuf)
     2062                if (pStreamCC->State.uTimerHz)
     2063                    Cfg.Device.cMsSchedulingHint = 1000 /* ms */ / pStreamCC->State.uTimerHz;
     2064
     2065                if (pStreamCC->State.pCircBuf)
    20582066                {
    2059                     RTCircBufDestroy(pStream->State.pCircBuf);
    2060                     pStream->State.pCircBuf = NULL;
     2067                    RTCircBufDestroy(pStreamCC->State.pCircBuf);
     2068                    pStreamCC->State.pCircBuf = NULL;
    20612069                }
    20622070
    2063                 rc = RTCircBufCreate(&pStream->State.pCircBuf, DrvAudioHlpMilliToBytes(100 /* ms */, &Cfg.Props)); /** @todo Make this configurable. */
     2071                rc = RTCircBufCreate(&pStreamCC->State.pCircBuf, DrvAudioHlpMilliToBytes(100 /* ms */, &Cfg.Props)); /** @todo Make this configurable. */
    20642072                if (RT_SUCCESS(rc))
    20652073                {
    2066                     ichac97R3MixerRemoveDrvStreams(pThis, pMixSink, Cfg.enmDir, Cfg.u);
    2067 
    2068                     rc = ichac97R3MixerAddDrvStreams(pThis, pMixSink, &Cfg);
     2074                    ichac97R3MixerRemoveDrvStreams(pThisCC, pMixSink, Cfg.enmDir, Cfg.u);
     2075
     2076                    rc = ichac97R3MixerAddDrvStreams(pThisCC, pMixSink, &Cfg);
    20692077                    if (RT_SUCCESS(rc))
    2070                         rc = DrvAudioHlpStreamCfgCopy(&pStream->State.Cfg, &Cfg);
     2078                        rc = DrvAudioHlpStreamCfgCopy(&pStreamCC->State.Cfg, &Cfg);
    20712079                }
    20722080            }
     
    20842092 *
    20852093 * @returns IPRT status code.
    2086  * @param   pThis               AC'97 state.
    2087  * @param   pStream             AC'97 stream to close.
    2088  */
    2089 static int ichac97R3StreamClose(PAC97STATE pThis, PAC97STREAM pStream)
    2090 {
    2091     RT_NOREF(pThis, pStream);
    2092 
     2094 * @param   pStream             The AC'97 stream to close (shared).
     2095 */
     2096static int ichac97R3StreamClose(PAC97STREAM pStream)
     2097{
     2098    RT_NOREF(pStream);
    20932099    LogFlowFunc(("[SD%RU8]\n", pStream->u8SD));
    2094 
    20952100    return VINF_SUCCESS;
    20962101}
     
    21012106 *
    21022107 * @returns IPRT status code.
    2103  * @param   pThis               AC'97 device state.
    2104  * @param   pStream             AC'97 stream to re-open.
     2108 * @param   pThis               The shared AC'97 device state.
     2109 * @param   pThisCC             The ring-3 AC'97 device state.
     2110 * @param   pStream             The AC'97 stream to re-open (shared).
     2111 * @param   pStreamCC           The AC'97 stream to re-open (ring-3).
    21052112 * @param   fForce              Whether to force re-opening the stream or not.
    21062113 *                              Otherwise re-opening only will happen if the PCM properties have changed.
    21072114 */
    2108 static int ichac97R3StreamReOpen(PAC97STATE pThis, PAC97STREAM pStream, bool fForce)
     2115static int ichac97R3StreamReOpen(PAC97STATE pThis, PAC97STATER3 pThisCC,
     2116                                 PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fForce)
    21092117{
    21102118    LogFlowFunc(("[SD%RU8]\n", pStream->u8SD));
    2111 
    2112     int rc = ichac97R3StreamClose(pThis, pStream);
     2119    Assert(pStream->u8SD == pStreamCC->u8SD);
     2120    Assert(pStream   - &pThis->aStreams[0]   == pStream->u8SD);
     2121    Assert(pStreamCC - &pThisCC->aStreams[0] == pStream->u8SD);
     2122
     2123    int rc = ichac97R3StreamClose(pStream);
    21132124    if (RT_SUCCESS(rc))
    2114         rc = ichac97R3StreamOpen(pThis, pStream, fForce);
     2125        rc = ichac97R3StreamOpen(pThis, pThisCC, pStream, pStreamCC, fForce);
    21152126
    21162127    return rc;
     
    21212132 *
    21222133 * @returns IPRT status code.
    2123  * @param   pStream             AC'97 stream to lock.
    2124  */
    2125 static void ichac97R3StreamLock(PAC97STREAM pStream)
    2126 {
    2127     int rc2 = RTCritSectEnter(&pStream->State.CritSect);
     2134 * @param   pStreamCC           The AC'97 stream to lock (ring-3).
     2135 */
     2136static void ichac97R3StreamLock(PAC97STREAMR3 pStreamCC)
     2137{
     2138    int rc2 = RTCritSectEnter(&pStreamCC->State.CritSect);
    21282139    AssertRC(rc2);
    21292140}
     
    21332144 *
    21342145 * @returns IPRT status code.
    2135  * @param   pStream             AC'97 stream to unlock.
    2136  */
    2137 static void ichac97R3StreamUnlock(PAC97STREAM pStream)
    2138 {
    2139     int rc2 = RTCritSectLeave(&pStream->State.CritSect);
     2146 * @param   pStreamCC           The AC'97 stream to unlock (ring-3).
     2147 */
     2148static void ichac97R3StreamUnlock(PAC97STREAMR3 pStreamCC)
     2149{
     2150    int rc2 = RTCritSectLeave(&pStreamCC->State.CritSect);
    21402151    AssertRC(rc2);
    21412152}
     
    21452156 *
    21462157 * @returns Available data (in bytes).
    2147  * @param   pStream             AC'97 stream to retrieve size for.
    2148  */
    2149 static uint32_t ichac97R3StreamGetUsed(PAC97STREAM pStream)
    2150 {
    2151     if (!pStream->State.pCircBuf)
     2158 * @param   pStreamCC           The AC'97 stream to retrieve size for (ring-3).
     2159 */
     2160static uint32_t ichac97R3StreamGetUsed(PAC97STREAMR3 pStreamCC)
     2161{
     2162    if (!pStreamCC->State.pCircBuf)
    21522163        return 0;
    21532164
    2154     return (uint32_t)RTCircBufUsed(pStream->State.pCircBuf);
     2165    return (uint32_t)RTCircBufUsed(pStreamCC->State.pCircBuf);
    21552166}
    21562167
     
    21612172 * @param   pStream             AC'97 stream to retrieve size for.
    21622173 */
    2163 static uint32_t ichac97R3StreamGetFree(PAC97STREAM pStream)
    2164 {
    2165     if (!pStream->State.pCircBuf)
     2174static uint32_t ichac97R3StreamGetFree(PAC97STREAMR3 pStreamCC)
     2175{
     2176    if (!pStreamCC->State.pCircBuf)
    21662177        return 0;
    21672178
    2168     return (uint32_t)RTCircBufFree(pStream->State.pCircBuf);
     2179    return (uint32_t)RTCircBufFree(pStreamCC->State.pCircBuf);
    21692180}
    21702181
     
    21752186 *
    21762187 * @returns IPRT status code.
    2177  * @param   pThis               AC'97 state.
     2188 * @param   pThis               The shared AC'97 state.
     2189 * @param   pThisCC             The ring-3 AC'97 state.
    21782190 * @param   index               AC'97 mixer index to set volume for.
    21792191 * @param   enmMixerCtl         Corresponding audio mixer sink.
    21802192 * @param   uVal                Volume value to set.
    21812193 */
    2182 static int ichac97R3MixerSetVolume(PAC97STATE pThis, int index, PDMAUDIOMIXERCTL enmMixerCtl, uint32_t uVal)
     2194static int ichac97R3MixerSetVolume(PAC97STATE pThis, PAC97STATER3 pThisCC, int index, PDMAUDIOMIXERCTL enmMixerCtl, uint32_t uVal)
    21832195{
    21842196    /*
     
    22342246    int rc = VINF_SUCCESS;
    22352247
    2236     if (pThis->pMixer) /* Device can be in reset state, so no mixer available. */
     2248    if (pThisCC->pMixer) /* Device can be in reset state, so no mixer available. */
    22372249    {
    22382250        PDMAUDIOVOLUME Vol   = { fCtlMuted, lVol, rVol };
     
    22422254        {
    22432255            case PDMAUDIOMIXERCTL_VOLUME_MASTER:
    2244                 rc = AudioMixerSetMasterVolume(pThis->pMixer, &Vol);
     2256                rc = AudioMixerSetMasterVolume(pThisCC->pMixer, &Vol);
    22452257                break;
    22462258
    22472259            case PDMAUDIOMIXERCTL_FRONT:
    2248                 pSink = pThis->pSinkOut;
     2260                pSink = pThisCC->pSinkOut;
    22492261                break;
    22502262
     
    22782290 *
    22792291 * @returns IPRT status code.
    2280  * @param   pThis               AC'97 state.
     2292 * @param   pThis               The shared AC'97 state.
     2293 * @param   pThisCC             The ring-3 AC'97 state.
    22812294 * @param   index               AC'97 mixer index to set volume for.
    22822295 * @param   enmMixerCtl         Corresponding audio mixer sink.
    22832296 * @param   uVal                Volume value to set.
    22842297 */
    2285 static int ichac97R3MixerSetGain(PAC97STATE pThis, int index, PDMAUDIOMIXERCTL enmMixerCtl, uint32_t uVal)
     2298static int ichac97R3MixerSetGain(PAC97STATE pThis, PAC97STATER3 pThisCC, int index, PDMAUDIOMIXERCTL enmMixerCtl, uint32_t uVal)
    22862299{
    22872300    /*
     
    23172330    int rc = VINF_SUCCESS;
    23182331
    2319     if (pThis->pMixer) /* Device can be in reset state, so no mixer available. */
     2332    if (pThisCC->pMixer) /* Device can be in reset state, so no mixer available. */
    23202333    {
    23212334        PDMAUDIOVOLUME Vol   = { fCtlMuted, lVol, rVol };
     
    23252338        {
    23262339            case PDMAUDIOMIXERCTL_MIC_IN:
    2327                 pSink = pThis->pSinkMicIn;
     2340                pSink = pThisCC->pSinkMicIn;
    23282341                break;
    23292342
    23302343            case PDMAUDIOMIXERCTL_LINE_IN:
    2331                 pSink = pThis->pSinkLineIn;
     2344                pSink = pThisCC->pSinkLineIn;
    23322345                break;
    23332346
     
    23452358             * NB: The codecs we support do not have the dedicated microphone control.
    23462359             */
    2347             if ((pSink == pThis->pSinkLineIn) && pThis->pSinkMicIn)
     2360            if ((pSink == pThisCC->pSinkLineIn) && pThisCC->pSinkMicIn)
    23482361                rc = AudioMixerSinkSetVolume(pSink, &Vol);
    23492362        }
     
    24322445 * source.
    24332446 *
    2434  * @param   pThis               AC'97 state.
     2447 * @param   pThis               The shared AC'97 state.
    24352448 * @param   val                 AC'97 recording source index to set.
    24362449 */
     
    24552468 *
    24562469 * @returns IPRT status code.
    2457  * @param   pThis               AC'97 state.
    2458  */
    2459 static int ichac97R3MixerReset(PAC97STATE pThis)
     2470 * @param   pThis               The shared AC'97 state.
     2471 * @param   pThisCC             The ring-3 AC'97 state.
     2472 */
     2473static int ichac97R3MixerReset(PAC97STATE pThis, PAC97STATER3 pThisCC)
    24602474{
    24612475    LogFlowFuncEnter();
     
    25152529
    25162530    /* The default value is 8000h, which corresponds to 0 dB attenuation with mute on. */
    2517     ichac97R3MixerSetVolume(pThis, AC97_Master_Volume_Mute,  PDMAUDIOMIXERCTL_VOLUME_MASTER, 0x8000);
     2531    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_Master_Volume_Mute,  PDMAUDIOMIXERCTL_VOLUME_MASTER, 0x8000);
    25182532
    25192533    /* The default value for stereo registers is 8808h, which corresponds to 0 dB gain with mute on.*/
    2520     ichac97R3MixerSetVolume(pThis, AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_FRONT,         0x8808);
    2521     ichac97R3MixerSetVolume(pThis, AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN,       0x8808);
    2522     ichac97R3MixerSetVolume(pThis, AC97_Mic_Volume_Mute,     PDMAUDIOMIXERCTL_MIC_IN,        0x8008);
     2534    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_FRONT,         0x8808);
     2535    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN,       0x8808);
     2536    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_Mic_Volume_Mute,     PDMAUDIOMIXERCTL_MIC_IN,        0x8008);
    25232537
    25242538    /* The default for record controls is 0 dB gain with mute on. */
    2525     ichac97R3MixerSetGain(pThis, AC97_Record_Gain_Mute,      PDMAUDIOMIXERCTL_LINE_IN,       0x8000);
    2526     ichac97R3MixerSetGain(pThis, AC97_Record_Gain_Mic_Mute,  PDMAUDIOMIXERCTL_MIC_IN,        0x8000);
     2539    ichac97R3MixerSetGain(pThis, pThisCC, AC97_Record_Gain_Mute,      PDMAUDIOMIXERCTL_LINE_IN,       0x8000);
     2540    ichac97R3MixerSetGain(pThis, pThisCC, AC97_Record_Gain_Mic_Mute,  PDMAUDIOMIXERCTL_MIC_IN,        0x8000);
    25272541
    25282542    return VINF_SUCCESS;
     
    25542568        uint32_t cbWrittenToStream;
    25552569
    2556         int rc2 = AudioMixerSinkWrite(pThis->pSinkOut, AUDMIXOP_COPY,
     2570        int rc2 = AudioMixerSinkWrite(pThisCC->pSinkOut, AUDMIXOP_COPY,
    25572571                                      pThis->silence, cbToWrite, &cbWrittenToStream);
    25582572        if (RT_SUCCESS(rc2))
     
    25762590static DECLCALLBACK(void) ichac97R3Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
    25772591{
    2578     PAC97STATE  pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     2592    PAC97STATE      pThis     = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
    25792593    STAM_PROFILE_START(&pThis->StatTimer, a);
    2580     PAC97STREAM pStream = (PAC97STREAM)pvUser;
     2594    PAC97STATER3    pThisCC   = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
     2595    PAC97STREAM     pStream   = (PAC97STREAM)pvUser;
     2596    PAC97STREAMR3   pStreamCC = &RT_SAFE_SUBSCRIPT8(pThisCC->aStreams, pStream->u8SD);
    25812597    RT_NOREF(pTimer);
    25822598
    2583     AssertPtr(pStream);
     2599    Assert(pStream - &pThis->aStreams[0] == pStream->u8SD);
    25842600    Assert(PDMDevHlpCritSectIsOwner(pDevIns, &pThis->CritSect));
    25852601    Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pStream->hTimer));
    25862602
    2587     ichac97R3StreamUpdate(pDevIns, pThis, pStream, true /* fInTimer */);
    2588 
    2589     PAUDMIXSINK pSink = ichac97R3IndexToSink(pThis, pStream->u8SD);
     2603    ichac97R3StreamUpdate(pDevIns, pThis, pThisCC, pStream, pStreamCC, true /* fInTimer */);
     2604
     2605    PAUDMIXSINK pSink = ichac97R3IndexToSink(pThisCC, pStream->u8SD);
    25902606    if (pSink && AudioMixerSinkIsActive(pSink))
    25912607    {
    2592         ichac97R3StreamTransferUpdate(pDevIns, pStream, pStream->Regs.picb << 1); /** @todo r=andy Assumes 16-bit samples. */
    2593         ichac97R3TimerSet(pDevIns, pStream, pStream->State.cTransferTicks);
     2608        ichac97R3StreamTransferUpdate(pDevIns, pStream, pStreamCC, pStream->Regs.picb << 1); /** @todo r=andy Assumes 16-bit samples. */
     2609        ichac97R3TimerSet(pDevIns, pStream, pStreamCC->State.cTransferTicks);
    25942610    }
    25952611
     
    26022618 *
    26032619 * @param   pDevIns             The device instance.
    2604  * @param   pThis               AC'97 state.
     2620 * @param   pThis               The shared AC'97 state.
    26052621 * @param   pStream             AC'97 stream to set timer for.
    26062622 * @param   cTicksToDeadline    The number of ticks to the new deadline.
     
    26262642 * @returns IPRT status code.
    26272643 * @param   pDevIns             The device instance.
    2628  * @param   pThis               AC'97 state.
    2629  * @param   pStream             AC'97 stream to update.
     2644 * @param   pThis               The shared AC'97 state.
     2645 * @param   pStream             The AC'97 stream to update (shared).
     2646 * @param   pStreamCC           The AC'97 stream to update (ring-3).
    26302647 * @param   cbToProcessMax      Maximum of data (in bytes) to process.
    26312648 */
    2632 static int ichac97R3StreamTransfer(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbToProcessMax)
     2649static int ichac97R3StreamTransfer(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STREAM pStream,
     2650                                   PAC97STREAMR3 pStreamCC, uint32_t cbToProcessMax)
    26332651{
    26342652    if (!cbToProcessMax)
     
    26362654
    26372655#ifdef VBOX_STRICT
    2638     const unsigned cbFrame = DrvAudioHlpPCMPropsBytesPerFrame(&pStream->State.Cfg.Props);
     2656    const unsigned cbFrame = DrvAudioHlpPCMPropsBytesPerFrame(&pStreamCC->State.Cfg.Props);
    26392657#endif
    26402658
     
    26422660    Assert(cbToProcessMax % cbFrame == 0);
    26432661
    2644     ichac97R3StreamLock(pStream);
     2662    ichac97R3StreamLock(pStreamCC);
    26452663
    26462664    PAC97BMREGS pRegs = &pStream->Regs;
     
    26612679        }
    26622680
    2663         ichac97R3StreamUnlock(pStream);
     2681        ichac97R3StreamUnlock(pStreamCC);
    26642682        return VINF_SUCCESS;
    26652683    }
     
    26702688        Log3Func(("[SD%RU8] BCIS set\n", pStream->u8SD));
    26712689
    2672         ichac97R3StreamUnlock(pStream);
     2690        ichac97R3StreamUnlock(pStreamCC);
    26732691        return VINF_SUCCESS;
    26742692    }
     
    26772695    uint32_t cbProcessedTotal = 0;
    26782696
    2679     PRTCIRCBUF pCircBuf = pStream->State.pCircBuf;
     2697    PRTCIRCBUF pCircBuf = pStreamCC->State.pCircBuf;
    26802698    AssertPtr(pCircBuf);
    26812699
     
    27032721            pRegs->piv = (pRegs->piv + 1) % AC97_MAX_BDLE;
    27042722
    2705             ichac97R3StreamFetchBDLE(pThis, pStream);
     2723            ichac97R3StreamFetchBDLE(pDevIns, pStream);
    27062724            continue;
    27072725        }
     
    27202738                if (cbDst)
    27212739                {
    2722                     int rc2 = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), pRegs->bd.addr, (uint8_t *)pvDst, cbDst);
     2740                    int rc2 = PDMDevHlpPhysRead(pDevIns, pRegs->bd.addr, (uint8_t *)pvDst, cbDst);
    27232741                    AssertRC(rc2);
    27242742
    2725                     if (pStream->Dbg.Runtime.fEnabled)
    2726                         DrvAudioHlpFileWrite(pStream->Dbg.Runtime.pFileDMA, pvDst, cbDst, 0 /* fFlags */);
     2743                    if (RT_LIKELY(!pStreamCC->Dbg.Runtime.fEnabled))
     2744                    { /* likely */ }
     2745                    else
     2746                        DrvAudioHlpFileWrite(pStreamCC->Dbg.Runtime.pFileDMA, pvDst, cbDst, 0 /* fFlags */);
    27272747                }
    27282748
     
    27452765/** @todo r=bird: Just curious, DevHDA uses PDMDevHlpPCIPhysWrite here.  So,
    27462766 *        is AC97 not subject to PCI busmaster enable/disable? */
    2747                     int rc2 = PDMDevHlpPhysWrite(pThis->CTX_SUFF(pDevIns), pRegs->bd.addr, (uint8_t *)pvSrc, cbSrc);
     2767                    int rc2 = PDMDevHlpPhysWrite(pDevIns, pRegs->bd.addr, (uint8_t *)pvSrc, cbSrc);
    27482768                    AssertRC(rc2);
    27492769
    2750                     if (pStream->Dbg.Runtime.fEnabled)
    2751                         DrvAudioHlpFileWrite(pStream->Dbg.Runtime.pFileDMA, pvSrc, cbSrc, 0 /* fFlags */);
     2770                    if (RT_LIKELY(!pStreamCC->Dbg.Runtime.fEnabled))
     2771                    { /* likely */ }
     2772                    else
     2773                        DrvAudioHlpFileWrite(pStreamCC->Dbg.Runtime.pFileDMA, pvSrc, cbSrc, 0 /* fFlags */);
    27522774                }
    27532775
     
    28052827                pRegs->civ = pRegs->piv;
    28062828                pRegs->piv = (pRegs->piv + 1) % AC97_MAX_BDLE;
    2807                 ichac97R3StreamFetchBDLE(pThis, pStream);
     2829                ichac97R3StreamFetchBDLE(pDevIns, pStream);
    28082830            }
    28092831
     
    28202842    }
    28212843
    2822     ichac97R3StreamUnlock(pStream);
     2844    ichac97R3StreamUnlock(pStreamCC);
    28232845
    28242846    LogFlowFuncLeaveRC(rc);
     
    29993021ichac97IoPortNabmWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t u32, unsigned cb)
    30003022{
    3001     PAC97STATE  pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3023    PAC97STATE      pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3024#ifdef IN_RING3
     3025    PAC97STATER3    pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
     3026#endif
    30023027    RT_NOREF(pvUser);
    30033028
    3004     PAC97STREAM pStream = NULL;
    3005     PAC97BMREGS pRegs   = NULL;
     3029#ifdef IN_RING3
     3030    PAC97STREAMR3   pStreamCC = NULL;
     3031#endif
     3032    PAC97STREAM     pStream   = NULL;
     3033    PAC97BMREGS     pRegs     = NULL;
    30063034    if (AC97_PORT2IDX(offPort) < AC97_MAX_STREAMS)
    30073035    {
    3008         pStream = &pThis->aStreams[AC97_PORT2IDX(offPort)];
    3009         pRegs   = &pStream->Regs;
     3036#ifdef IN_RING3
     3037        pStreamCC = &pThisCC->aStreams[AC97_PORT2IDX(offPort)];
     3038#endif
     3039        pStream   = &pThis->aStreams[AC97_PORT2IDX(offPort)];
     3040        pRegs     = &pStream->Regs;
    30103041
    30113042        DEVAC97_LOCK_BOTH_RETURN(pDevIns, pThis, pStream, VINF_IOM_R3_IOPORT_WRITE);
     
    30623093                        Assert((pRegs->cr & AC97_CR_RPBM) == 0);
    30633094
    3064                         ichac97R3StreamEnable(pThis, pStream, false /* fEnable */);
    3065                         ichac97R3StreamReset(pThis, pStream);
     3095                        ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, false /* fEnable */);
     3096                        ichac97R3StreamReset(pThis, pStream, pStreamCC);
    30663097
    30673098                        ichac97StreamUpdateSR(pDevIns, pThis, pStream, AC97_SR_DCH); /** @todo Do we need to do that? */
     
    30753106                            Log3Func(("[SD%RU8] Disable\n", pStream->u8SD));
    30763107
    3077                             ichac97R3StreamEnable(pThis, pStream, false /* fEnable */);
     3108                            ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, false /* fEnable */);
    30783109
    30793110                            pRegs->sr |= AC97_SR_DCH;
     
    30893120
    30903121                            /* Fetch the initial BDLE descriptor. */
    3091                             ichac97R3StreamFetchBDLE(pThis, pStream);
     3122                            ichac97R3StreamFetchBDLE(pDevIns, pStream);
    30923123# ifdef LOG_ENABLED
    3093                             ichac97R3BDLEDumpAll(pThis, pStream->Regs.bdbar, pStream->Regs.lvi + 1);
     3124                            ichac97R3BDLEDumpAll(pDevIns, pStream->Regs.bdbar, pStream->Regs.lvi + 1);
    30943125# endif
    3095                             ichac97R3StreamEnable(pThis, pStream, true /* fEnable */);
     3126                            ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, true /* fEnable */);
    30963127
    30973128                            /* Arm the timer for this stream. */
    30983129                            /** @todo r=bird: This function returns bool, not VBox status! */
    3099                             ichac97R3TimerSet(pDevIns, pStream, pStream->State.cTransferTicks);
     3130                            ichac97R3TimerSet(pDevIns, pStream, pStreamCC->State.cTransferTicks);
    31003131                        }
    31013132                    }
     
    32423273ichac97IoPortNamWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t u32, unsigned cb)
    32433274{
    3244     PAC97STATE pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3275    PAC97STATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3276#ifdef IN_RING3
     3277    PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
     3278#endif
    32453279    RT_NOREF(pvUser);
    32463280
     
    32643298                case AC97_Reset:
    32653299#ifdef IN_RING3
    3266                     ichac97R3Reset(pThis->CTX_SUFF(pDevIns));
     3300                    ichac97R3Reset(pDevIns);
    32673301#else
    32683302                    rc = VINF_IOM_R3_IOPORT_WRITE;
     
    32813315                    }
    32823316#ifdef IN_RING3
    3283                     ichac97R3MixerSetVolume(pThis, offPort, PDMAUDIOMIXERCTL_VOLUME_MASTER, u32);
     3317                    ichac97R3MixerSetVolume(pThis, pThisCC, offPort, PDMAUDIOMIXERCTL_VOLUME_MASTER, u32);
    32843318#else
    32853319                    rc = VINF_IOM_R3_IOPORT_WRITE;
     
    32933327                            /* Register controls PCM (front) outputs. */
    32943328#ifdef IN_RING3
    3295                             ichac97R3MixerSetVolume(pThis, offPort, PDMAUDIOMIXERCTL_VOLUME_MASTER, u32);
     3329                            ichac97R3MixerSetVolume(pThis, pThisCC, offPort, PDMAUDIOMIXERCTL_VOLUME_MASTER, u32);
    32963330#else
    32973331                            rc = VINF_IOM_R3_IOPORT_WRITE;
     
    33023336                case AC97_PCM_Out_Volume_Mute:
    33033337#ifdef IN_RING3
    3304                     ichac97R3MixerSetVolume(pThis, offPort, PDMAUDIOMIXERCTL_FRONT, u32);
     3338                    ichac97R3MixerSetVolume(pThis, pThisCC, offPort, PDMAUDIOMIXERCTL_FRONT, u32);
    33053339#else
    33063340                    rc = VINF_IOM_R3_IOPORT_WRITE;
     
    33093343                case AC97_Line_In_Volume_Mute:
    33103344#ifdef IN_RING3
    3311                     ichac97R3MixerSetVolume(pThis, offPort, PDMAUDIOMIXERCTL_LINE_IN, u32);
     3345                    ichac97R3MixerSetVolume(pThis, pThisCC, offPort, PDMAUDIOMIXERCTL_LINE_IN, u32);
    33123346#else
    33133347                    rc = VINF_IOM_R3_IOPORT_WRITE;
     
    33253359                    /* Newer Ubuntu guests rely on that when controlling gain and muting
    33263360                     * the recording (capturing) levels. */
    3327                     ichac97R3MixerSetGain(pThis, offPort, PDMAUDIOMIXERCTL_LINE_IN, u32);
     3361                    ichac97R3MixerSetGain(pThis, pThisCC, offPort, PDMAUDIOMIXERCTL_LINE_IN, u32);
    33283362#else
    33293363                    rc = VINF_IOM_R3_IOPORT_WRITE;
     
    33333367#ifdef IN_RING3
    33343368                    /* Ditto; see note above. */
    3335                     ichac97R3MixerSetGain(pThis, offPort, PDMAUDIOMIXERCTL_MIC_IN,  u32);
     3369                    ichac97R3MixerSetGain(pThis, pThisCC, offPort, PDMAUDIOMIXERCTL_MIC_IN,  u32);
    33363370#else
    33373371                    rc = VINF_IOM_R3_IOPORT_WRITE;
     
    33533387                    {
    33543388                        ichac97MixerSet(pThis, AC97_PCM_Front_DAC_Rate, 0xbb80); /* Set default (48000 Hz). */
    3355                         ichac97R3StreamReOpen(pThis, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX], true /* fForce */);
     3389                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX],
     3390                                              &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX], true /* fForce */);
    33563391
    33573392                        ichac97MixerSet(pThis, AC97_PCM_LR_ADC_Rate, 0xbb80); /* Set default (48000 Hz). */
    3358                         ichac97R3StreamReOpen(pThis, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX], true /* fForce */);
     3393                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX],
     3394                                              &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX], true /* fForce */);
    33593395                    }
    33603396                    else
     
    33673403                    {
    33683404                        ichac97MixerSet(pThis, AC97_MIC_ADC_Rate, 0xbb80); /* Set default (48000 Hz). */
    3369                         ichac97R3StreamReOpen(pThis, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX], true /* fForce */);
     3405                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX],
     3406                                              &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX], true /* fForce */);
    33703407                    }
    33713408                    else
     
    33843421                        LogRel2(("AC97: Setting front DAC rate to 0x%x\n", u32));
    33853422                        ichac97MixerSet(pThis, offPort, u32);
    3386                         ichac97R3StreamReOpen(pThis, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX], true /* fForce */);
     3423                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX],
     3424                                              &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX], true /* fForce */);
    33873425                    }
    33883426                    else
     
    33983436                        LogRel2(("AC97: Setting microphone ADC rate to 0x%x\n", u32));
    33993437                        ichac97MixerSet(pThis, offPort, u32);
    3400                         ichac97R3StreamReOpen(pThis, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX], true /* fForce */);
     3438                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX],
     3439                                              &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX], true /* fForce */);
    34013440                    }
    34023441                    else
     
    34123451                        LogRel2(("AC97: Setting line-in ADC rate to 0x%x\n", u32));
    34133452                        ichac97MixerSet(pThis, offPort, u32);
    3414                         ichac97R3StreamReOpen(pThis, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX], true /* fForce */);
     3453                        ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX],
     3454                                              &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX], true /* fForce */);
    34153455                    }
    34163456                    else
     
    34783518static DECLCALLBACK(int) ichac97R3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
    34793519{
    3480     PAC97STATE    pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
    3481     PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
     3520    PAC97STATE      pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3521    PAC97STATER3    pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
     3522    PCPDMDEVHLPR3   pHlp    = pDevIns->pHlpR3;
    34823523
    34833524    LogFlowFuncEnter();
     
    34993540    uint8_t active[AC97SOUNDSOURCE_END_INDEX];
    35003541
    3501     active[AC97SOUNDSOURCE_PI_INDEX] = ichac97R3StreamIsEnabled(pThis, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX]) ? 1 : 0;
    3502     active[AC97SOUNDSOURCE_PO_INDEX] = ichac97R3StreamIsEnabled(pThis, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX]) ? 1 : 0;
    3503     active[AC97SOUNDSOURCE_MC_INDEX] = ichac97R3StreamIsEnabled(pThis, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX]) ? 1 : 0;
     3542    active[AC97SOUNDSOURCE_PI_INDEX] = ichac97R3StreamIsEnabled(pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX]) ? 1 : 0;
     3543    active[AC97SOUNDSOURCE_PO_INDEX] = ichac97R3StreamIsEnabled(pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX]) ? 1 : 0;
     3544    active[AC97SOUNDSOURCE_MC_INDEX] = ichac97R3StreamIsEnabled(pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX]) ? 1 : 0;
    35043545
    35053546    pHlp->pfnSSMPutMem(pSSM, active, sizeof(active));
     
    35393580static DECLCALLBACK(int) ichac97R3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
    35403581{
    3541     PAC97STATE    pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
    3542     PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
     3582    PAC97STATE    pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3583    PAC97STATER3  pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
     3584    PCPDMDEVHLPR3 pHlp    = pDevIns->pHlpR3;
    35433585
    35443586    LogRel2(("ichac97LoadExec: uVersion=%RU32, uPass=0x%x\n", uVersion, uPass));
     
    35673609
    35683610    ichac97R3MixerRecordSelect(pThis, ichac97MixerGet(pThis, AC97_Record_Select));
    3569     ichac97R3MixerSetVolume(pThis, AC97_Master_Volume_Mute, PDMAUDIOMIXERCTL_VOLUME_MASTER, ichac97MixerGet(pThis, AC97_Master_Volume_Mute));
    3570     ichac97R3MixerSetVolume(pThis, AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_FRONT, ichac97MixerGet(pThis, AC97_PCM_Out_Volume_Mute));
    3571     ichac97R3MixerSetVolume(pThis, AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN, ichac97MixerGet(pThis, AC97_Line_In_Volume_Mute));
    3572     ichac97R3MixerSetVolume(pThis, AC97_Mic_Volume_Mute, PDMAUDIOMIXERCTL_MIC_IN, ichac97MixerGet(pThis, AC97_Mic_Volume_Mute));
    3573     ichac97R3MixerSetGain(pThis, AC97_Record_Gain_Mic_Mute, PDMAUDIOMIXERCTL_MIC_IN, ichac97MixerGet(pThis, AC97_Record_Gain_Mic_Mute));
    3574     ichac97R3MixerSetGain(pThis, AC97_Record_Gain_Mute, PDMAUDIOMIXERCTL_LINE_IN, ichac97MixerGet(pThis, AC97_Record_Gain_Mute));
     3611    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_Master_Volume_Mute,    PDMAUDIOMIXERCTL_VOLUME_MASTER,
     3612                            ichac97MixerGet(pThis, AC97_Master_Volume_Mute));
     3613    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_PCM_Out_Volume_Mute,   PDMAUDIOMIXERCTL_FRONT,
     3614                            ichac97MixerGet(pThis, AC97_PCM_Out_Volume_Mute));
     3615    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_Line_In_Volume_Mute,   PDMAUDIOMIXERCTL_LINE_IN,
     3616                            ichac97MixerGet(pThis, AC97_Line_In_Volume_Mute));
     3617    ichac97R3MixerSetVolume(pThis, pThisCC, AC97_Mic_Volume_Mute,       PDMAUDIOMIXERCTL_MIC_IN,
     3618                            ichac97MixerGet(pThis, AC97_Mic_Volume_Mute));
     3619    ichac97R3MixerSetGain(pThis, pThisCC, AC97_Record_Gain_Mic_Mute,    PDMAUDIOMIXERCTL_MIC_IN,
     3620                          ichac97MixerGet(pThis, AC97_Record_Gain_Mic_Mute));
     3621    ichac97R3MixerSetGain(pThis, pThisCC, AC97_Record_Gain_Mute,        PDMAUDIOMIXERCTL_LINE_IN,
     3622                          ichac97MixerGet(pThis, AC97_Record_Gain_Mute));
    35753623    if (pThis->uCodecModel == AC97_CODEC_AD1980)
    35763624        if (ichac97MixerGet(pThis, AC97_AD_Misc) & AC97_AD_MISC_HPSEL)
    3577             ichac97R3MixerSetVolume(pThis, AC97_Headphone_Volume_Mute, PDMAUDIOMIXERCTL_VOLUME_MASTER,
     3625            ichac97R3MixerSetVolume(pThis, pThisCC, AC97_Headphone_Volume_Mute, PDMAUDIOMIXERCTL_VOLUME_MASTER,
    35783626                                    ichac97MixerGet(pThis, AC97_Headphone_Volume_Mute));
    35793627
     
    35813629    for (unsigned i = 0; i < AC97_MAX_STREAMS; i++)
    35823630    {
    3583         const bool        fEnable = RT_BOOL(uaStrmsActive[i]);
    3584         const PAC97STREAM pStream = &pThis->aStreams[i];
    3585 
    3586         rc2 = ichac97R3StreamEnable(pThis, pStream, fEnable);
     3631        const bool          fEnable   = RT_BOOL(uaStrmsActive[i]);
     3632        const PAC97STREAM   pStream   = &pThis->aStreams[i];
     3633        const PAC97STREAMR3 pStreamCC = &pThisCC->aStreams[i];
     3634
     3635        rc2 = ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, fEnable);
    35873636        AssertRC(rc2);
    35883637        if (   fEnable
     
    35903639        {
    35913640            /* Re-arm the timer for this stream. */
    3592             ichac97R3TimerSet(pDevIns, pStream, pStream->State.cTransferTicks);
     3641            ichac97R3TimerSet(pDevIns, pStream, pStreamCC->State.cTransferTicks);
    35933642        }
    35943643
     
    36083657static DECLCALLBACK(void *) ichac97R3QueryInterface(struct PDMIBASE *pInterface, const char *pszIID)
    36093658{
    3610     PAC97STATE pThis = RT_FROM_MEMBER(pInterface, AC97STATE, IBase);
    3611     Assert(&pThis->IBase == pInterface);
    3612 
    3613     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->IBase);
     3659    PAC97STATER3 pThisCC = RT_FROM_MEMBER(pInterface, AC97STATER3, IBase);
     3660    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThisCC->IBase);
    36143661    return NULL;
    36153662}
     
    36233670static DECLCALLBACK(void) ichac97R3PowerOff(PPDMDEVINS pDevIns)
    36243671{
    3625     PAC97STATE pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3672    PAC97STATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3673    PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
    36263674
    36273675    LogRel2(("AC97: Powering off ...\n"));
     
    36293677    /* Note: Involves mixer stream / sink destruction, so also do this here
    36303678     *       instead of in ichac97R3Destruct(). */
    3631     ichac97R3StreamsDestroy(pThis);
    3632 
    3633     /**
     3679    ichac97R3StreamsDestroy(pThis, pThisCC);
     3680
     3681    /*
    36343682     * Note: Destroy the mixer while powering off and *not* in ichac97R3Destruct,
    36353683     *       giving the mixer the chance to release any references held to
    36363684     *       PDM audio streams it maintains.
    36373685     */
    3638     if (pThis->pMixer)
    3639     {
    3640         AudioMixerDestroy(pThis->pMixer);
    3641         pThis->pMixer = NULL;
     3686    if (pThisCC->pMixer)
     3687    {
     3688        AudioMixerDestroy(pThisCC->pMixer);
     3689        pThisCC->pMixer = NULL;
    36423690    }
    36433691}
     
    36523700static DECLCALLBACK(void) ichac97R3Reset(PPDMDEVINS pDevIns)
    36533701{
    3654     PAC97STATE pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3702    PAC97STATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3703    PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
    36553704
    36563705    LogRel(("AC97: Reset\n"));
     
    36613710     * the codec manually.
    36623711     */
    3663     ichac97R3MixerReset(pThis);
     3712    ichac97R3MixerReset(pThis, pThisCC);
    36643713
    36653714    /*
     
    36683717    for (unsigned i = 0; i < AC97_MAX_STREAMS; i++)
    36693718    {
    3670         ichac97R3StreamEnable(pThis, &pThis->aStreams[i], false /* fEnable */);
    3671         ichac97R3StreamReset(pThis, &pThis->aStreams[i]);
     3719        ichac97R3StreamEnable(pThis, pThisCC, &pThis->aStreams[i], &pThisCC->aStreams[i], false /* fEnable */);
     3720        ichac97R3StreamReset(pThis, &pThis->aStreams[i], &pThisCC->aStreams[i]);
    36723721    }
    36733722
     
    36783727     * the mixer sink(s) might still have data to be processed when an audio stream gets reset.
    36793728     */
    3680     AudioMixerSinkReset(pThis->pSinkLineIn);
    3681     AudioMixerSinkReset(pThis->pSinkMicIn);
    3682     AudioMixerSinkReset(pThis->pSinkOut);
     3729    AudioMixerSinkReset(pThisCC->pSinkLineIn);
     3730    AudioMixerSinkReset(pThisCC->pSinkMicIn);
     3731    AudioMixerSinkReset(pThisCC->pSinkOut);
    36833732}
    36843733
     
    36923741 *
    36933742 * @returns VBox status code.
    3694  * @param   pThis       AC'97 state.
     3743 * @param   pDevIns     The device instance.
     3744 * @param   pThisCC     The ring-3 AC'97 device state.
    36953745 * @param   iLun        The logical unit which is being attached.
    36963746 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    36973747 * @param   ppDrv       Attached driver instance on success. Optional.
    36983748 */
    3699 static int ichac97R3AttachInternal(PAC97STATE pThis, unsigned iLun, uint32_t fFlags, PAC97DRIVER *ppDrv)
     3749static int ichac97R3AttachInternal(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, unsigned iLun, uint32_t fFlags, PAC97DRIVER *ppDrv)
    37003750{
    37013751    RT_NOREF(fFlags);
     
    37093759
    37103760    PPDMIBASE pDrvBase;
    3711     int rc = PDMDevHlpDriverAttach(pThis->pDevInsR3, iLun, &pThis->IBase, &pDrvBase, pszDesc);
     3761    int rc = PDMDevHlpDriverAttach(pDevIns, iLun, &pThisCC->IBase, &pDrvBase, pszDesc);
    37123762    if (RT_SUCCESS(rc))
    37133763    {
     
    37183768            pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR);
    37193769            AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n", iLun, rc));
    3720             pDrv->pAC97State = pThis;
    37213770            pDrv->uLUN       = iLun;
    37223771            pDrv->pszDesc    = pszDesc;
     
    37343783            if (!pDrv->fAttached)
    37353784            {
    3736                 RTListAppend(&pThis->lstDrv, &pDrv->Node);
     3785                RTListAppend(&pThisCC->lstDrv, &pDrv->Node);
    37373786                pDrv->fAttached = true;
    37383787            }
     
    37653814 *
    37663815 * @returns VBox status code.
    3767  * @param   pThis       AC'97 state.
     3816 * @param   pThisCC     The ring-3 AC'97 device state.
    37683817 * @param   pDrv        Driver to detach from device.
    37693818 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    37703819 */
    3771 static int ichac97R3DetachInternal(PAC97STATE pThis, PAC97DRIVER pDrv, uint32_t fFlags)
     3820static int ichac97R3DetachInternal(PAC97STATER3 pThisCC, PAC97DRIVER pDrv, uint32_t fFlags)
    37723821{
    37733822    RT_NOREF(fFlags);
     
    37753824    /* First, remove the driver from our list and destory it's associated streams.
    37763825     * This also will un-set the driver as a recording source (if associated). */
    3777     ichac97R3MixerRemoveDrv(pThis, pDrv);
     3826    ichac97R3MixerRemoveDrv(pThisCC, pDrv);
    37783827
    37793828    /* Next, search backwards for a capable (attached) driver which now will be the
     
    37813830    PDMAUDIODSTSRCUNION dstSrc;
    37823831    PAC97DRIVER pDrvCur;
    3783     RTListForEachReverse(&pThis->lstDrv, pDrvCur, AC97DRIVER, Node)
     3832    RTListForEachReverse(&pThisCC->lstDrv, pDrvCur, AC97DRIVER, Node)
    37843833    {
    37853834        if (!pDrvCur->pConnector)
     
    37923841
    37933842        dstSrc.enmSrc = PDMAUDIORECSRC_MIC;
    3794         PAC97DRIVERSTREAM pDrvStrm = ichac97R3MixerGetDrvStream(pThis, pDrvCur, PDMAUDIODIR_IN, dstSrc);
     3843        PAC97DRIVERSTREAM pDrvStrm = ichac97R3MixerGetDrvStream(pDrvCur, PDMAUDIODIR_IN, dstSrc);
    37953844        if (   pDrvStrm
    37963845            && pDrvStrm->pMixStrm)
    37973846        {
    3798             rc2 = AudioMixerSinkSetRecordingSource(pThis->pSinkMicIn, pDrvStrm->pMixStrm);
     3847            rc2 = AudioMixerSinkSetRecordingSource(pThisCC->pSinkMicIn, pDrvStrm->pMixStrm);
    37993848            if (RT_SUCCESS(rc2))
    38003849                LogRel2(("AC97: Set new recording source for 'Mic In' to '%s'\n", Cfg.szName));
     
    38023851
    38033852        dstSrc.enmSrc = PDMAUDIORECSRC_LINE;
    3804         pDrvStrm = ichac97R3MixerGetDrvStream(pThis, pDrvCur, PDMAUDIODIR_IN, dstSrc);
     3853        pDrvStrm = ichac97R3MixerGetDrvStream(pDrvCur, PDMAUDIODIR_IN, dstSrc);
    38053854        if (   pDrvStrm
    38063855            && pDrvStrm->pMixStrm)
    38073856        {
    3808             rc2 = AudioMixerSinkSetRecordingSource(pThis->pSinkLineIn, pDrvStrm->pMixStrm);
     3857            rc2 = AudioMixerSinkSetRecordingSource(pThisCC->pSinkLineIn, pDrvStrm->pMixStrm);
    38093858            if (RT_SUCCESS(rc2))
    38103859                LogRel2(("AC97: Set new recording source for 'Line In' to '%s'\n", Cfg.szName));
     
    38213870static DECLCALLBACK(int) ichac97R3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
    38223871{
    3823     PAC97STATE pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3872    PAC97STATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3873    PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
    38243874
    38253875    LogFunc(("iLUN=%u, fFlags=0x%x\n", iLUN, fFlags));
     
    38283878
    38293879    PAC97DRIVER pDrv;
    3830     int rc2 = ichac97R3AttachInternal(pThis, iLUN, fFlags, &pDrv);
     3880    int rc2 = ichac97R3AttachInternal(pDevIns, pThisCC, iLUN, fFlags, &pDrv);
    38313881    if (RT_SUCCESS(rc2))
    3832         rc2 = ichac97R3MixerAddDrv(pThis, pDrv);
     3882        rc2 = ichac97R3MixerAddDrv(pThisCC, pDrv);
    38333883
    38343884    if (RT_FAILURE(rc2))
     
    38453895static DECLCALLBACK(void) ichac97R3Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
    38463896{
    3847     PAC97STATE pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3897    PAC97STATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3898    PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
    38483899
    38493900    LogFunc(("iLUN=%u, fFlags=0x%x\n", iLUN, fFlags));
     
    38523903
    38533904    PAC97DRIVER pDrv, pDrvNext;
    3854     RTListForEachSafe(&pThis->lstDrv, pDrv, pDrvNext, AC97DRIVER, Node)
     3905    RTListForEachSafe(&pThisCC->lstDrv, pDrv, pDrvNext, AC97DRIVER, Node)
    38553906    {
    38563907        if (pDrv->uLUN == iLUN)
    38573908        {
    3858             int rc2 = ichac97R3DetachInternal(pThis, pDrv, fFlags);
     3909            int rc2 = ichac97R3DetachInternal(pThisCC, pDrv, fFlags);
    38593910            if (RT_SUCCESS(rc2))
    38603911            {
     
    38753926 *
    38763927 * @returns VBox status code.
    3877  * @param   pThis       Device instance.
     3928 * @param   pDevIns     The device instance.
     3929 * @param   pThis       The ring-3 AC'97 device state.
    38783930 * @param   iLun        The logical unit which is being replaced.
    38793931 */
    3880 static int ichac97R3ReconfigLunWithNullAudio(PAC97STATE pThis, unsigned iLun)
    3881 {
    3882     int rc = PDMDevHlpDriverReconfigure2(pThis->pDevInsR3, iLun, "AUDIO", "NullAudio");
     3932static int ichac97R3ReconfigLunWithNullAudio(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, unsigned iLun)
     3933{
     3934    int rc = PDMDevHlpDriverReconfigure2(pDevIns, iLun, "AUDIO", "NullAudio");
    38833935    if (RT_SUCCESS(rc))
    3884         rc = ichac97R3AttachInternal(pThis, iLun, 0 /* fFlags */, NULL /* ppDrv */);
    3885     LogFunc(("pThis=%p, iLun=%u, rc=%Rrc\n", pThis, iLun, rc));
     3936        rc = ichac97R3AttachInternal(pDevIns,  pThisCC, iLun, 0 /* fFlags */, NULL /* ppDrv */);
     3937    LogFunc(("pThisCC=%p, iLun=%u, rc=%Rrc\n", pThisCC, iLun, rc));
    38863938    return rc;
    38873939}
     
    38933945{
    38943946    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns); /* this shall come first */
    3895     PAC97STATE pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3947    PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
    38963948
    38973949    LogFlowFuncEnter();
    38983950
    38993951    PAC97DRIVER pDrv, pDrvNext;
    3900     RTListForEachSafe(&pThis->lstDrv, pDrv, pDrvNext, AC97DRIVER, Node)
     3952    RTListForEachSafe(&pThisCC->lstDrv, pDrv, pDrvNext, AC97DRIVER, Node)
    39013953    {
    39023954        RTListNodeRemove(&pDrv->Node);
     
    39063958
    39073959    /* Sanity. */
    3908     Assert(RTListIsEmpty(&pThis->lstDrv));
     3960    Assert(RTListIsEmpty(&pThisCC->lstDrv));
    39093961
    39103962    return VINF_SUCCESS;
     
    39183970    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); /* this shall come first */
    39193971    PAC97STATE      pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     3972    PAC97STATER3    pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
    39203973    PCPDMDEVHLPR3   pHlp    = pDevIns->pHlpR3;
    39213974    Assert(iInstance == 0); RT_NOREF(iInstance);
     
    39243977     * Initialize data so we can run the destructor without scewing up.
    39253978     */
    3926     pThis->pDevInsR3                = pDevIns;
    3927     pThis->IBase.pfnQueryInterface  = ichac97R3QueryInterface;
    3928     RTListInit(&pThis->lstDrv);
     3979    pThisCC->pDevIns                  = pDevIns;
     3980    pThisCC->IBase.pfnQueryInterface  = ichac97R3QueryInterface;
     3981    RTListInit(&pThisCC->lstDrv);
    39293982
    39303983    /*
     
    39474000        LogRel(("AC97: Using custom device timer rate (%RU16Hz)\n", pThis->uTimerHz));
    39484001
    3949     rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "DebugEnabled", &pThis->Dbg.fEnabled, false);
     4002    rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "DebugEnabled", &pThisCC->Dbg.fEnabled, false);
    39504003    if (RT_FAILURE(rc))
    39514004        return PDMDEV_SET_ERROR(pDevIns, rc,
    39524005                                N_("AC97 configuration error: failed to read debugging enabled flag as boolean"));
    39534006
    3954     rc = pHlp->pfnCFGMQueryStringDef(pCfg, "DebugPathOut", pThis->Dbg.szOutPath, sizeof(pThis->Dbg.szOutPath),
     4007    rc = pHlp->pfnCFGMQueryStringDef(pCfg, "DebugPathOut", pThisCC->Dbg.szOutPath, sizeof(pThisCC->Dbg.szOutPath),
    39554008                                     VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH);
    39564009    if (RT_FAILURE(rc))
     
    39584011                                N_("AC97 configuration error: failed to read debugging output path flag as string"));
    39594012
    3960     if (pThis->Dbg.fEnabled)
    3961         LogRel2(("AC97: Debug output will be saved to '%s'\n", pThis->Dbg.szOutPath));
     4013    if (pThisCC->Dbg.fEnabled)
     4014        LogRel2(("AC97: Debug output will be saved to '%s'\n", pThisCC->Dbg.szOutPath));
    39624015
    39634016    /*
     
    40624115        AssertBreak(iLun < UINT8_MAX);
    40634116        LogFunc(("Trying to attach driver for LUN#%u ...\n", iLun));
    4064         rc = ichac97R3AttachInternal(pThis, iLun, 0 /* fFlags */, NULL /* ppDrv */);
     4117        rc = ichac97R3AttachInternal(pDevIns, pThisCC, iLun, 0 /* fFlags */, NULL /* ppDrv */);
    40654118        if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
    40664119        {
     
    40704123        if (rc == VERR_AUDIO_BACKEND_INIT_FAILED)
    40714124        {
    4072             ichac97R3ReconfigLunWithNullAudio(pThis, iLun); /* Pretend attaching to the NULL audio backend will never fail. */
     4125            ichac97R3ReconfigLunWithNullAudio(pDevIns, pThisCC, iLun); /* Pretend attaching to the NULL audio backend will never fail. */
    40734126            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
    40744127                                       N_("Host audio backend initialization has failed. "
     
    40794132    }
    40804133
    4081     rc = AudioMixerCreate("AC'97 Mixer", 0 /* uFlags */, &pThis->pMixer);
     4134    rc = AudioMixerCreate("AC'97 Mixer", 0 /* uFlags */, &pThisCC->pMixer);
    40824135    AssertRCReturn(rc, rc);
    4083     rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThis->pSinkLineIn);
     4136    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThisCC->pSinkLineIn);
    40844137    AssertRCReturn(rc, rc);
    4085     rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThis->pSinkMicIn);
     4138    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThisCC->pSinkMicIn);
    40864139    AssertRCReturn(rc, rc);
    4087     rc = AudioMixerCreateSink(pThis->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThis->pSinkOut);
     4140    rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThisCC->pSinkOut);
    40884141    AssertRCReturn(rc, rc);
    40894142
     
    40944147    for (unsigned i = 0; i < AC97_MAX_STREAMS; i++)
    40954148    {
    4096         rc = ichac97R3StreamCreate(pThis, &pThis->aStreams[i], i /* SD# */);
     4149        rc = ichac97R3StreamCreate(pThisCC, &pThis->aStreams[i], &pThisCC->aStreams[i], i /* SD# */);
    40974150        AssertRCReturn(rc, rc);
    40984151    }
     
    41234176# ifdef VBOX_WITH_AUDIO_AC97_ONETIME_INIT
    41244177    PAC97DRIVER pDrv;
    4125     RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node)
     4178    RTListForEach(&pThisCC->lstDrv, pDrv, AC97DRIVER, Node)
    41264179    {
    41274180        /*
     
    41454198            LogRel(("AC97: Falling back to NULL backend (no sound audible)\n"));
    41464199            ichac97R3Reset(pDevIns);
    4147             ichac97R3ReconfigLunWithNullAudio(pThis, iLun);
     4200            ichac97R3ReconfigLunWithNullAudio(pdEvIns, pThsiCC, iLun);
    41484201            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
    41494202                                       N_("No audio devices could be opened. "
     
    42694322    /* .uSharedVersion = */         42,
    42704323    /* .cbInstanceShared = */       sizeof(AC97STATE),
    4271     /* .cbInstanceCC = */           0,
     4324    /* .cbInstanceCC = */           CTX_EXPR(sizeof(AC97STATER3), 0, 0),
    42724325    /* .cbInstanceRC = */           0,
    42734326    /* .cMaxPciDevices = */         1,
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette