VirtualBox

Changeset 59348 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Jan 14, 2016 2:48:08 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
105029
Message:

Audio: Implemented dynamic fallback support to NULL audio backends for HDA, AC'97 and SB16 emulation; also did some preparations for audio hotplugging support.

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

Legend:

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

    r59275 r59348  
    315315    uint8_t                            uLUN;
    316316    uint8_t                            Padding[5];
    317     /** Audio connector interface to the underlying
    318      *  host backend. */
     317    /** Pointer to attached driver base interface. */
     318    R3PTRTYPE(PPDMIBASE)               pDrvBase;
     319    /** Audio connector interface to the underlying host backend. */
    319320    R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pConnector;
    320321    /** Stream for line input. */
     
    372373    uint8_t                 silence[128];
    373374    int                     bup_flag;
    374     /** Pointer to the attached audio driver. */
    375     PPDMIBASE               pDrvBase;
    376375    /** The base interface for LUN\#0. */
    377376    PDMIBASE                IBase;
     
    21912190    PAC97STATE pThis = PDMINS_2_DATA(pDevIns, PAC97STATE);
    21922191
    2193     AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
    2194                     ("AC'97 device does not support hotplugging\n"),
    2195                     VERR_INVALID_PARAMETER);
    2196 
    21972192    /*
    21982193     * Attach driver.
     
    22002195    char *pszDesc = NULL;
    22012196    if (RTStrAPrintf(&pszDesc, "Audio driver port (AC'97) for LUN #%u", uLUN) <= 0)
    2202         AssertMsgReturn(pszDesc,
    2203                         ("Not enough memory for AC'97 driver port description of LUN #%u\n", uLUN),
    2204                         VERR_NO_MEMORY);
    2205 
     2197        AssertReleaseMsgReturn(pszDesc,
     2198                               ("Not enough memory for AC'97 driver port description of LUN #%u\n", uLUN),
     2199                               VERR_NO_MEMORY);
     2200
     2201    PPDMIBASE pDrvBase;
    22062202    int rc = PDMDevHlpDriverAttach(pDevIns, uLUN,
    2207                                    &pThis->IBase, &pThis->pDrvBase, pszDesc);
     2203                                   &pThis->IBase, &pDrvBase, pszDesc);
    22082204    if (RT_SUCCESS(rc))
    22092205    {
     
    22112207        if (pDrv)
    22122208        {
    2213             pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
    2214             AssertMsg(pDrv->pConnector != NULL,
    2215                       ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n",
    2216                       uLUN, rc));
     2209            pDrv->pDrvBase   = pDrvBase;
     2210            pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR);
     2211            AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n", uLUN, rc));
    22172212            pDrv->pAC97State = pThis;
    2218             pDrv->uLUN = uLUN;
     2213            pDrv->uLUN       = uLUN;
    22192214
    22202215            /*
     
    22412236                        uLUN, pszDesc, rc));
    22422237
    2243     RTStrFree(pszDesc);
     2238    if (RT_FAILURE(rc))
     2239    {
     2240        /* Only free this string on failure;
     2241         * must remain valid for the live of the driver instance. */
     2242        RTStrFree(pszDesc);
     2243    }
    22442244
    22452245    LogFunc(("iLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
     
    22472247}
    22482248
     2249static void ichac97Detach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
     2250{
     2251    LogFunc(("iLUN=%u, fFlags=0x%x\n", uLUN, fFlags));
     2252}
     2253
     2254static int ichac97Reattach(PAC97STATE pThis, PCFGMNODE pCfg, PAC97DRIVER pDrv, const char *pszDriver)
     2255{
     2256    AssertPtrReturn(pThis,     VERR_INVALID_POINTER);
     2257    AssertPtrReturn(pCfg,      VERR_INVALID_POINTER);
     2258    AssertPtrReturn(pDrv,      VERR_INVALID_POINTER);
     2259    AssertPtrReturn(pszDriver, VERR_INVALID_POINTER);
     2260
     2261    PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);
     2262    PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
     2263    PCFGMNODE pDev0 = CFGMR3GetChild(pRoot, "Devices/ichac97/0/");
     2264
     2265    /* Remove LUN branch. */
     2266    CFGMR3RemoveNode(CFGMR3GetChildF(pDev0, "LUN#%u/", pDrv->uLUN));
     2267
     2268    int rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */);
     2269    if (RT_FAILURE(rc))
     2270        return rc;
     2271
     2272#define RC_CHECK() if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; }
     2273
     2274    do
     2275    {
     2276        PCFGMNODE pLunL0;
     2277        rc = CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%u/", pDrv->uLUN);  RC_CHECK();
     2278        rc = CFGMR3InsertString(pLunL0, "Driver",       "AUDIO");       RC_CHECK();
     2279        rc = CFGMR3InsertNode(pLunL0,   "Config/",       NULL);         RC_CHECK();
     2280
     2281        PCFGMNODE pLunL1, pLunL2;
     2282        rc = CFGMR3InsertNode  (pLunL0, "AttachedDriver/", &pLunL1);    RC_CHECK();
     2283        rc = CFGMR3InsertNode  (pLunL1,  "Config/",        &pLunL2);    RC_CHECK();
     2284        rc = CFGMR3InsertString(pLunL1,  "Driver",          pszDriver); RC_CHECK();
     2285
     2286        rc = CFGMR3InsertString(pLunL2, "AudioDriver", pszDriver);      RC_CHECK();
     2287
     2288    } while (0);
     2289
     2290    if (RT_SUCCESS(rc))
     2291        rc = ichac97Attach(pThis->pDevInsR3, pDrv->uLUN, 0 /* fFlags */);
     2292
     2293    LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, pDrv->uLUN, pszDriver, rc));
     2294
     2295#undef RC_CHECK
     2296
     2297    return rc;
     2298}
    22492299
    22502300/**
     
    23732423    {
    23742424        LogFunc(("Trying to attach driver for LUN #%RU8 ...\n", uLUN));
    2375         rc = ichac97Attach(pDevIns, uLUN, PDM_TACH_FLAGS_NOT_HOT_PLUG);
     2425        rc = ichac97Attach(pDevIns, uLUN, 0 /* fFlags */);
    23762426        if (RT_FAILURE(rc))
    23772427        {
     
    24502500            if (cFailed == 3)
    24512501            {
    2452                 LogRel(("AC97: Falling back to NULL driver (no sound audible)\n"));
     2502                LogRel(("AC97: Falling back to NULL backend (no sound audible)\n"));
    24532503
    24542504                ichac97Reset(pDevIns);
    2455 
    2456                 /* Was not able initialize *any* stream.
    2457                  * Select the NULL audio driver instead. */
    2458                 pCon->pfnInitNull(pCon);
     2505                ichac97Reattach(pThis, pCfg, pDrv, "NullAudio");
    24592506
    24602507                PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
     
    26062653    NULL,
    26072654    /* pfnAttach */
    2608     NULL,
     2655    ichac97Attach,
    26092656    /* pfnDetach */
    2610     NULL,
     2657    ichac97Detach,
    26112658    /* pfnQueryInterface. */
    26122659    NULL,
  • trunk/src/VBox/Devices/Audio/DevIchHda.cpp

    r59343 r59348  
    658658    /** LUN to which this driver has been assigned. */
    659659    uint8_t                            uLUN;
    660     /** Audio connector interface to the underlying
    661      *  host backend. */
     660    /** Pointer to attached driver base interface. */
     661    R3PTRTYPE(PPDMIBASE)               pDrvBase;
     662    /** Audio connector interface to the underlying host backend. */
    662663    R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pConnector;
    663664    /** Stream for line input. */
     
    684685    /** Padding for alignment. */
    685686    uint32_t                           u32Padding;
    686     /** Pointer to the attached audio driver. */
    687     R3PTRTYPE(PPDMIBASE)               pDrvBase;
    688687    /** The base interface for LUN\#0. */
    689688    PDMIBASE                           IBase;
     
    43234322    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    43244323
    4325     AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
    4326                     ("HDA device does not support hotplugging\n"),
    4327                     VERR_INVALID_PARAMETER);
    4328 
    43294324    /*
    43304325     * Attach driver.
     
    43324327    char *pszDesc = NULL;
    43334328    if (RTStrAPrintf(&pszDesc, "Audio driver port (HDA) for LUN#%u", uLUN) <= 0)
    4334         AssertMsgReturn(pszDesc,
    4335                         ("Not enough memory for HDA driver port description of LUN #%u\n", uLUN),
    4336                         VERR_NO_MEMORY);
    4337 
     4329        AssertReleaseMsgReturn(pszDesc,
     4330                               ("Not enough memory for HDA driver port description of LUN #%u\n", uLUN),
     4331                               VERR_NO_MEMORY);
     4332
     4333    PPDMIBASE pDrvBase;
    43384334    int rc = PDMDevHlpDriverAttach(pDevIns, uLUN,
    4339                                    &pThis->IBase, &pThis->pDrvBase, pszDesc);
     4335                                   &pThis->IBase, &pDrvBase, pszDesc);
    43404336    if (RT_SUCCESS(rc))
    43414337    {
     
    43434339        if (pDrv)
    43444340        {
    4345             pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
     4341            pDrv->pDrvBase   = pDrvBase;
     4342            pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR);
    43464343            AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN#%u has no host audio interface, rc=%Rrc\n", uLUN, rc));
    43474344            pDrv->pHDAState  = pThis;
     
    43634360            rc = VERR_NO_MEMORY;
    43644361    }
    4365     else if (   rc == VERR_PDM_NO_ATTACHED_DRIVER
    4366              || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME)
     4362    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
    43674363    {
    43684364        LogFunc(("No attached driver for LUN #%u\n", uLUN));
     
    43724368                        uLUN, pszDesc, rc));
    43734369
    4374     RTStrFree(pszDesc);
     4370    if (RT_FAILURE(rc))
     4371    {
     4372        /* Only free this string on failure;
     4373         * must remain valid for the live of the driver instance. */
     4374        RTStrFree(pszDesc);
     4375    }
    43754376
    43764377    LogFunc(("uLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
     
    43784379}
    43794380
    4380 static DECLCALLBACK(void) hdaDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
    4381 {
    4382     NOREF(pDevIns); NOREF(iLUN); NOREF(fFlags);
    4383 
    4384     LogFlowFuncEnter();
     4381static DECLCALLBACK(void) hdaDetach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
     4382{
     4383    LogFunc(("iLUN=%u, fFlags=0x%x\n", uLUN, fFlags));
     4384}
     4385
     4386static int hdaReattach(PHDASTATE pThis, PCFGMNODE pCfg, PHDADRIVER pDrv, const char *pszDriver)
     4387{
     4388    AssertPtrReturn(pThis,     VERR_INVALID_POINTER);
     4389    AssertPtrReturn(pCfg,      VERR_INVALID_POINTER);
     4390    AssertPtrReturn(pDrv,      VERR_INVALID_POINTER);
     4391    AssertPtrReturn(pszDriver, VERR_INVALID_POINTER);
     4392
     4393    PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);
     4394    PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
     4395    PCFGMNODE pDev0 = CFGMR3GetChild(pRoot, "Devices/hda/0/");
     4396
     4397    /* Remove LUN branch. */
     4398    CFGMR3RemoveNode(CFGMR3GetChildF(pDev0, "LUN#%u/", pDrv->uLUN));
     4399
     4400    int rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */);
     4401    if (RT_FAILURE(rc))
     4402        return rc;
     4403
     4404#define RC_CHECK() if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; }
     4405
     4406    do
     4407    {
     4408        PCFGMNODE pLunL0;
     4409        rc = CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%u/", pDrv->uLUN);  RC_CHECK();
     4410        rc = CFGMR3InsertString(pLunL0, "Driver",       "AUDIO");       RC_CHECK();
     4411        rc = CFGMR3InsertNode(pLunL0,   "Config/",       NULL);         RC_CHECK();
     4412
     4413        PCFGMNODE pLunL1, pLunL2;
     4414        rc = CFGMR3InsertNode  (pLunL0, "AttachedDriver/", &pLunL1);    RC_CHECK();
     4415        rc = CFGMR3InsertNode  (pLunL1,  "Config/",        &pLunL2);    RC_CHECK();
     4416        rc = CFGMR3InsertString(pLunL1,  "Driver",          pszDriver); RC_CHECK();
     4417
     4418        rc = CFGMR3InsertString(pLunL2, "AudioDriver", pszDriver);      RC_CHECK();
     4419
     4420    } while (0);
     4421
     4422    if (RT_SUCCESS(rc))
     4423        rc = hdaAttach(pThis->pDevInsR3, pDrv->uLUN, 0 /* fFlags */);
     4424
     4425    LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, pDrv->uLUN, pszDriver, rc));
     4426
     4427#undef RC_CHECK
     4428
     4429    return rc;
    43854430}
    43864431
     
    43884433 * @interface_method_impl{PDMDEVREG,pfnConstruct}
    43894434 */
    4390 static DECLCALLBACK(int) hdaConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
     4435static DECLCALLBACK(int) hdaConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
    43914436{
    43924437    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
     
    43974442     * Validations.
    43984443     */
    4399     if (!CFGMR3AreValuesValid(pCfgHandle, "R0Enabled\0"
    4400                                           "RCEnabled\0"
    4401                                           "TimerHz\0"))
     4444    if (!CFGMR3AreValuesValid(pCfg, "R0Enabled\0"
     4445                                    "RCEnabled\0"
     4446                                    "TimerHz\0"))
    44024447        return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
    44034448                                N_ ("Invalid configuration for the Intel HDA device"));
    44044449
    4405     int rc = CFGMR3QueryBoolDef(pCfgHandle, "RCEnabled", &pThis->fRCEnabled, false);
     4450    int rc = CFGMR3QueryBoolDef(pCfg, "RCEnabled", &pThis->fRCEnabled, false);
    44064451    if (RT_FAILURE(rc))
    44074452        return PDMDEV_SET_ERROR(pDevIns, rc,
    44084453                                N_("HDA configuration error: failed to read RCEnabled as boolean"));
    4409     rc = CFGMR3QueryBoolDef(pCfgHandle, "R0Enabled", &pThis->fR0Enabled, false);
     4454    rc = CFGMR3QueryBoolDef(pCfg, "R0Enabled", &pThis->fR0Enabled, false);
    44104455    if (RT_FAILURE(rc))
    44114456        return PDMDEV_SET_ERROR(pDevIns, rc,
     
    44134458#ifndef VBOX_WITH_AUDIO_CALLBACKS
    44144459    uint16_t uTimerHz;
    4415     rc = CFGMR3QueryU16Def(pCfgHandle, "TimerHz", &uTimerHz, 200 /* Hz */);
     4460    rc = CFGMR3QueryU16Def(pCfg, "TimerHz", &uTimerHz, 200 /* Hz */);
    44164461    if (RT_FAILURE(rc))
    44174462        return PDMDEV_SET_ERROR(pDevIns, rc,
     
    45404585    {
    45414586        LogFunc(("Trying to attach driver for LUN #%RU32 ...\n", uLUN));
    4542         rc = hdaAttach(pDevIns, uLUN, PDM_TACH_FLAGS_NOT_HOT_PLUG);
     4587        rc = hdaAttach(pDevIns, uLUN, 0 /* fFlags */);
    45434588        if (RT_FAILURE(rc))
    45444589        {
     
    46074652
    46084653        /* Construct the codec. */
    4609         rc = hdaCodecConstruct(pDevIns, pThis->pCodec, 0 /* Codec index */, pCfgHandle);
     4654        rc = hdaCodecConstruct(pDevIns, pThis->pCodec, 0 /* Codec index */, pCfg);
    46104655        if (RT_FAILURE(rc))
    46114656            AssertRCReturn(rc, rc);
     
    46294674        rc = hdaStreamCreate(&pThis->StrmStOut);
    46304675        AssertRC(rc);
     4676
     4677        PHDADRIVER pDrv;
     4678        RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
     4679        {
     4680            /*
     4681             * Only primary drivers are critical for the VM to run. Everything else
     4682             * might not worth showing an own error message box in the GUI.
     4683             */
     4684            if (!(pDrv->Flags & PDMAUDIODRVFLAG_PRIMARY))
     4685                continue;
     4686
     4687            PPDMIAUDIOCONNECTOR pCon = pDrv->pConnector;
     4688            AssertPtr(pCon);
     4689
     4690            uint8_t cFailed = 0;
     4691            if (!pCon->pfnIsValidIn (pCon, pDrv->LineIn.pStrmIn))
     4692                cFailed++;
     4693#ifdef VBOX_WITH_HDA_MIC_IN
     4694            if (!pCon->pfnIsValidIn (pCon, pDrv->MicIn.pStrmIn))
     4695                cFailed++;
     4696#endif
     4697            if (!pCon->pfnIsValidOut(pCon, pDrv->Out.pStrmOut))
     4698                cFailed++;
     4699
     4700#ifdef VBOX_WITH_HDA_MIC_IN
     4701            if (cFailed == 3)
     4702#else
     4703            if (cFailed == 2)
     4704#endif
     4705            {
     4706                LogRel(("HDA: Falling back to NULL backend (no sound audible)\n"));
     4707
     4708                hdaReset(pDevIns);
     4709                hdaReattach(pThis, pCfg, pDrv, "NullAudio");
     4710
     4711                PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
     4712                    N_("No audio devices could be opened. Selecting the NULL audio backend "
     4713                       "with the consequence that no sound is audible"));
     4714            }
     4715            else if (cFailed)
     4716            {
     4717                if (!pDrv->pConnector->pfnIsValidIn (pDrv->pConnector, pDrv->LineIn.pStrmIn))
     4718                    LogRel(("HDA: WARNING: Unable to open PCM line input for LUN #%RU32!\n",       pDrv->uLUN));
     4719#ifdef VBOX_WITH_HDA_MIC_IN
     4720                if (!pDrv->pConnector->pfnIsValidIn (pDrv->pConnector, pDrv->MicIn.pStrmIn))
     4721                    LogRel(("HDA: WARNING: Unable to open PCM microphone input for LUN #%RU32!\n", pDrv->uLUN));
     4722#endif
     4723                if (!pDrv->pConnector->pfnIsValidOut(pDrv->pConnector, pDrv->Out.pStrmOut))
     4724                    LogRel(("HDA: WARNING: Unable to open PCM output for LUN #%RU32!\n",           pDrv->uLUN));
     4725
     4726                char   szMissingStreams[255];
     4727                size_t len = 0;
     4728                if (!pCon->pfnIsValidIn (pCon, pDrv->LineIn.pStrmIn))
     4729                    len = RTStrPrintf(szMissingStreams,
     4730                                      sizeof(szMissingStreams), "PCM Input");
     4731#ifdef VBOX_WITH_HDA_MIC_IN
     4732                if (!pCon->pfnIsValidIn (pCon, pDrv->MicIn.pStrmIn))
     4733                    len += RTStrPrintf(szMissingStreams + len,
     4734                                       sizeof(szMissingStreams) - len, len ? ", PCM Microphone" : "PCM Microphone");
     4735#endif
     4736                if (!pCon->pfnIsValidOut(pCon, pDrv->Out.pStrmOut))
     4737                    len += RTStrPrintf(szMissingStreams + len,
     4738                                       sizeof(szMissingStreams) - len, len ? ", PCM Output" : "PCM Output");
     4739
     4740                PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
     4741                    N_("Some HDA audio streams (%s) could not be opened. Guest applications generating audio "
     4742                    "output or depending on audio input may hang. Make sure your host audio device "
     4743                    "is working properly. Check the logfile for error messages of the audio "
     4744                    "subsystem"), szMissingStreams);
     4745            }
     4746        }
    46314747    }
    46324748
     
    48194935    NULL,
    48204936    /* pfnAttach */
    4821     NULL,
     4937    hdaAttach,
    48224938    /* pfnDetach */
    4823     NULL,
     4939    hdaDetach,
    48244940    /* pfnQueryInterface. */
    48254941    NULL,
  • trunk/src/VBox/Devices/Audio/DevSB16.cpp

    r59275 r59348  
    9898    uint8_t                            uLUN;
    9999    uint8_t                            Padding[5];
    100     /** Audio connector interface to the underlying
    101      *  host backend. */
     100    /** Pointer to attached driver base interface. */
     101    R3PTRTYPE(PPDMIBASE)               pDrvBase;
     102    /** Audio connector interface to the underlying host backend. */
    102103    R3PTRTYPE(PPDMIAUDIOCONNECTOR)     pConnector;
    103104    /** Stream for output. */
     
    109110#ifdef VBOX
    110111    /** Pointer to the device instance. */
    111     PPDMDEVINSR3        pDevIns;
     112    PPDMDEVINSR3        pDevInsR3;
    112113    /** Pointer to the connector of the attached audio driver. */
    113114    PPDMIAUDIOCONNECTOR pDrv;
     
    179180    uint64_t                       uTimerTSIO;
    180181#endif
    181     PTMTIMER  pTimerIRQ;
    182     PPDMIBASE pDrvBase;
    183     /** LUN\#0: Base interface. */
    184     PDMIBASE  IBase;
     182    PTMTIMER                       pTimerIRQ;
     183    /** The base interface for LUN\#0. */
     184    PDMIBASE                       IBase;
    185185
    186186    /* mixer state */
     
    207207    PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE);
    208208
    209     AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG,
    210                     ("AC'97 device does not support hotplugging\n"),
    211                     VERR_INVALID_PARAMETER);
    212 
    213209    /*
    214210     * Attach driver.
     
    216212    char *pszDesc = NULL;
    217213    if (RTStrAPrintf(&pszDesc, "Audio driver port (SB16) for LUN #%u", uLUN) <= 0)
    218         AssertMsgReturn(pszDesc,
    219                         ("Not enough memory for SB16 driver port description of LUN #%u\n", uLUN),
    220                         VERR_NO_MEMORY);
    221 
     214        AssertReleaseMsgReturn(pszDesc,
     215                               ("Not enough memory for SB16 driver port description of LUN #%u\n", uLUN),
     216                               VERR_NO_MEMORY);
     217
     218    PPDMIBASE pDrvBase;
    222219    int rc = PDMDevHlpDriverAttach(pDevIns, uLUN,
    223                                    &pThis->IBase, &pThis->pDrvBase, pszDesc);
     220                                   &pThis->IBase, &pDrvBase, pszDesc);
    224221    if (RT_SUCCESS(rc))
    225222    {
     
    227224        if (pDrv)
    228225        {
    229             pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR);
    230             AssertMsg(pDrv->pConnector != NULL,
    231                       ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n",
    232                       uLUN, rc));
     226            pDrv->pDrvBase   = pDrvBase;
     227            pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR);
     228            AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n", uLUN, rc));
    233229            pDrv->pSB16State = pThis;
    234             pDrv->uLUN = uLUN;
     230            pDrv->uLUN       = uLUN;
    235231
    236232            /*
     
    257253                        uLUN, pszDesc, rc));
    258254
    259     RTStrFree(pszDesc);
     255    if (RT_FAILURE(rc))
     256    {
     257        /* Only free this string on failure;
     258         * must remain valid for the live of the driver instance. */
     259        RTStrFree(pszDesc);
     260    }
    260261
    261262    LogFunc(("iLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
     263    return rc;
     264}
     265
     266static void sb16Detach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
     267{
     268    LogFunc(("iLUN=%u, fFlags=0x%x\n", uLUN, fFlags));
     269}
     270
     271static int sb16Reattach(PSB16STATE pThis, PCFGMNODE pCfg, PSB16DRIVER pDrv, const char *pszDriver)
     272{
     273    AssertPtrReturn(pThis,     VERR_INVALID_POINTER);
     274    AssertPtrReturn(pCfg,      VERR_INVALID_POINTER);
     275    AssertPtrReturn(pDrv,      VERR_INVALID_POINTER);
     276    AssertPtrReturn(pszDriver, VERR_INVALID_POINTER);
     277
     278    PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);
     279    PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
     280    PCFGMNODE pDev0 = CFGMR3GetChild(pRoot, "Devices/SB16/0/");
     281
     282    /* Remove LUN branch. */
     283    CFGMR3RemoveNode(CFGMR3GetChildF(pDev0, "LUN#%u/", pDrv->uLUN));
     284
     285    int rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */);
     286    if (RT_FAILURE(rc))
     287        return rc;
     288
     289#define RC_CHECK() if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; }
     290
     291    do
     292    {
     293        PCFGMNODE pLunL0;
     294        rc = CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%u/", pDrv->uLUN);  RC_CHECK();
     295        rc = CFGMR3InsertString(pLunL0, "Driver",       "AUDIO");       RC_CHECK();
     296        rc = CFGMR3InsertNode(pLunL0,   "Config/",       NULL);         RC_CHECK();
     297
     298        PCFGMNODE pLunL1, pLunL2;
     299        rc = CFGMR3InsertNode  (pLunL0, "AttachedDriver/", &pLunL1);    RC_CHECK();
     300        rc = CFGMR3InsertNode  (pLunL1,  "Config/",        &pLunL2);    RC_CHECK();
     301        rc = CFGMR3InsertString(pLunL1,  "Driver",          pszDriver); RC_CHECK();
     302
     303        rc = CFGMR3InsertString(pLunL2, "AudioDriver", pszDriver);      RC_CHECK();
     304
     305    } while (0);
     306
     307    if (RT_SUCCESS(rc))
     308        rc = sb16Attach(pThis->pDevInsR3, pDrv->uLUN, 0 /* fFlags */);
     309
     310    LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, pDrv->uLUN, pszDriver, rc));
     311
     312#undef RC_CHECK
     313
    262314    return rc;
    263315}
     
    336388    if (hold)
    337389    {
    338         PDMDevHlpDMASetDREQ (pThis->pDevIns, dma, 1);
    339         PDMDevHlpDMASchedule (pThis->pDevIns);
     390        PDMDevHlpDMASetDREQ (pThis->pDevInsR3, dma, 1);
     391        PDMDevHlpDMASchedule (pThis->pDevInsR3);
    340392        RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
    341393            pDrv->pConnector->pfnEnableOut(pDrv->pConnector,
     
    344396    else
    345397    {
    346         PDMDevHlpDMASetDREQ (pThis->pDevIns, dma, 0);
     398        PDMDevHlpDMASetDREQ (pThis->pDevInsR3, dma, 0);
    347399        RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
    348400            pDrv->pConnector->pfnEnableOut(pDrv->pConnector,
     
    355407    PSB16STATE pThis = (PSB16STATE)pvThis;
    356408    pThis->can_write = 1;
    357     PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
     409    PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 1);
    358410}
    359411
     
    747799                dsp_out_data(pThis, 0xaa);
    748800                pThis->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
    749                 PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
     801                PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 1);
    750802                break;
    751803
     
    920972            ticks = (bytes * TMTimerGetFreq(pThis->pTimerIRQ)) / freq;
    921973            if (ticks < TMTimerGetFreq(pThis->pTimerIRQ) / 1024)
    922                 PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
     974                PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 1);
    923975            else
    924976                TMTimerSet(pThis->pTimerIRQ, TMTimerGet(pThis->pTimerIRQ) + ticks);
     
    10241076static void sb16Reset(PSB16STATE pThis)
    10251077{
    1026     PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
     1078    PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 0);
    10271079    if (pThis->dma_auto)
    10281080    {
    1029         PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
    1030         PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
     1081        PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 1);
     1082        PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 0);
    10311083    }
    10321084
     
    10671119                        {
    10681120                            pThis->highspeed = 0;
    1069                             PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
     1121                            PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 0);
    10701122                            sb16Control(pThis, 0);
    10711123                        }
     
    11911243                ack = 1;
    11921244                pThis->mixer_regs[0x82] &= ~1;
    1193                 PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
     1245                PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 0);
    11941246            }
    11951247            break;
     
    12011253                ack = 1;
    12021254                pThis->mixer_regs[0x82] &= ~2;
    1203                PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
     1255               PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 0);
    12041256            }
    12051257            break;
     
    15291581            cbToRead = sizeof(tmpbuf);
    15301582
    1531         int rc = PDMDevHlpDMAReadMemory(pThis->pDevIns, nchan, tmpbuf, dma_pos, cbToRead, &cbRead);
     1583        int rc = PDMDevHlpDMAReadMemory(pThis->pDevInsR3, nchan, tmpbuf, dma_pos, cbToRead, &cbRead);
    15321584        AssertMsgRC(rc, ("DMAReadMemory -> %Rrc\n", rc));
    15331585
     
    16221674    {
    16231675        pThis->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
    1624         PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1);
     1676        PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 1);
    16251677        if (0 == pThis->dma_auto)
    16261678        {
     
    17301782
    17311783        /* New space available, see if we can transfer more. */
    1732         PDMDevHlpDMASchedule(pThis->pDevIns);
     1784        PDMDevHlpDMASchedule(pThis->pDevInsR3);
    17331785    }
    17341786
     
    19622014    PSB16DRIVER pDrv;
    19632015    uint8_t uLUN = 0;
    1964     char *pszDesc;
     2016
    19652017    RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
    19662018    {
     2019        char *pszDesc;
    19672020        if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] sb16.po", uLUN) <= 0)
    19682021        {
     
    19932046        uLUN++;
    19942047    }
     2048
    19952049    /* Ensure volume gets propagated. */
    19962050    AudioMixerInvalidate(pThis->pMixer);
     
    20092063     * sure there's no interrupt or DMA activity.
    20102064     */
    2011     PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0);
     2065    PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 0);
    20122066
    20132067    pThis->mixer_regs[0x82] = 0;
     
    20672121}
    20682122
    2069 static DECLCALLBACK(int) sb16Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
     2123static DECLCALLBACK(int) sb16Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
    20702124{
    20712125    PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE);
     
    20762130    Assert(iInstance == 0);
    20772131    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    2078     if (!CFGMR3AreValuesValid(pCfgHandle,
     2132    if (!CFGMR3AreValuesValid(pCfg,
    20792133                              "IRQ\0"
    20802134                              "DMA\0"
     
    20892143     * Read config data.
    20902144     */
    2091     int rc = CFGMR3QuerySIntDef(pCfgHandle, "IRQ", &pThis->irq, 5);
     2145    int rc = CFGMR3QuerySIntDef(pCfg, "IRQ", &pThis->irq, 5);
    20922146    if (RT_FAILURE(rc))
    20932147        return PDMDEV_SET_ERROR(pDevIns, rc,
     
    20952149    pThis->irqCfg  = pThis->irq;
    20962150
    2097     rc = CFGMR3QuerySIntDef(pCfgHandle, "DMA", &pThis->dma, 1);
     2151    rc = CFGMR3QuerySIntDef(pCfg, "DMA", &pThis->dma, 1);
    20982152    if (RT_FAILURE(rc))
    20992153        return PDMDEV_SET_ERROR(pDevIns, rc,
     
    21012155    pThis->dmaCfg  = pThis->dma;
    21022156
    2103     rc = CFGMR3QuerySIntDef(pCfgHandle, "DMA16", &pThis->hdma, 5);
     2157    rc = CFGMR3QuerySIntDef(pCfg, "DMA16", &pThis->hdma, 5);
    21042158    if (RT_FAILURE(rc))
    21052159        return PDMDEV_SET_ERROR(pDevIns, rc,
     
    21082162
    21092163    RTIOPORT Port;
    2110     rc = CFGMR3QueryPortDef(pCfgHandle, "Port", &Port, 0x220);
     2164    rc = CFGMR3QueryPortDef(pCfg, "Port", &Port, 0x220);
    21112165    if (RT_FAILURE(rc))
    21122166        return PDMDEV_SET_ERROR(pDevIns, rc,
     
    21162170
    21172171    uint16_t u16Version;
    2118     rc = CFGMR3QueryU16Def(pCfgHandle, "Version", &u16Version, 0x0405);
     2172    rc = CFGMR3QueryU16Def(pCfg, "Version", &u16Version, 0x0405);
    21192173    if (RT_FAILURE(rc))
    21202174        return PDMDEV_SET_ERROR(pDevIns, rc,
     
    21232177#ifndef VBOX_WITH_AUDIO_CALLBACKS
    21242178    uint16_t uTimerHz;
    2125     rc = CFGMR3QueryU16Def(pCfgHandle, "TimerHz", &uTimerHz, 200 /* Hz */);
     2179    rc = CFGMR3QueryU16Def(pCfg, "TimerHz", &uTimerHz, 200 /* Hz */);
    21262180    if (RT_FAILURE(rc))
    21272181        return PDMDEV_SET_ERROR(pDevIns, rc,
     
    21352189     * Init instance data.
    21362190     */
    2137     pThis->pDevIns                 = pDevIns;
     2191    pThis->pDevInsR3               = pDevIns;
    21382192    pThis->IBase.pfnQueryInterface = sb16QueryInterface;
    21392193    pThis->cmd                     = -1;
     
    21872241    {
    21882242        LogFunc(("Trying to attach driver for LUN #%RU8 ...\n", uLUN));
    2189         rc = sb16Attach(pDevIns, uLUN, PDM_TACH_FLAGS_NOT_HOT_PLUG);
     2243        rc = sb16Attach(pDevIns, uLUN, 0 /* fFlags */);
    21902244        if (RT_FAILURE(rc))
    21912245        {
     
    22012255
    22022256    sb16ResetLegacy(pThis);
     2257
     2258    PSB16DRIVER pDrv;
     2259    RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
     2260    {
     2261        /*
     2262         * Only primary drivers are critical for the VM to run. Everything else
     2263         * might not worth showing an own error message box in the GUI.
     2264         */
     2265        if (!(pDrv->Flags & PDMAUDIODRVFLAG_PRIMARY))
     2266            continue;
     2267
     2268        PPDMIAUDIOCONNECTOR pCon = pDrv->pConnector;
     2269        AssertPtr(pCon);
     2270
     2271        uint8_t cFailed = 0;
     2272        if (!pCon->pfnIsValidOut(pCon, pDrv->Out.pStrmOut))
     2273            cFailed++;
     2274
     2275        if (cFailed)
     2276        {
     2277            LogRel(("SB16: Falling back to NULL backend (no sound audible)\n"));
     2278
     2279            sb16ResetLegacy(pThis);
     2280            sb16Reattach(pThis, pCfg, pDrv, "NullAudio");
     2281
     2282            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
     2283                N_("No audio devices could be opened. Selecting the NULL audio backend "
     2284                   "with the consequence that no sound is audible"));
     2285        }
     2286    }
    22032287
    22042288#ifndef VBOX_WITH_AUDIO_CALLBACKS
     
    22222306    if (RT_SUCCESS(rc))
    22232307    {
     2308        /** @todo Merge this callback registration with the validation block above once
     2309         *  this becomes the standard. */
    22242310        PSB16DRIVER pDrv;
    22252311        RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
     
    22912377    NULL,
    22922378    /* pfnAttach */
    2293     NULL,
     2379    sb16Attach,
    22942380    /* pfnDetach */
    2295     NULL,
     2381    sb16Detach,
    22962382    /* pfnQueryInterface */
    22972383    NULL,
  • trunk/src/VBox/Devices/Audio/DrvAudio.cpp

    r59275 r59348  
    17281728}
    17291729
    1730 static DECLCALLBACK(int) drvAudioInitNull(PPDMIAUDIOCONNECTOR pInterface)
    1731 {
    1732     PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
    1733     NOREF(pThis);
    1734 
    1735     LogRel(("Audio: Using NULL driver; no sound will be audible\n"));
    1736 
    1737     /* Nothing to do here yet. */
    1738     return VINF_SUCCESS;
    1739 }
    1740 
    17411730static DECLCALLBACK(int) drvAudioRead(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOGSTSTRMIN pGstStrmIn,
    17421731                                      void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     
    21692158    pThis->IAudioConnector.pfnIsValidIn              = drvAudioIsValidIn;
    21702159    pThis->IAudioConnector.pfnIsValidOut             = drvAudioIsValidOut;
    2171     pThis->IAudioConnector.pfnInitNull               = drvAudioInitNull;
    21722160    pThis->IAudioConnector.pfnEnableOut              = drvAudioEnableOut;
    21732161    pThis->IAudioConnector.pfnEnableIn               = drvAudioEnableIn;
Note: See TracChangeset for help on using the changeset viewer.

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