VirtualBox

Changeset 88502 in vbox


Ignore:
Timestamp:
Apr 14, 2021 9:42:15 AM (4 years ago)
Author:
vboxsync
Message:

DevHda: Fixed regression caused by incorrect assumption about ring-0 vs ring-3 code in r142859 where the CORB processing was made ring-0 capable. bugref:9890

Location:
trunk/src/VBox/Devices/Audio
Files:
4 edited

Legend:

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

    r88476 r88502  
    754754}
    755755
    756 #ifdef IN_RING3
    757 
    758 /**
    759  * Processes the next CORB buffer command in the queue (ring-3).
    760  *
    761  * Note: This function only will be called when the ring-0 version did not have an appropriate dispatcher.
     756
     757/**
     758 * Processes the next CORB buffer command in the queue.
    762759 *
    763760 * This will invoke the HDA codec ring-3 verb dispatcher.
    764761 *
    765  * @returns VBox status code suitable for MMIO write return.
     762 * @returns VBox status code.
    766763 * @param   pDevIns             The device instance.
    767764 * @param   pThis               The shared HDA device state.
    768765 * @param   pThisCC             The ring-0 HDA device state.
    769766 */
    770 static int hdaR3CORBCmdProcess(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC)
     767static int hdaCORBCmdProcess(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATECC pThisCC)
    771768{
    772769    Log3Func(("ENTER CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP), HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP)));
     
    778775    }
    779776
    780     /* Note: Command buffer syncing was already done in R0. */
    781 
    782777    Assert(pThis->cbCorbBuf);
    783778
    784     int rc;
     779    int rc = hdaCmdSync(pDevIns, pThis, true /* Sync from guest */);
     780    AssertRCReturn(rc, rc);
    785781
    786782    /*
     
    796792    uint8_t        rirbWp       = HDA_REG(pThis, RIRBWP);
    797793
     794#ifndef IN_RING3
     795    /*
     796     * Check t
     797     */
     798#endif
     799
    798800    /*
    799801     * The loop.
     
    810812         */
    811813        uint64_t uResp = 0;
     814#ifndef IN_RING3
     815        rc = pThisCC->Codec.pfnLookup(&pThis->Codec, &pThisCC->Codec, HDA_CODEC_CMD(uCmd, 0 /* Codec index */), &uResp);
     816#else
    812817        rc = pThisCC->pCodec->pfnLookup(&pThis->Codec, pThisCC->pCodec, HDA_CODEC_CMD(uCmd, 0 /* Codec index */), &uResp);
    813         if (RT_FAILURE(rc)) /* Can return VERR_NOT_FOUND. */
     818#endif
     819        if (RT_SUCCESS(rc))
     820            AssertRCSuccess(rc); /* no informational statuses */
     821        else
     822        {
     823#ifndef IN_RING3
     824            if (rc == VERR_INVALID_CONTEXT)
     825            {
     826                corbRp = corbRp == 0 ? cCorbEntries - 1 : corbRp - 1;
     827                LogFunc(("->R3 CORB - uCmd=%#x\n", uCmd));
     828                rc = PDMDevHlpTaskTrigger(pDevIns, pThis->hCorbDmaTask);
     829                AssertRCReturn(rc, rc);
     830                break; /* take the normal way out. */
     831            }
     832#endif
    814833            Log3Func(("Lookup for codec verb %08x failed: %Rrc\n", uCmd, rc));
    815 
    816         /* Note: No return here (as we're doing for the ring-0 version);
    817                  we still need to do the interrupt handling below. */
    818 
     834        }
    819835        Log3Func(("Codec verb %08x -> response %016RX64\n", uCmd, uResp));
    820836
     
    881897}
    882898
    883 #else /* IN_RING0 */
    884 
    885 /**
    886  * Processes the next CORB buffer command in the queue (ring-0).
    887  *
    888  * This will invoke the HDA codec verb dispatcher.
    889  *
    890  * @returns VBox status code suitable for MMIO write return.
    891  * @param   pDevIns             The device instance.
    892  * @param   pThis               The shared HDA device state.
    893  * @param   pThisCC             The ring-0 HDA device state.
    894  */
    895 static int hdaR0CORBCmdProcess(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER0 pThisCC)
    896 {
    897     Log3Func(("CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP), HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP)));
    898 
    899     if (!(HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA))
    900     {
    901         LogFunc(("CORB DMA not active, skipping\n"));
    902         return VINF_SUCCESS;
    903     }
    904 
    905     Assert(pThis->cbCorbBuf);
    906 
    907     int rc = hdaCmdSync(pDevIns, pThis, true /* Sync from guest */);
    908     AssertRCReturn(rc, rc);
    909 
    910     /*
    911      * Prepare local copies of relevant registers.
    912      */
    913     uint16_t cIntCnt = HDA_REG(pThis, RINTCNT) & 0xff;
    914     if (!cIntCnt) /* 0 means 256 interrupts. */
    915         cIntCnt = HDA_MAX_RINTCNT;
    916 
    917     uint32_t const cCorbEntries = RT_MIN(RT_MAX(pThis->cbCorbBuf, 1), sizeof(pThis->au32CorbBuf)) / HDA_CORB_ELEMENT_SIZE;
    918     uint8_t  const corbWp       = HDA_REG(pThis, CORBWP) % cCorbEntries;
    919     uint8_t        corbRp       = HDA_REG(pThis, CORBRP);
    920     uint8_t        rirbWp       = HDA_REG(pThis, RIRBWP);
    921 
    922     /*
    923      * The loop.
    924      */
    925     Log3Func(("START CORB(RP:%x, WP:%x) RIRBWP:%x, RINTCNT:%RU8/%RU8\n", corbRp, corbWp, rirbWp, pThis->u16RespIntCnt, cIntCnt));
    926     while (corbRp != corbWp)
    927     {
    928         /* Fetch the command from the CORB. */
    929         corbRp = (corbRp + 1) /* Advance +1 as the first command(s) are at CORBWP + 1. */ % cCorbEntries;
    930         uint32_t const uCmd = pThis->au32CorbBuf[corbRp];
    931 
    932         /*
    933          * Execute the command.
    934          */
    935         uint64_t uResp = 0;
    936         rc = pThisCC->Codec.pfnLookup(&pThis->Codec, &pThisCC->Codec, HDA_CODEC_CMD(uCmd, 0 /* Codec index */), &uResp);
    937         if (RT_FAILURE(rc)) /* Can return VERR_NOT_FOUND. */
    938         {
    939             Log3Func(("Lookup for codec verb %08x failed: %Rrc\n", uCmd, rc));
    940             return rc;
    941         }
    942         Log3Func(("Codec verb %08x -> response %016RX64\n", uCmd, uResp));
    943 
    944         if (   (uResp & CODEC_RESPONSE_UNSOLICITED)
    945             && !(HDA_REG(pThis, GCTL) & HDA_GCTL_UNSOL))
    946         {
    947             LogFunc(("Unexpected unsolicited response.\n"));
    948             HDA_REG(pThis, CORBRP) = corbRp;
    949             /** @todo r=andy No RIRB syncing to guest required in that case? */
    950             /** @todo r=bird: Why isn't RIRBWP updated here.  The response might come
    951              *        after already processing several commands, can't it?  (When you think
    952              *        about it, it is bascially the same question as Andy is asking.) */
    953             return VINF_SUCCESS;
    954         }
    955 
    956         /*
    957          * Store the response in the RIRB.
    958          */
    959         AssertCompile(HDA_RIRB_SIZE == RT_ELEMENTS(pThis->au64RirbBuf));
    960         rirbWp = (rirbWp + 1) % HDA_RIRB_SIZE;
    961         pThis->au64RirbBuf[rirbWp] = uResp;
    962 
    963         /*
    964          * Send interrupt if needed.
    965          */
    966         bool fSendInterrupt = false;
    967         pThis->u16RespIntCnt++;
    968         if (pThis->u16RespIntCnt >= cIntCnt) /* Response interrupt count reached? */
    969         {
    970             pThis->u16RespIntCnt = 0; /* Reset internal interrupt response counter. */
    971 
    972             Log3Func(("Response interrupt count reached (%RU16)\n", pThis->u16RespIntCnt));
    973             fSendInterrupt = true;
    974         }
    975         else if (corbRp == corbWp) /* Did we reach the end of the current command buffer? */
    976         {
    977             Log3Func(("Command buffer empty\n"));
    978             fSendInterrupt = true;
    979         }
    980         if (fSendInterrupt)
    981         {
    982             if (HDA_REG(pThis, RIRBCTL) & HDA_RIRBCTL_RINTCTL) /* Response Interrupt Control (RINTCTL) enabled? */
    983             {
    984                 HDA_REG(pThis, RIRBSTS) |= HDA_RIRBSTS_RINTFL;
    985                 HDA_PROCESS_INTERRUPT(pDevIns, pThis);
    986             }
    987         }
    988     }
    989 
    990     /*
    991      * Put register locals back.
    992      */
    993     Log3Func(("END CORB(RP:%x, WP:%x) RIRBWP:%x, RINTCNT:%RU8/%RU8\n", corbRp, corbWp, rirbWp, pThis->u16RespIntCnt, cIntCnt));
    994     HDA_REG(pThis, CORBRP) = corbRp;
    995     HDA_REG(pThis, RIRBWP) = rirbWp;
    996 
    997     /*
    998      * Write out the response.
    999      */
    1000     rc = hdaCmdSync(pDevIns, pThis, false /* Sync to guest */);
    1001     AssertRC(rc);
    1002 
    1003     return rc;
    1004 }
    1005 
     899#ifdef IN_RING3
     900/**
     901 * @callback_method_impl{FNPDMTASKDEV, Continue CORB DMA in ring-3}
     902 */
     903static DECLCALLBACK(void) hdaR3CorbDmaTaskWorker(PPDMDEVINS pDevIns, void *pvUser)
     904{
     905    PHDASTATE       pThis   = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
     906    PHDASTATER3     pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3);
     907    RT_NOREF(pvUser);
     908    LogFlowFunc(("\n"));
     909
     910    DEVHDA_LOCK(pDevIns, pThis);
     911    hdaCORBCmdProcess(pDevIns, pThis, pThisCC);
     912    DEVHDA_UNLOCK(pDevIns, pThis);
     913
     914}
    1006915#endif /* IN_RING3 */
    1007916
     
    12351144
    12361145    if (HDA_REG(pThis, CORBCTL) & HDA_CORBCTL_DMA) /* DMA engine started? */
    1237     {
    1238 #ifdef IN_RING3
    1239         /* ignore rc */ hdaR3CORBCmdProcess(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3));
    1240 
    1241 #else
    1242         if (hdaR0CORBCmdProcess(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER0)) == VERR_NOT_FOUND)
    1243             return VINF_IOM_R3_MMIO_WRITE; /* Try ring-3. */
    1244 #endif
    1245     }
     1146        rc = hdaCORBCmdProcess(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATECC));
    12461147    else
    12471148        LogFunc(("CORB DMA not running, skipping\n"));
    12481149
    1249     return VINF_SUCCESS;
     1150    return rc;
    12501151}
    12511152
     
    13101211    AssertRCSuccess(VBOXSTRICTRC_VAL(rc));
    13111212
    1312 #ifdef IN_RING3
    1313     rc = hdaR3CORBCmdProcess(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3));
    1314     if (rc == VERR_NOT_FOUND)
    1315         rc = VINF_SUCCESS;
    1316 #else
    1317     rc = hdaR0CORBCmdProcess(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER0));
    1318     if (rc == VERR_NOT_FOUND) /* Try ring-3. */
    1319         rc = VINF_IOM_R3_MMIO_WRITE;
    1320 #endif
    1321 
    1322     return rc;
     1213    return hdaCORBCmdProcess(pDevIns, pThis, PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATECC));
    13231214}
    13241215
     
    47574648    pThis->cbCorbBuf            = HDA_CORB_SIZE * HDA_CORB_ELEMENT_SIZE;
    47584649    pThis->cbRirbBuf            = HDA_RIRB_SIZE * HDA_RIRB_ELEMENT_SIZE;
     4650    pThis->hCorbDmaTask         = NIL_PDMTASKHANDLE;
    47594651
    47604652    /** @todo r=bird: There are probably other things which should be
     
    49724864    }
    49734865# endif
     4866
     4867    /* Create task for continuing CORB DMA in ring-3. */
     4868    rc = PDMDevHlpTaskCreate(pDevIns, PDMTASK_F_RZ, "HDA CORB DMA",
     4869                             hdaR3CorbDmaTaskWorker, NULL /*pvUser*/, &pThis->hCorbDmaTask);
     4870    AssertRCReturn(rc,rc);
    49744871
    49754872    rc = PDMDevHlpSSMRegisterEx(pDevIns, HDA_SAVED_STATE_VERSION, sizeof(*pThis), NULL /*pszBefore*/,
  • trunk/src/VBox/Devices/Audio/DevHda.h

    r88235 r88502  
    131131    /** The start time of the wall clock (WALCLK), measured on the virtual sync clock. */
    132132    uint64_t                tsWalClkStart;
     133    /** CORB DMA task handle.
     134     * We use this when there is stuff we cannot handle in ring-0.  */
     135    PDMTASKHANDLE           hCorbDmaTask;
    133136    /** The CORB buffer. */
    134137    uint32_t                au32CorbBuf[HDA_CORB_SIZE];
     
    269272
    270273
     274/** Pointer to the context specific HDA state (HDASTATER3 or HDASTATER0). */
     275typedef CTX_SUFF(PHDASTATE) PHDASTATECC;
     276
    271277#endif /* !VBOX_INCLUDED_SRC_Audio_DevHda_h */
    272278
  • trunk/src/VBox/Devices/Audio/DevHdaCodec.cpp

    r88235 r88502  
    9797#define STAC9221_NUM_NODES                                 0x1C
    9898
     99
     100/*********************************************************************************************************************************
     101*   Global Variables                                                                                                             *
     102*********************************************************************************************************************************/
    99103#ifdef IN_RING3
    100104
     
    141145#endif /* IN_RING3 */
    142146
     147
     148
    143149#if 0 /* unused */
    144150static DECLCALLBACK(void) stac9220DbgNodes(PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs)
     
    157163}
    158164#endif
     165
    159166
    160167/**
     
    924931}
    925932
    926 #ifdef IN_RING0
    927 
    928933DECLINLINE(void) hdaCodecSetRegisterU16(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset)
    929934{
     
    931936}
    932937
    933 #endif
    934938
    935939/*
     
    938942#if 0 /* unused */
    939943
    940 static DECLCALLBACK(int) vrbProcUnimplemented(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    941 {
    942     RT_NOREF(pThis, cmd);
     944static DECLCALLBACK(int) vrbProcUnimplemented(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     945{
     946    RT_NOREF(pThis, pThisCC, cmd);
    943947    LogFlowFunc(("cmd(raw:%x: cad:%x, d:%c, nid:%x, verb:%x)\n", cmd,
    944948                 CODEC_CAD(cmd), CODEC_DIRECT(cmd) ? 'N' : 'Y', CODEC_NID(cmd), CODEC_VERBDATA(cmd)));
     
    947951}
    948952
    949 static DECLCALLBACK(int) vrbProcBreak(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
     953static DECLCALLBACK(int) vrbProcBreak(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
    950954{
    951955    int rc;
    952     rc = vrbProcUnimplemented(pThis, cmd, pResp);
     956    rc = vrbProcUnimplemented(pThis, pThisCC, cmd, pResp);
    953957    *pResp |= CODEC_RESPONSE_UNSOLICITED;
    954958    return rc;
     
    957961#endif /* unused */
    958962
    959 #ifdef IN_RING0
    960963
    961964/* B-- */
    962 static DECLCALLBACK(int) vrbProcGetAmplifier(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    963 {
     965static DECLCALLBACK(int) vrbProcGetAmplifier(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     966{
     967    RT_NOREF(pThisCC);
    964968    *pResp = 0;
    965969
     
    10051009}
    10061010
    1007 static DECLCALLBACK(int) vrbProcGetParameter(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1008 {
     1011static DECLCALLBACK(int) vrbProcGetParameter(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1012{
     1013    RT_NOREF(pThisCC);
    10091014    Assert((cmd & CODEC_VERB_8BIT_DATA) < CODECNODE_F00_PARAM_LENGTH);
    10101015    if ((cmd & CODEC_VERB_8BIT_DATA) >= CODECNODE_F00_PARAM_LENGTH)
     
    10211026
    10221027/* F01 */
    1023 static DECLCALLBACK(int) vrbProcGetConSelectCtrl(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1024 {
     1028static DECLCALLBACK(int) vrbProcGetConSelectCtrl(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1029{
     1030    RT_NOREF(pThisCC);
    10251031    *pResp = 0;
    10261032
     
    10421048
    10431049/* 701 */
    1044 static DECLCALLBACK(int) vrbProcSetConSelectCtrl(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1045 {
     1050static DECLCALLBACK(int) vrbProcSetConSelectCtrl(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1051{
     1052    RT_NOREF(pThisCC);
    10461053    *pResp = 0;
    10471054
     
    10671074
    10681075/* F07 */
    1069 static DECLCALLBACK(int) vrbProcGetPinCtrl(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1070 {
     1076static DECLCALLBACK(int) vrbProcGetPinCtrl(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1077{
     1078    RT_NOREF(pThisCC);
    10711079    *pResp = 0;
    10721080
     
    10901098
    10911099/* 707 */
    1092 static DECLCALLBACK(int) vrbProcSetPinCtrl(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1093 {
     1100static DECLCALLBACK(int) vrbProcSetPinCtrl(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1101{
     1102    RT_NOREF(pThisCC);
    10941103    *pResp = 0;
    10951104
     
    11181127
    11191128/* F08 */
    1120 static DECLCALLBACK(int) vrbProcGetUnsolicitedEnabled(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1121 {
     1129static DECLCALLBACK(int) vrbProcGetUnsolicitedEnabled(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1130{
     1131    RT_NOREF(pThisCC);
    11221132    *pResp = 0;
    11231133
     
    11411151
    11421152/* 708 */
    1143 static DECLCALLBACK(int) vrbProcSetUnsolicitedEnabled(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1144 {
     1153static DECLCALLBACK(int) vrbProcSetUnsolicitedEnabled(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1154{
     1155    RT_NOREF(pThisCC);
    11451156    *pResp = 0;
    11461157
     
    11681179
    11691180/* F09 */
    1170 static DECLCALLBACK(int) vrbProcGetPinSense(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1171 {
     1181static DECLCALLBACK(int) vrbProcGetPinSense(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1182{
     1183    RT_NOREF(pThisCC);
    11721184    *pResp = 0;
    11731185
     
    11861198
    11871199/* 709 */
    1188 static DECLCALLBACK(int) vrbProcSetPinSense(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1189 {
     1200static DECLCALLBACK(int) vrbProcSetPinSense(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1201{
     1202    RT_NOREF(pThisCC);
    11901203    *pResp = 0;
    11911204
     
    12041217}
    12051218
    1206 static DECLCALLBACK(int) vrbProcGetConnectionListEntry(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1207 {
     1219static DECLCALLBACK(int) vrbProcGetConnectionListEntry(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1220{
     1221    RT_NOREF(pThisCC);
    12081222    *pResp = 0;
    12091223
     
    12191233
    12201234/* F03 */
    1221 static DECLCALLBACK(int) vrbProcGetProcessingState(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1222 {
     1235static DECLCALLBACK(int) vrbProcGetProcessingState(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1236{
     1237    RT_NOREF(pThisCC);
    12231238    *pResp = 0;
    12241239
     
    12301245
    12311246/* 703 */
    1232 static DECLCALLBACK(int) vrbProcSetProcessingState(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1233 {
     1247static DECLCALLBACK(int) vrbProcSetProcessingState(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1248{
     1249    RT_NOREF(pThisCC);
    12341250    *pResp = 0;
    12351251
     
    12401256
    12411257/* F0D */
    1242 static DECLCALLBACK(int) vrbProcGetDigitalConverter(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1243 {
     1258static DECLCALLBACK(int) vrbProcGetDigitalConverter(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1259{
     1260    RT_NOREF(pThisCC);
    12441261    *pResp = 0;
    12451262
     
    12641281
    12651282/* 70D */
    1266 static DECLCALLBACK(int) vrbProcSetDigitalConverter1(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1267 {
     1283static DECLCALLBACK(int) vrbProcSetDigitalConverter1(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1284{
     1285    RT_NOREF(pThisCC);
    12681286    return codecSetDigitalConverter(pThis, cmd, 0, pResp);
    12691287}
    12701288
    12711289/* 70E */
    1272 static DECLCALLBACK(int) vrbProcSetDigitalConverter2(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1273 {
     1290static DECLCALLBACK(int) vrbProcSetDigitalConverter2(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1291{
     1292    RT_NOREF(pThisCC);
    12741293    return codecSetDigitalConverter(pThis, cmd, 8, pResp);
    12751294}
    12761295
    12771296/* F20 */
    1278 static DECLCALLBACK(int) vrbProcGetSubId(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1279 {
     1297static DECLCALLBACK(int) vrbProcGetSubId(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1298{
     1299    RT_NOREF(pThisCC);
    12801300    Assert(CODEC_CAD(cmd) == pThis->id);
    12811301    Assert(CODEC_NID(cmd) < pThis->cTotalNodes);
     
    13111331
    13121332/* 720 */
    1313 static DECLCALLBACK(int) vrbProcSetSubId0(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1314 {
     1333static DECLCALLBACK(int) vrbProcSetSubId0(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1334{
     1335    RT_NOREF(pThisCC);
    13151336    *pResp = 0;
    13161337    return codecSetSubIdX(pThis, cmd, 0);
     
    13181339
    13191340/* 721 */
    1320 static DECLCALLBACK(int) vrbProcSetSubId1(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1321 {
     1341static DECLCALLBACK(int) vrbProcSetSubId1(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1342{
     1343    RT_NOREF(pThisCC);
    13221344    *pResp = 0;
    13231345    return codecSetSubIdX(pThis, cmd, 8);
     
    13251347
    13261348/* 722 */
    1327 static DECLCALLBACK(int) vrbProcSetSubId2(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1328 {
     1349static DECLCALLBACK(int) vrbProcSetSubId2(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1350{
     1351    RT_NOREF(pThisCC);
    13291352    *pResp = 0;
    13301353    return codecSetSubIdX(pThis, cmd, 16);
     
    13321355
    13331356/* 723 */
    1334 static DECLCALLBACK(int) vrbProcSetSubId3(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1335 {
     1357static DECLCALLBACK(int) vrbProcSetSubId3(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1358{
     1359    RT_NOREF(pThisCC);
    13361360    *pResp = 0;
    13371361    return codecSetSubIdX(pThis, cmd, 24);
    13381362}
    13391363
    1340 static DECLCALLBACK(int) vrbProcReset(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1341 {
     1364static DECLCALLBACK(int) vrbProcReset(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1365{
     1366    RT_NOREF(pThisCC);
    13421367    Assert(CODEC_CAD(cmd) == pThis->id);
    13431368
     
    13571382
    13581383/* F05 */
    1359 static DECLCALLBACK(int) vrbProcGetPowerState(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1360 {
     1384static DECLCALLBACK(int) vrbProcGetPowerState(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1385{
     1386    RT_NOREF(pThisCC);
    13611387    *pResp = 0;
    13621388
     
    13871413/* 705 */
    13881414#if 1
    1389 static DECLCALLBACK(int) vrbProcSetPowerState(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1390 {
     1415static DECLCALLBACK(int) vrbProcSetPowerState(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1416{
     1417    RT_NOREF(pThisCC);
    13911418    *pResp = 0;
    13921419
     
    14891516}
    14901517
    1491 static DECLCALLBACK(int) vrbProcSetPowerState(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1492 {
     1518static DECLCALLBACK(int) vrbProcSetPowerState(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1519{
     1520    RT_NOREF(pThisCC);
    14931521    Assert(CODEC_CAD(cmd) == pThis->id);
    14941522    Assert(CODEC_NID(cmd) < pThis->cTotalNodes);
     
    15571585
    15581586/* F06 */
    1559 static DECLCALLBACK(int) vrbProcGetStreamId(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1560 {
     1587static DECLCALLBACK(int) vrbProcGetStreamId(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1588{
     1589    RT_NOREF(pThisCC);
    15611590    *pResp = 0;
    15621591
     
    15811610
    15821611/* A0 */
    1583 static DECLCALLBACK(int) vrbProcGetConverterFormat(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1584 {
     1612static DECLCALLBACK(int) vrbProcGetConverterFormat(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1613{
     1614    RT_NOREF(pThisCC);
    15851615    *pResp = 0;
    15861616
     
    16021632
    16031633/* Also see section 3.7.1. */
    1604 static DECLCALLBACK(int) vrbProcSetConverterFormat(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1605 {
     1634static DECLCALLBACK(int) vrbProcSetConverterFormat(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1635{
     1636    RT_NOREF(pThisCC);
    16061637    *pResp = 0;
    16071638
     
    16211652
    16221653/* F0C */
    1623 static DECLCALLBACK(int) vrbProcGetEAPD_BTLEnabled(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1624 {
     1654static DECLCALLBACK(int) vrbProcGetEAPD_BTLEnabled(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1655{
     1656    RT_NOREF(pThisCC);
    16251657    *pResp = 0;
    16261658
     
    16381670
    16391671/* 70C */
    1640 static DECLCALLBACK(int) vrbProcSetEAPD_BTLEnabled(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1641 {
     1672static DECLCALLBACK(int) vrbProcSetEAPD_BTLEnabled(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1673{
     1674    RT_NOREF(pThisCC);
    16421675    *pResp = 0;
    16431676
     
    16591692
    16601693/* F0F */
    1661 static DECLCALLBACK(int) vrbProcGetVolumeKnobCtrl(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1662 {
     1694static DECLCALLBACK(int) vrbProcGetVolumeKnobCtrl(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1695{
     1696    RT_NOREF(pThisCC);
    16631697    *pResp = 0;
    16641698
     
    16721706
    16731707/* 70F */
    1674 static DECLCALLBACK(int) vrbProcSetVolumeKnobCtrl(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1675 {
     1708static DECLCALLBACK(int) vrbProcSetVolumeKnobCtrl(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1709{
     1710    RT_NOREF(pThisCC);
    16761711    *pResp = 0;
    16771712
     
    16891724
    16901725/* F15 */
    1691 static DECLCALLBACK(int) vrbProcGetGPIOData(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1692 {
    1693     RT_NOREF(pThis, cmd);
     1726static DECLCALLBACK(int) vrbProcGetGPIOData(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1727{
     1728    RT_NOREF(pThis, pThisCC, cmd);
    16941729    *pResp = 0;
    16951730    return VINF_SUCCESS;
     
    16971732
    16981733/* 715 */
    1699 static DECLCALLBACK(int) vrbProcSetGPIOData(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1700 {
    1701     RT_NOREF(pThis, cmd);
     1734static DECLCALLBACK(int) vrbProcSetGPIOData(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1735{
     1736    RT_NOREF(pThis, pThisCC, cmd);
    17021737    *pResp = 0;
    17031738    return VINF_SUCCESS;
     
    17051740
    17061741/* F16 */
    1707 static DECLCALLBACK(int) vrbProcGetGPIOEnableMask(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1708 {
    1709     RT_NOREF(pThis, cmd);
     1742static DECLCALLBACK(int) vrbProcGetGPIOEnableMask(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1743{
     1744    RT_NOREF(pThis, pThisCC, cmd);
    17101745    *pResp = 0;
    17111746    return VINF_SUCCESS;
     
    17131748
    17141749/* 716 */
    1715 static DECLCALLBACK(int) vrbProcSetGPIOEnableMask(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1716 {
    1717     RT_NOREF(pThis, cmd);
     1750static DECLCALLBACK(int) vrbProcSetGPIOEnableMask(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1751{
     1752    RT_NOREF(pThis, pThisCC, cmd);
    17181753    *pResp = 0;
    17191754    return VINF_SUCCESS;
     
    17211756
    17221757/* F17 */
    1723 static DECLCALLBACK(int) vrbProcGetGPIODirection(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1724 {
     1758static DECLCALLBACK(int) vrbProcGetGPIODirection(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1759{
     1760    RT_NOREF(pThisCC);
    17251761    *pResp = 0;
    17261762
     
    17351771
    17361772/* 717 */
    1737 static DECLCALLBACK(int) vrbProcSetGPIODirection(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1738 {
     1773static DECLCALLBACK(int) vrbProcSetGPIODirection(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1774{
     1775    RT_NOREF(pThisCC);
    17391776    *pResp = 0;
    17401777
     
    17521789
    17531790/* F1C */
    1754 static DECLCALLBACK(int) vrbProcGetConfig(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1755 {
     1791static DECLCALLBACK(int) vrbProcGetConfig(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1792{
     1793    RT_NOREF(pThisCC);
    17561794    *pResp = 0;
    17571795
     
    17991837
    18001838/* 71C */
    1801 static DECLCALLBACK(int) vrbProcSetConfig0(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1802 {
     1839static DECLCALLBACK(int) vrbProcSetConfig0(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1840{
     1841    RT_NOREF(pThisCC);
    18031842    *pResp = 0;
    18041843    return codecSetConfigX(pThis, cmd, 0);
     
    18061845
    18071846/* 71D */
    1808 static DECLCALLBACK(int) vrbProcSetConfig1(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1809 {
     1847static DECLCALLBACK(int) vrbProcSetConfig1(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1848{
     1849    RT_NOREF(pThisCC);
    18101850    *pResp = 0;
    18111851    return codecSetConfigX(pThis, cmd, 8);
     
    18131853
    18141854/* 71E */
    1815 static DECLCALLBACK(int) vrbProcSetConfig2(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1816 {
     1855static DECLCALLBACK(int) vrbProcSetConfig2(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1856{
     1857    RT_NOREF(pThisCC);
    18171858    *pResp = 0;
    18181859    return codecSetConfigX(pThis, cmd, 16);
     
    18201861
    18211862/* 71E */
    1822 static DECLCALLBACK(int) vrbProcSetConfig3(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1823 {
     1863static DECLCALLBACK(int) vrbProcSetConfig3(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1864{
     1865    RT_NOREF(pThisCC);
    18241866    *pResp = 0;
    18251867    return codecSetConfigX(pThis, cmd, 24);
     
    18271869
    18281870/* F04 */
    1829 static DECLCALLBACK(int) vrbProcGetSDISelect(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1830 {
     1871static DECLCALLBACK(int) vrbProcGetSDISelect(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1872{
     1873    RT_NOREF(pThisCC);
    18311874    *pResp = 0;
    18321875
     
    18401883
    18411884/* 704 */
    1842 static DECLCALLBACK(int) vrbProcSetSDISelect(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    1843 {
     1885static DECLCALLBACK(int) vrbProcSetSDISelect(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
     1886{
     1887    RT_NOREF(pThisCC);
    18441888    *pResp = 0;
    18451889
     
    18561900}
    18571901
    1858 #else /* IN_RING3 */
     1902#ifdef IN_RING3
    18591903
    18601904/* 3-- */
    1861 static DECLCALLBACK(int) vrbProcR3SetAmplifier(PHDACODEC pThis, PHDACODECR3 pThisCC, uint32_t cmd, uint64_t *pResp)
     1905static DECLCALLBACK(int) vrbProcR3SetAmplifier(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
    18621906{
    18631907    *pResp = 0;
     
    19241968
    19251969/* 706 */
    1926 static DECLCALLBACK(int) vrbProcR3SetStreamId(PHDACODEC pThis, PHDACODECR3 pThisCC, uint32_t cmd, uint64_t *pResp)
     1970static DECLCALLBACK(int) vrbProcR3SetStreamId(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t cmd, uint64_t *pResp)
    19271971{
    19281972    *pResp = 0;
     
    19381982
    19391983    PDMAUDIODIR enmDir;
    1940     uint32_t *pu32Addr = NULL;
     1984    uint32_t   *pu32Addr;
    19411985    if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
    19421986    {
     
    19632007        enmDir = PDMAUDIODIR_UNKNOWN;
    19642008        LogRel2(("HDA: Warning: Unhandled set stream ID command for NID0x%02x: 0x%x\n", CODEC_NID(cmd), cmd));
     2009        return VINF_SUCCESS;
    19652010    }
    19662011
    19672012    /* Do we (re-)assign our input/output SDn (SDI/SDO) IDs? */
    1968     if (enmDir != PDMAUDIODIR_UNKNOWN)
    1969     {
    1970         pThis->aNodes[CODEC_NID(cmd)].node.uSD      = uSD;
    1971         pThis->aNodes[CODEC_NID(cmd)].node.uChannel = uChannel;
    1972 
    1973         if (enmDir == PDMAUDIODIR_OUT)
    1974         {
    1975             /** @todo Check if non-interleaved streams need a different channel / SDn? */
    1976 
    1977             /* Propagate to the controller. */
    1978             pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_FRONT,      uSD, uChannel);
    1979 #ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
    1980             pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_CENTER_LFE, uSD, uChannel);
    1981             pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_REAR,       uSD, uChannel);
    1982 #endif
    1983         }
    1984         else if (enmDir == PDMAUDIODIR_IN)
    1985         {
    1986             pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_LINE_IN,    uSD, uChannel);
    1987 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    1988             pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_MIC_IN,     uSD, uChannel);
    1989 #endif
    1990         }
    1991     }
    1992 
    1993     if (pu32Addr)
    1994         hdaCodecSetRegisterU8(pu32Addr, cmd, 0);
    1995 
    1996     return VINF_SUCCESS;
    1997 }
    1998 
    1999 #endif /* IN_RING0 */
    2000 
    2001 #ifdef IN_RING0
     2013    pThis->aNodes[CODEC_NID(cmd)].node.uSD      = uSD;
     2014    pThis->aNodes[CODEC_NID(cmd)].node.uChannel = uChannel;
     2015
     2016    if (enmDir == PDMAUDIODIR_OUT)
     2017    {
     2018        /** @todo Check if non-interleaved streams need a different channel / SDn? */
     2019
     2020        /* Propagate to the controller. */
     2021        pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_FRONT,      uSD, uChannel);
     2022# ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
     2023        pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_CENTER_LFE, uSD, uChannel);
     2024        pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_REAR,       uSD, uChannel);
     2025# endif
     2026    }
     2027    else if (enmDir == PDMAUDIODIR_IN)
     2028    {
     2029        pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_LINE_IN,    uSD, uChannel);
     2030# ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     2031        pThisCC->pfnCbMixerControl(pThisCC->pDevIns, PDMAUDIOMIXERCTL_MIC_IN,     uSD, uChannel);
     2032# endif
     2033    }
     2034
     2035    hdaCodecSetRegisterU8(pu32Addr, cmd, 0);
     2036
     2037    return VINF_SUCCESS;
     2038}
     2039
     2040#endif /* IN_RING3 */
     2041
    20022042
    20032043/**
    2004  * HDA codec verb map for ring-0.
     2044 * HDA codec verb descriptors.
     2045 *
    20052046 * @todo Any reason not to use binary search here?
    20062047 *      bird: because you'd need to sort the entries first...
    20072048 */
    2008 static const CODECVERBR0 g_aCodecVerbsR0[] =
    2009 {
    2010     /* Verb        Verb mask            Callback                        Name
    2011      * ---------- --------------------- ----------------------------------------------------------
    2012      */
    2013     { 0x000F0000, CODEC_VERB_8BIT_CMD , vrbProcGetParameter           , "GetParameter          " },
    2014     { 0x000F0100, CODEC_VERB_8BIT_CMD , vrbProcGetConSelectCtrl       , "GetConSelectCtrl      " },
    2015     { 0x00070100, CODEC_VERB_8BIT_CMD , vrbProcSetConSelectCtrl       , "SetConSelectCtrl      " },
    2016     { 0x000F0600, CODEC_VERB_8BIT_CMD , vrbProcGetStreamId            , "GetStreamId           " },
    2017     { 0x000F0700, CODEC_VERB_8BIT_CMD , vrbProcGetPinCtrl             , "GetPinCtrl            " },
    2018     { 0x00070700, CODEC_VERB_8BIT_CMD , vrbProcSetPinCtrl             , "SetPinCtrl            " },
    2019     { 0x000F0800, CODEC_VERB_8BIT_CMD , vrbProcGetUnsolicitedEnabled  , "GetUnsolicitedEnabled " },
    2020     { 0x00070800, CODEC_VERB_8BIT_CMD , vrbProcSetUnsolicitedEnabled  , "SetUnsolicitedEnabled " },
    2021     { 0x000F0900, CODEC_VERB_8BIT_CMD , vrbProcGetPinSense            , "GetPinSense           " },
    2022     { 0x00070900, CODEC_VERB_8BIT_CMD , vrbProcSetPinSense            , "SetPinSense           " },
    2023     { 0x000F0200, CODEC_VERB_8BIT_CMD , vrbProcGetConnectionListEntry , "GetConnectionListEntry" },
    2024     { 0x000F0300, CODEC_VERB_8BIT_CMD , vrbProcGetProcessingState     , "GetProcessingState    " },
    2025     { 0x00070300, CODEC_VERB_8BIT_CMD , vrbProcSetProcessingState     , "SetProcessingState    " },
    2026     { 0x000F0D00, CODEC_VERB_8BIT_CMD , vrbProcGetDigitalConverter    , "GetDigitalConverter   " },
    2027     { 0x00070D00, CODEC_VERB_8BIT_CMD , vrbProcSetDigitalConverter1   , "SetDigitalConverter1  " },
    2028     { 0x00070E00, CODEC_VERB_8BIT_CMD , vrbProcSetDigitalConverter2   , "SetDigitalConverter2  " },
    2029     { 0x000F2000, CODEC_VERB_8BIT_CMD , vrbProcGetSubId               , "GetSubId              " },
    2030     { 0x00072000, CODEC_VERB_8BIT_CMD , vrbProcSetSubId0              , "SetSubId0             " },
    2031     { 0x00072100, CODEC_VERB_8BIT_CMD , vrbProcSetSubId1              , "SetSubId1             " },
    2032     { 0x00072200, CODEC_VERB_8BIT_CMD , vrbProcSetSubId2              , "SetSubId2             " },
    2033     { 0x00072300, CODEC_VERB_8BIT_CMD , vrbProcSetSubId3              , "SetSubId3             " },
    2034     { 0x0007FF00, CODEC_VERB_8BIT_CMD , vrbProcReset                  , "Reset                 " },
    2035     { 0x000F0500, CODEC_VERB_8BIT_CMD , vrbProcGetPowerState          , "GetPowerState         " },
    2036     { 0x00070500, CODEC_VERB_8BIT_CMD , vrbProcSetPowerState          , "SetPowerState         " },
    2037     { 0x000F0C00, CODEC_VERB_8BIT_CMD , vrbProcGetEAPD_BTLEnabled     , "GetEAPD_BTLEnabled    " },
    2038     { 0x00070C00, CODEC_VERB_8BIT_CMD , vrbProcSetEAPD_BTLEnabled     , "SetEAPD_BTLEnabled    " },
    2039     { 0x000F0F00, CODEC_VERB_8BIT_CMD , vrbProcGetVolumeKnobCtrl      , "GetVolumeKnobCtrl     " },
    2040     { 0x00070F00, CODEC_VERB_8BIT_CMD , vrbProcSetVolumeKnobCtrl      , "SetVolumeKnobCtrl     " },
    2041     { 0x000F1500, CODEC_VERB_8BIT_CMD , vrbProcGetGPIOData            , "GetGPIOData           " },
    2042     { 0x00071500, CODEC_VERB_8BIT_CMD , vrbProcSetGPIOData            , "SetGPIOData           " },
    2043     { 0x000F1600, CODEC_VERB_8BIT_CMD , vrbProcGetGPIOEnableMask      , "GetGPIOEnableMask     " },
    2044     { 0x00071600, CODEC_VERB_8BIT_CMD , vrbProcSetGPIOEnableMask      , "SetGPIOEnableMask     " },
    2045     { 0x000F1700, CODEC_VERB_8BIT_CMD , vrbProcGetGPIODirection       , "GetGPIODirection      " },
    2046     { 0x00071700, CODEC_VERB_8BIT_CMD , vrbProcSetGPIODirection       , "SetGPIODirection      " },
    2047     { 0x000F1C00, CODEC_VERB_8BIT_CMD , vrbProcGetConfig              , "GetConfig             " },
    2048     { 0x00071C00, CODEC_VERB_8BIT_CMD , vrbProcSetConfig0             , "SetConfig0            " },
    2049     { 0x00071D00, CODEC_VERB_8BIT_CMD , vrbProcSetConfig1             , "SetConfig1            " },
    2050     { 0x00071E00, CODEC_VERB_8BIT_CMD , vrbProcSetConfig2             , "SetConfig2            " },
    2051     { 0x00071F00, CODEC_VERB_8BIT_CMD , vrbProcSetConfig3             , "SetConfig3            " },
    2052     { 0x000A0000, CODEC_VERB_16BIT_CMD, vrbProcGetConverterFormat     , "GetConverterFormat    " },
    2053     { 0x00020000, CODEC_VERB_16BIT_CMD, vrbProcSetConverterFormat     , "SetConverterFormat    " },
    2054     { 0x000B0000, CODEC_VERB_16BIT_CMD, vrbProcGetAmplifier           , "GetAmplifier          " },
    2055     { 0x000F0400, CODEC_VERB_8BIT_CMD , vrbProcGetSDISelect           , "GetSDISelect          " },
    2056     { 0x00070400, CODEC_VERB_8BIT_CMD , vrbProcSetSDISelect           , "SetSDISelect          " }
     2049static const CODECVERB g_aCodecVerbs[] =
     2050{
     2051    /* Verb        Verb mask            Callback                                   Name
     2052       ---------- --------------------- ------------------------------------------------------------------- */
     2053    { 0x000F0000, CODEC_VERB_8BIT_CMD , vrbProcGetParameter                      , "GetParameter          " },
     2054    { 0x000F0100, CODEC_VERB_8BIT_CMD , vrbProcGetConSelectCtrl                  , "GetConSelectCtrl      " },
     2055    { 0x00070100, CODEC_VERB_8BIT_CMD , vrbProcSetConSelectCtrl                  , "SetConSelectCtrl      " },
     2056    { 0x000F0600, CODEC_VERB_8BIT_CMD , vrbProcGetStreamId                       , "GetStreamId           " },
     2057    { 0x00070600, CODEC_VERB_8BIT_CMD , CTX_EXPR(vrbProcR3SetStreamId,NULL,NULL) , "SetStreamId           " },
     2058    { 0x000F0700, CODEC_VERB_8BIT_CMD , vrbProcGetPinCtrl                        , "GetPinCtrl            " },
     2059    { 0x00070700, CODEC_VERB_8BIT_CMD , vrbProcSetPinCtrl                        , "SetPinCtrl            " },
     2060    { 0x000F0800, CODEC_VERB_8BIT_CMD , vrbProcGetUnsolicitedEnabled             , "GetUnsolicitedEnabled " },
     2061    { 0x00070800, CODEC_VERB_8BIT_CMD , vrbProcSetUnsolicitedEnabled             , "SetUnsolicitedEnabled " },
     2062    { 0x000F0900, CODEC_VERB_8BIT_CMD , vrbProcGetPinSense                       , "GetPinSense           " },
     2063    { 0x00070900, CODEC_VERB_8BIT_CMD , vrbProcSetPinSense                       , "SetPinSense           " },
     2064    { 0x000F0200, CODEC_VERB_8BIT_CMD , vrbProcGetConnectionListEntry            , "GetConnectionListEntry" },
     2065    { 0x000F0300, CODEC_VERB_8BIT_CMD , vrbProcGetProcessingState                , "GetProcessingState    " },
     2066    { 0x00070300, CODEC_VERB_8BIT_CMD , vrbProcSetProcessingState                , "SetProcessingState    " },
     2067    { 0x000F0D00, CODEC_VERB_8BIT_CMD , vrbProcGetDigitalConverter               , "GetDigitalConverter   " },
     2068    { 0x00070D00, CODEC_VERB_8BIT_CMD , vrbProcSetDigitalConverter1              , "SetDigitalConverter1  " },
     2069    { 0x00070E00, CODEC_VERB_8BIT_CMD , vrbProcSetDigitalConverter2              , "SetDigitalConverter2  " },
     2070    { 0x000F2000, CODEC_VERB_8BIT_CMD , vrbProcGetSubId                          , "GetSubId              " },
     2071    { 0x00072000, CODEC_VERB_8BIT_CMD , vrbProcSetSubId0                         , "SetSubId0             " },
     2072    { 0x00072100, CODEC_VERB_8BIT_CMD , vrbProcSetSubId1                         , "SetSubId1             " },
     2073    { 0x00072200, CODEC_VERB_8BIT_CMD , vrbProcSetSubId2                         , "SetSubId2             " },
     2074    { 0x00072300, CODEC_VERB_8BIT_CMD , vrbProcSetSubId3                         , "SetSubId3             " },
     2075    { 0x0007FF00, CODEC_VERB_8BIT_CMD , vrbProcReset                             , "Reset                 " },
     2076    { 0x000F0500, CODEC_VERB_8BIT_CMD , vrbProcGetPowerState                     , "GetPowerState         " },
     2077    { 0x00070500, CODEC_VERB_8BIT_CMD , vrbProcSetPowerState                     , "SetPowerState         " },
     2078    { 0x000F0C00, CODEC_VERB_8BIT_CMD , vrbProcGetEAPD_BTLEnabled                , "GetEAPD_BTLEnabled    " },
     2079    { 0x00070C00, CODEC_VERB_8BIT_CMD , vrbProcSetEAPD_BTLEnabled                , "SetEAPD_BTLEnabled    " },
     2080    { 0x000F0F00, CODEC_VERB_8BIT_CMD , vrbProcGetVolumeKnobCtrl                 , "GetVolumeKnobCtrl     " },
     2081    { 0x00070F00, CODEC_VERB_8BIT_CMD , vrbProcSetVolumeKnobCtrl                 , "SetVolumeKnobCtrl     " },
     2082    { 0x000F1500, CODEC_VERB_8BIT_CMD , vrbProcGetGPIOData                       , "GetGPIOData           " },
     2083    { 0x00071500, CODEC_VERB_8BIT_CMD , vrbProcSetGPIOData                       , "SetGPIOData           " },
     2084    { 0x000F1600, CODEC_VERB_8BIT_CMD , vrbProcGetGPIOEnableMask                 , "GetGPIOEnableMask     " },
     2085    { 0x00071600, CODEC_VERB_8BIT_CMD , vrbProcSetGPIOEnableMask                 , "SetGPIOEnableMask     " },
     2086    { 0x000F1700, CODEC_VERB_8BIT_CMD , vrbProcGetGPIODirection                  , "GetGPIODirection      " },
     2087    { 0x00071700, CODEC_VERB_8BIT_CMD , vrbProcSetGPIODirection                  , "SetGPIODirection      " },
     2088    { 0x000F1C00, CODEC_VERB_8BIT_CMD , vrbProcGetConfig                         , "GetConfig             " },
     2089    { 0x00071C00, CODEC_VERB_8BIT_CMD , vrbProcSetConfig0                        , "SetConfig0            " },
     2090    { 0x00071D00, CODEC_VERB_8BIT_CMD , vrbProcSetConfig1                        , "SetConfig1            " },
     2091    { 0x00071E00, CODEC_VERB_8BIT_CMD , vrbProcSetConfig2                        , "SetConfig2            " },
     2092    { 0x00071F00, CODEC_VERB_8BIT_CMD , vrbProcSetConfig3                        , "SetConfig3            " },
     2093    { 0x000A0000, CODEC_VERB_16BIT_CMD, vrbProcGetConverterFormat                , "GetConverterFormat    " },
     2094    { 0x00020000, CODEC_VERB_16BIT_CMD, vrbProcSetConverterFormat                , "SetConverterFormat    " },
     2095    { 0x000B0000, CODEC_VERB_16BIT_CMD, vrbProcGetAmplifier                      , "GetAmplifier          " },
     2096    { 0x00030000, CODEC_VERB_16BIT_CMD, CTX_EXPR(vrbProcR3SetAmplifier,NULL,NULL), "SetAmplifier          " },
     2097    { 0x000F0400, CODEC_VERB_8BIT_CMD , vrbProcGetSDISelect                      , "GetSDISelect          " },
     2098    { 0x00070400, CODEC_VERB_8BIT_CMD , vrbProcSetSDISelect                      , "SetSDISelect          " },
    20572099    /** @todo Implement 0x7e7: IDT Set GPIO (STAC922x only). */
    20582100};
    20592101
    2060 #else /* IN_RING3 */
    2061 
    2062 /**
    2063  * HDA codec verb map for ring-3.
    2064  */
    2065 static const CODECVERBR3 g_aCodecVerbsR3[] =
    2066 {
    2067    /* Verb        Verb mask            Callback                        Name
    2068     * ---------- --------------------- ----------------------------------------------------------
    2069     */
    2070    { 0x00070600, CODEC_VERB_8BIT_CMD , vrbProcR3SetStreamId          , "SetStreamId           " },
    2071    { 0x00030000, CODEC_VERB_16BIT_CMD, vrbProcR3SetAmplifier         , "SetAmplifier          " }
    2072 };
    2073 
    2074 #endif /* IN_RING0 */
    20752102
    20762103#ifdef IN_RING3
     
    23112338}
    23122339
    2313 static DECLCALLBACK(int) codecR3Lookup(PHDACODEC pThis, PHDACODECR3 pThisCC, uint32_t cmd, uint64_t *puResp)
    2314 {
    2315     AssertPtrReturn(pThisCC,  VERR_INVALID_POINTER);
    2316     AssertPtrReturn(puResp, VERR_INVALID_POINTER);
    2317 
    2318     STAM_COUNTER_INC(&pThisCC->StatLookupsR3);
    2319 
    2320     if (CODEC_CAD(cmd) != pThis->id)
    2321     {
    2322         *puResp = 0;
    2323         AssertMsgFailed(("Unknown codec address 0x%x\n", CODEC_CAD(cmd)));
    2324         return VERR_INVALID_PARAMETER;
    2325     }
    2326 
    2327     if (   CODEC_VERBDATA(cmd) == 0
    2328         || CODEC_NID(cmd) >= pThis->cTotalNodes)
    2329     {
    2330         *puResp = 0;
    2331         AssertMsgFailed(("[NID0x%02x] Unknown / invalid node or data (0x%x)\n", CODEC_NID(cmd), CODEC_VERBDATA(cmd)));
    2332         return VERR_INVALID_PARAMETER;
    2333     }
    2334 
    2335     /** @todo r=andy Implement a binary search here. */
    2336     for (size_t i = 0; i < pThisCC->cVerbs; i++)
    2337     {
    2338         PCODECVERBR3 pVerb = &pThisCC->aVerbs[i];
    2339 
    2340         if ((CODEC_VERBDATA(cmd) & pVerb->mask) == pThisCC->aVerbs[i].verb)
    2341         {
    2342             AssertPtrReturn(pVerb->pfn, VERR_NOT_IMPLEMENTED); /* Paranoia. */
    2343 
    2344             int rc2 = pVerb->pfn(pThis, pThisCC, cmd, puResp);
    2345             AssertRC(rc2);
     2340#endif /* IN_RING3 */
     2341
     2342/**
     2343 * Implements
     2344 */
     2345static DECLCALLBACK(int) codecLookup(PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t uCmd, uint64_t *puResp)
     2346{
     2347    /*
     2348     * Clear the return value and assert some sanity.
     2349     */
     2350    AssertPtr(puResp);
     2351    *puResp = 0;
     2352    AssertPtr(pThis);
     2353    AssertPtr(pThisCC);
     2354    AssertMsgReturn(CODEC_CAD(uCmd) == pThis->id,
     2355                    ("Unknown codec address 0x%x\n", CODEC_CAD(uCmd)),
     2356                    VERR_INVALID_PARAMETER);
     2357    AssertMsgReturn(   CODEC_VERBDATA(uCmd) != 0
     2358                    && CODEC_NID(uCmd) < pThis->cTotalNodes,
     2359                    ("[NID0x%02x] Unknown / invalid node or data (0x%x)\n", CODEC_NID(uCmd), CODEC_VERBDATA(uCmd)),
     2360                    VERR_INVALID_PARAMETER);
     2361    STAM_COUNTER_INC(&pThis->CTX_SUFF(StatLookups));
     2362
     2363    /*
     2364     * Lookup the verb.
     2365     * Note! if we want other verb tables, add a table selector before the loop.
     2366     */
     2367    for (size_t i = 0; i < RT_ELEMENTS(g_aCodecVerbs); i++)
     2368    {
     2369        if ((CODEC_VERBDATA(uCmd) & g_aCodecVerbs[i].fMask) == g_aCodecVerbs[i].uVerb)
     2370        {
     2371#ifndef IN_RING3
     2372            if (!g_aCodecVerbs[i].pfn)
     2373            {
     2374                Log3Func(("[NID0x%02x] (0x%x) %s: 0x%x -> VERR_INVALID_CONTEXT\n", /* -> ring-3 */
     2375                          CODEC_NID(uCmd), g_aCodecVerbs[i].uVerb, g_aCodecVerbs[i].pszName, CODEC_VERB_PAYLOAD8(uCmd)));
     2376                return VERR_INVALID_CONTEXT;
     2377            }
     2378#endif
     2379            AssertPtrReturn(g_aCodecVerbs[i].pfn, VERR_INTERNAL_ERROR_5); /* Paranoia^2. */
     2380
     2381            int rc = g_aCodecVerbs[i].pfn(pThis, pThisCC, uCmd, puResp);
     2382            AssertRC(rc);
    23462383            Log3Func(("[NID0x%02x] (0x%x) %s: 0x%x -> 0x%x\n",
    2347                       CODEC_NID(cmd), pVerb->verb, pVerb->pszName, CODEC_VERB_PAYLOAD8(cmd), *puResp));
    2348             return rc2;
    2349         }
    2350     }
    2351 
    2352     *puResp = 0;
    2353     LogFunc(("[NID0x%02x] Callback for %x not found\n", CODEC_NID(cmd), CODEC_VERBDATA(cmd)));
     2384                      CODEC_NID(uCmd), g_aCodecVerbs[i].uVerb, g_aCodecVerbs[i].pszName, CODEC_VERB_PAYLOAD8(uCmd), *puResp));
     2385            return rc;
     2386        }
     2387    }
     2388
     2389    LogFunc(("[NID0x%02x] Callback for %x not found\n", CODEC_NID(uCmd), CODEC_VERBDATA(uCmd)));
    23542390    return VERR_NOT_FOUND;
    23552391}
    23562392
    2357 #else /* IN_RING0 */
    2358 
    2359 static DECLCALLBACK(int) codecR0Lookup(PHDACODEC pThis, PHDACODECR0 pThisCC, uint32_t cmd, uint64_t *puResp)
    2360 {
    2361     AssertPtrReturn(pThis,  VERR_INVALID_POINTER);
    2362     AssertPtrReturn(puResp, VERR_INVALID_POINTER);
    2363 
    2364     STAM_COUNTER_INC(&pThisCC->StatLookupsR0);
    2365 
    2366     if (CODEC_CAD(cmd) != pThis->id)
    2367     {
    2368         *puResp = 0;
    2369         AssertMsgFailed(("Unknown codec address 0x%x\n", CODEC_CAD(cmd)));
    2370         return VERR_INVALID_PARAMETER;
    2371     }
    2372 
    2373     if (   CODEC_VERBDATA(cmd) == 0
    2374         || CODEC_NID(cmd) >= pThis->cTotalNodes)
    2375     {
    2376         *puResp = 0;
    2377         AssertMsgFailed(("[NID0x%02x] Unknown / invalid node or data (0x%x)\n", CODEC_NID(cmd), CODEC_VERBDATA(cmd)));
    2378         return VERR_INVALID_PARAMETER;
    2379     }
    2380 
    2381     /** @todo r=andy Implement a binary search here. */
    2382     for (size_t i = 0; i < pThisCC->cVerbs; i++)
    2383     {
    2384         PCODECVERBR0 pVerb = &pThisCC->aVerbs[i];
    2385 
    2386         if ((CODEC_VERBDATA(cmd) & pVerb->mask) == pThisCC->aVerbs[i].verb)
    2387         {
    2388             AssertPtrReturn(pVerb->pfn, VERR_NOT_IMPLEMENTED); /* Paranoia. */
    2389 
    2390             int rc2 = pVerb->pfn(pThis, cmd, puResp);
    2391             AssertRC(rc2);
    2392             Log3Func(("[NID0x%02x] (0x%x) %s: 0x%x -> 0x%x\n",
    2393                       CODEC_NID(cmd), pVerb->verb, pVerb->pszName, CODEC_VERB_PAYLOAD8(cmd), *puResp));
    2394             return rc2;
    2395         }
    2396     }
    2397 
    2398     *puResp = 0;
    2399     LogFunc(("[NID0x%02x] Callback for %x not found\n", CODEC_NID(cmd), CODEC_VERBDATA(cmd)));
    2400     return VERR_NOT_FOUND;
    2401 }
    2402 
    2403 #endif /* IN_RING0 */
    24042393
    24052394/*
     
    25732562 * @param   pCfg                CFGM node to use for configuration.
    25742563 */
    2575 int hdaR3CodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis, PHDACODECR3 pThisCC,
    2576                         uint16_t uLUN, PCFGMNODE pCfg)
     2564int hdaR3CodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis, PHDACODECR3 pThisCC, uint16_t uLUN, PCFGMNODE pCfg)
    25772565{
    25782566    AssertPtrReturn(pDevIns, VERR_INVALID_POINTER);
     
    26002588    }
    26012589
    2602     memcpy(&pThisCC->aVerbs, &g_aCodecVerbsR3, sizeof(CODECVERBR3) * RT_ELEMENTS(g_aCodecVerbsR3));
    2603     pThisCC->cVerbs = RT_ELEMENTS(g_aCodecVerbsR3);
    2604 
    26052590    pThisCC->pfnDbgSelector  = codecR3DbgSelector;
    26062591    pThisCC->pfnDbgListNodes = codecR3DbgListNodes;
    2607 
    2608     pThisCC->pfnLookup       = codecR3Lookup;
     2592    pThisCC->pfnLookup       = codecLookup;
    26092593
    26102594    /*
     
    26192603    AssertRCReturn(rc, rc);
    26202604
    2621 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    2622 # error "Implement mic-in support!"
    2623 #endif
     2605# ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     2606#  error "Implement mic-in support!"
     2607# endif
    26242608
    26252609    /*
    26262610     * Statistics
    26272611     */
    2628 #ifdef VBOX_WITH_STATISTICS
    2629     PDMDevHlpSTAMRegister(pDevIns, &pThisCC->StatLookupsR3, STAMTYPE_COUNTER, "Codec/LookupsR3", STAMUNIT_OCCURENCES, "Number of R3 codecLookup calls");
    2630 #endif
     2612    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatLookupsR3, STAMTYPE_COUNTER, "Codec/LookupsR0", STAMUNIT_OCCURENCES, "Number of R0 codecLookup calls");
     2613    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatLookupsR0, STAMTYPE_COUNTER, "Codec/LookupsR3", STAMUNIT_OCCURENCES, "Number of R3 codecLookup calls");
    26312614
    26322615    return rc;
     
    26492632    AssertPtrReturn(pThisCC, VERR_INVALID_POINTER);
    26502633
    2651     memcpy(&pThisCC->aVerbs, &g_aCodecVerbsR0, sizeof(CODECVERBR0) * RT_ELEMENTS(g_aCodecVerbsR0));
    2652     pThisCC->cVerbs = RT_ELEMENTS(g_aCodecVerbsR0);
    2653 
    2654     pThisCC->pfnLookup = codecR0Lookup;
     2634    pThisCC->pfnLookup = codecLookup;
    26552635
    26562636    /* Note: Everything else is done in the R3 part. */
    26572637
    2658     /*
    2659      * Statistics
    2660      */
    2661 #ifdef VBOX_WITH_STATISTICS
    2662     /** @todo */
    2663 #endif
    2664 
    2665     return VINF_SUCCESS;
    2666 }
    2667 
    2668 #endif /* IN_RING3 */
     2638    return VINF_SUCCESS;
     2639}
     2640
     2641#endif /* IN_RING0 */
    26692642
    26702643/**
  • trunk/src/VBox/Devices/Audio/DevHdaCodec.h

    r88235 r88502  
    3030/** Pointer to a ring-3 HDA device state.  */
    3131typedef struct HDASTATER3 *PHDASTATER3;
     32
    3233/** The ICH HDA (Intel) common codec state. */
    3334typedef struct HDACODEC *PHDACODEC;
    34 /** The ICH HDA (Intel) ring-0 state. */
     35/** The ICH HDA (Intel) ring-0 codec state. */
    3536typedef struct HDACODECR0 *PHDACODECR0;
    36 /** The ICH HDA (Intel) ring-3 state. */
     37/** The ICH HDA (Intel) ring-3 codec state. */
    3738typedef struct HDACODECR3 *PHDACODECR3;
     39/** The ICH HDA (Intel) current context codec state. */
     40typedef CTX_SUFF(PHDACODEC) PHDACODECCC;
     41
    3842/** The HDA host driver backend. */
    3943typedef struct HDADRIVER *PHDADRIVER;
     
    5155    CODEC_TYPE__32BIT_HACK = 0x7fffffff
    5256} CODEC_TYPE;
    53 
    54 /**
    55  * Verb processor method.
    56  */
    57 typedef DECLCALLBACKTYPE(int, FNHDACODECVERBPROCESSORR0,(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp));
    58 typedef FNHDACODECVERBPROCESSORR0 *PFNHDACODECVERBPROCESSORR0;
    59 typedef DECLCALLBACKTYPE(int, FNHDACODECVERBPROCESSORR3,(PHDACODEC pThis, PHDACODECR3 pThisCC, uint32_t cmd, uint64_t *pResp));
    60 typedef FNHDACODECVERBPROCESSORR3 *PFNHDACODECVERBPROCESSORR3;
    6157
    6258/* PRM 5.3.1 */
     
    568564
    569565/**
    570  * Structure for maintaining a codec verb implementation (ring-0).
    571  */
    572 typedef struct CODECVERBR0
     566 * A codec verb descriptor.
     567 */
     568typedef struct CODECVERB
    573569{
    574570    /** Verb. */
    575     uint32_t                   verb;
     571    uint32_t                   uVerb;
    576572    /** Verb mask. */
    577     uint32_t                   mask;
    578     /** Function pointer for implementation callback. */
    579     PFNHDACODECVERBPROCESSORR0 pfn;
     573    uint32_t                   fMask;
     574    /**
     575     * Function pointer for implementation callback.
     576     *
     577     * This is always a valid  pointer in ring-3, while elsewhere a NULL indicates
     578     * that we must return to ring-3 to process it.
     579     */
     580    DECLCALLBACKMEMBER(int,    pfn, (PHDACODEC pThis, PHDACODECCC pThisCC, uint32_t uCmd, uint64_t *puResp));
    580581    /** Friendly name, for debugging. */
    581582    const char                *pszName;
    582 } CODECVERBR0;
    583 /** Ponter to a  codec verb implementation (ring-0). */
    584 typedef CODECVERBR0 *PCODECVERBR0;
    585 
    586 /**
    587  * Structure for maintaining a codec verb implementation (ring-3).
    588  */
    589 typedef struct CODECVERBR3
    590 {
    591     /** Verb. */
    592     uint32_t                   verb;
    593     /** Verb mask. */
    594     uint32_t                   mask;
    595     /** Function pointer for implementation callback. */
    596     PFNHDACODECVERBPROCESSORR3 pfn;
    597     /** Friendly name, for debugging. */
    598     const char                *pszName;
    599 } CODECVERBR3;
    600 /** Ponter to a  codec verb implementation (ring-3). */
    601 typedef CODECVERBR3 *PCODECVERBR3;
     583} CODECVERB;
     584/** Pointer to a const codec verb descriptor. */
     585typedef CODECVERB const *PCCODECVERB;
     586
    602587
    603588#define AMPLIFIER_SIZE 60
     
    623608    uint32_t        au32F02_param[CODECNODE_F02_PARAM_LENGTH];
    624609} CODECCOMMONNODE;
    625 typedef CODECCOMMONNODE *PCODECCOMMONNODE;
    626610AssertCompile(CODECNODE_F00_PARAM_LENGTH == 20);  /* saved state */
    627611AssertCompile(CODECNODE_F02_PARAM_LENGTH == 16); /* saved state */
     612AssertCompileSize(CODECCOMMONNODE, (1 + 20 + 16) * sizeof(uint32_t));
     613typedef CODECCOMMONNODE *PCODECCOMMONNODE;
    628614
    629615/**
     
    835821AssertNodeSize(CODECNODE, 60 + 6);
    836822
    837 #define CODEC_VERBS_MAX     64
    838823#define CODEC_NODES_MAX     32
    839824
     
    853838
    854839    CODECNODE  aNodes[CODEC_NODES_MAX];
    855     size_t     cNodes;
     840    uint32_t   cNodes;
    856841
    857842    bool       fInReset;
    858     uint8_t    abPadding1[3];
     843    uint8_t    abPadding1[3]; /**< @todo r=bird: Merge with bPadding2 and eliminate both */
    859844
    860845    uint8_t    cTotalNodes;
     
    876861    uint8_t    au8VolKnobs[CODEC_NODES_MAX];
    877862    uint8_t    au8Reserveds[CODEC_NODES_MAX];
     863
     864    STAMCOUNTER StatLookupsR0;
     865    STAMCOUNTER StatLookupsR3;
    878866} HDACODEC;
    879867
     
    883871typedef struct HDACODECR0
    884872{
    885     CODECVERBR0             aVerbs[CODEC_VERBS_MAX];
    886     size_t                  cVerbs;
    887 
    888873    /** @name Public codec functions.
    889874     *  @{  */
     875#if 0 /** @todo r=bird: why can I just disable these and not get compile errors?  Unfinished code?  No comments.  Not at all amused! */
    890876    DECLR0CALLBACKMEMBER(void, pfnReset, (PHDACODEC pThis, PHDACODECR0 pThisCC));
    891877    DECLR0CALLBACKMEMBER(int,  pfnNodeReset, (PHDACODEC pThis, uint8_t nID, PCODECNODE pNode));
     878#endif
    892879    DECLR0CALLBACKMEMBER(int,  pfnLookup, (PHDACODEC pThis, PHDACODECR0 pThisCC, uint32_t uVerb, uint64_t *puResp));
    893880    /** @} */
    894 
    895 #ifdef VBOX_WITH_STATISTICS
    896     STAMCOUNTER StatLookupsR0;
    897 #endif
    898 
    899881} HDACODECR0;
    900882
     
    906888typedef struct HDACODECR3
    907889{
    908     CODECVERBR3             aVerbs[CODEC_VERBS_MAX];
    909     size_t                  cVerbs;
    910 
    911890    /** @name Public codec functions.
    912891     *  @{  */
     
    965944    DECLR3CALLBACKMEMBER(int,  pfnCbMixerSetVolume, (PPDMDEVINS pDevIns, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOVOLUME pVol));
    966945    /** @} */
    967 
    968 #ifdef VBOX_WITH_STATISTICS
    969     STAMCOUNTER StatLookupsR0;
    970     STAMCOUNTER StatLookupsR3;
    971 #endif
    972 
    973946} HDACODECR3;
    974947
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