VirtualBox

Changeset 68908 in vbox


Ignore:
Timestamp:
Sep 28, 2017 1:26:02 PM (7 years ago)
Author:
vboxsync
Message:

Audio/HDA: Implemented support for attaching + detaching drivers on runtime.

File:
1 edited

Legend:

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

    r68901 r68908  
    21542154
    21552155/**
    2156  * Adds audio streams of all attached LUNs to a given HDA audio mixer sink.
     2156 * Adds a driver stream to a specific mixer sink.
    21572157 *
    21582158 * @returns IPRT status code.
     
    21602160 * @param   pSink               HDA mixer sink to add audio streams to.
    21612161 * @param   pCfg                Audio stream configuration to use for the audio streams to add.
    2162  */
    2163 static DECLCALLBACK(int) hdaMixerAddStream(PHDASTATE pThis, PHDAMIXERSINK pSink, PPDMAUDIOSTREAMCFG pCfg)
    2164 {
    2165     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    2166     AssertPtrReturn(pSink, VERR_INVALID_POINTER);
    2167     AssertPtrReturn(pCfg,  VERR_INVALID_POINTER);
    2168 
    2169     LogFunc(("Sink=%s, Stream=%s\n", pSink->pMixSink->pszName, pCfg->szName));
     2162 * @param   pDrv                Driver stream to add.
     2163 */
     2164static int hdaMixerAddDrvStream(PHDASTATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv)
     2165{
     2166    AssertPtrReturn(pThis,    VERR_INVALID_POINTER);
     2167    AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
     2168    AssertPtrReturn(pCfg,     VERR_INVALID_POINTER);
     2169
     2170    LogFunc(("Sink=%s, Stream=%s\n", pMixSink->pszName, pCfg->szName));
     2171
     2172    PPDMAUDIOSTREAMCFG pStreamCfg = DrvAudioHlpStreamCfgDup(pCfg);
     2173    if (!pStreamCfg)
     2174        return VERR_NO_MEMORY;
     2175
     2176    if (!RTStrPrintf(pStreamCfg->szName, sizeof(pStreamCfg->szName), "%s", pCfg->szName))
     2177    {
     2178        RTMemFree(pStreamCfg);
     2179        return VERR_BUFFER_OVERFLOW;
     2180    }
     2181
     2182    LogFunc(("[LUN#%RU8] %s\n", pDrv->uLUN, pStreamCfg->szName));
     2183
     2184    int rc = VINF_SUCCESS;
     2185
     2186    PHDADRIVERSTREAM pDrvStream = NULL;
     2187
     2188    if (pStreamCfg->enmDir == PDMAUDIODIR_IN)
     2189    {
     2190        LogFunc(("enmRecSource=%d\n", pStreamCfg->DestSource.Source));
     2191
     2192        switch (pStreamCfg->DestSource.Source)
     2193        {
     2194            case PDMAUDIORECSOURCE_LINE:
     2195                pDrvStream = &pDrv->LineIn;
     2196                break;
     2197#ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     2198            case PDMAUDIORECSOURCE_MIC:
     2199                pDrvStream = &pDrv->MicIn;
     2200                break;
     2201#endif
     2202            default:
     2203                rc = VERR_NOT_SUPPORTED;
     2204                break;
     2205        }
     2206    }
     2207    else if (pStreamCfg->enmDir == PDMAUDIODIR_OUT)
     2208    {
     2209        LogFunc(("enmPlaybackDest=%d\n", pStreamCfg->DestSource.Dest));
     2210
     2211        switch (pStreamCfg->DestSource.Dest)
     2212        {
     2213            case PDMAUDIOPLAYBACKDEST_FRONT:
     2214                pDrvStream = &pDrv->Front;
     2215                break;
     2216#ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
     2217            case PDMAUDIOPLAYBACKDEST_CENTER_LFE:
     2218                pDrvStream = &pDrv->CenterLFE;
     2219                break;
     2220            case PDMAUDIOPLAYBACKDEST_REAR:
     2221                pDrvStream = &pDrv->Rear;
     2222                break;
     2223#endif
     2224            default:
     2225                rc = VERR_NOT_SUPPORTED;
     2226                break;
     2227        }
     2228    }
     2229    else
     2230        rc = VERR_NOT_SUPPORTED;
     2231
     2232    if (RT_SUCCESS(rc))
     2233    {
     2234        AssertPtr(pDrvStream);
     2235        AssertMsg(pDrvStream->pMixStrm == NULL, ("[LUN#%RU8] Driver stream already present when it must not\n", pDrv->uLUN));
     2236
     2237        PAUDMIXSTREAM pMixStrm;
     2238        rc = AudioMixerSinkCreateStream(pMixSink, pDrv->pConnector, pStreamCfg, 0 /* fFlags */, &pMixStrm);
     2239        if (RT_SUCCESS(rc))
     2240        {
     2241            rc = AudioMixerSinkAddStream(pMixSink, pMixStrm);
     2242            LogFlowFunc(("LUN#%RU8: Added \"%s\" to sink, rc=%Rrc\n", pDrv->uLUN, pStreamCfg->szName, rc));
     2243        }
     2244
     2245        if (RT_SUCCESS(rc))
     2246            pDrvStream->pMixStrm = pMixStrm;
     2247    }
     2248
     2249    if (pStreamCfg)
     2250    {
     2251        RTMemFree(pStreamCfg);
     2252        pStreamCfg = NULL;
     2253    }
     2254
     2255    LogFlowFuncLeaveRC(rc);
     2256    return rc;
     2257}
     2258
     2259/**
     2260 * Adds all current driver streams to a specific mixer sink.
     2261 *
     2262 * @returns IPRT status code.
     2263 * @param   pThis               HDA state.
     2264 * @param   pMixSink            Mixer sink to add stream to.
     2265 * @param   pCfg                Audio stream configuration to use for the audio streams to add.
     2266 */
     2267static int hdaMixerAddDrvStreams(PHDASTATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg)
     2268{
     2269    AssertPtrReturn(pThis,    VERR_INVALID_POINTER);
     2270    AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
     2271    AssertPtrReturn(pCfg,     VERR_INVALID_POINTER);
     2272
     2273    LogFunc(("Sink=%s, Stream=%s\n", pMixSink->pszName, pCfg->szName));
    21702274
    21712275    if (!DrvAudioHlpStreamCfgIsValid(pCfg))
    2172     {
    2173         LogRel(("HDA: Invalid stream configuration used for sink #%RU8: %RU8 bit, %RU8 channel(s) @ %RU32Hz\n",
    2174                 pSink->uSD, pCfg->Props.cBits, pCfg->Props.cChannels, pCfg->Props.uHz));
    2175 
    2176         AssertFailed(); /* Should not happen. */
    21772276        return VERR_INVALID_PARAMETER;
    2178     }
    2179 
    2180     int rc = AudioMixerSinkSetFormat(pSink->pMixSink, &pCfg->Props);
     2277
     2278    int rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props);
    21812279    if (RT_FAILURE(rc))
    21822280        return rc;
     
    21852283    RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
    21862284    {
    2187         int rc2 = VINF_SUCCESS;
    2188         PHDADRIVERSTREAM pDrvStream = NULL;
    2189 
    2190         PPDMAUDIOSTREAMCFG pStreamCfg = DrvAudioHlpStreamCfgDup(pCfg);
    2191         if (!pStreamCfg)
    2192         {
    2193             rc = VERR_NO_MEMORY;
    2194             break;
    2195         }
    2196 
    2197         RTStrPrintf(pStreamCfg->szName, RT_ELEMENTS(pStreamCfg->szName), "%s", pCfg->szName);
    2198 
    2199         if (pStreamCfg->enmDir == PDMAUDIODIR_IN)
    2200         {
    2201             LogFunc(("enmRecSource=%d\n", pStreamCfg->DestSource.Source));
    2202 
    2203             switch (pStreamCfg->DestSource.Source)
    2204             {
    2205                 case PDMAUDIORECSOURCE_LINE:
    2206                     pDrvStream = &pDrv->LineIn;
    2207                     break;
    2208 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    2209                 case PDMAUDIORECSOURCE_MIC:
    2210                     pDrvStream = &pDrv->MicIn;
    2211                     break;
    2212 #endif
    2213                 default:
    2214                     rc2 = VERR_NOT_SUPPORTED;
    2215                     break;
    2216             }
    2217         }
    2218         else if (pStreamCfg->enmDir == PDMAUDIODIR_OUT)
    2219         {
    2220             LogFunc(("enmPlaybackDest=%d\n", pStreamCfg->DestSource.Dest));
    2221 
    2222             switch (pStreamCfg->DestSource.Dest)
    2223             {
    2224                 case PDMAUDIOPLAYBACKDEST_FRONT:
    2225                     pDrvStream = &pDrv->Front;
    2226                     break;
    2227 #ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
    2228                 case PDMAUDIOPLAYBACKDEST_CENTER_LFE:
    2229                     pDrvStream = &pDrv->CenterLFE;
    2230                     break;
    2231                 case PDMAUDIOPLAYBACKDEST_REAR:
    2232                     pDrvStream = &pDrv->Rear;
    2233                     break;
    2234 #endif
    2235                 default:
    2236                     rc2 = VERR_NOT_SUPPORTED;
    2237                     break;
    2238             }
    2239         }
    2240         else
    2241             rc2 = VERR_NOT_SUPPORTED;
    2242 
    2243         if (RT_SUCCESS(rc2))
    2244         {
    2245             AssertPtr(pDrvStream);
    2246 
    2247             AudioMixerSinkRemoveStream(pSink->pMixSink, pDrvStream->pMixStrm);
    2248 
    2249             AudioMixerStreamDestroy(pDrvStream->pMixStrm);
    2250             pDrvStream->pMixStrm = NULL;
    2251 
    2252             PAUDMIXSTREAM pMixStrm;
    2253             rc2 = AudioMixerSinkCreateStream(pSink->pMixSink, pDrv->pConnector, pStreamCfg, 0 /* fFlags */, &pMixStrm);
    2254             if (RT_SUCCESS(rc2))
    2255             {
    2256                 rc2 = AudioMixerSinkAddStream(pSink->pMixSink, pMixStrm);
    2257                 LogFlowFunc(("LUN#%RU8: Added \"%s\" to sink, rc=%Rrc\n", pDrv->uLUN, pStreamCfg->szName , rc2));
    2258             }
    2259 
    2260             if (RT_SUCCESS(rc2))
    2261                 pDrvStream->pMixStrm = pMixStrm;
    2262 
    2263             /* If creating a stream fails, be forgiving and continue -- don't pass rc2 to rc here. */
    2264         }
    2265 
    2266         if (pStreamCfg)
    2267         {
    2268             RTMemFree(pStreamCfg);
    2269             pStreamCfg = NULL;
    2270         }
     2285        int rc2 = hdaMixerAddDrvStream(pThis, pMixSink, pCfg, pDrv);
     2286        if (RT_SUCCESS(rc))
     2287            rc = rc2;
    22712288    }
    22722289
     
    22952312    if (pSink)
    22962313    {
    2297         rc = hdaMixerAddStream(pThis, pSink, pCfg);
     2314        rc = hdaMixerAddDrvStreams(pThis, pSink->pMixSink, pCfg);
    22982315
    22992316        AssertPtr(pSink->pMixSink);
     
    44044421 *
    44054422 * @returns VBox status code.
    4406  * @param   pDevIns     The device instance.
    4407  * @param   pDrv        Driver to (re-)use for (re-)attaching to.
    4408  *                      If NULL is specified, a new driver will be created and appended
    4409  *                      to the driver list.
     4423 * @param   pThis       HDA state.
    44104424 * @param   uLUN        The logical unit which is being detached.
    44114425 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    4412  */
    4413 static int hdaAttachInternal(PPDMDEVINS pDevIns, PHDADRIVER pDrv, unsigned uLUN, uint32_t fFlags)
     4426 * @param   ppDrv       Attached driver instance on success. Optional.
     4427 */
     4428static int hdaAttachInternal(PHDASTATE pThis, unsigned uLUN, uint32_t fFlags, PHDADRIVER *ppDrv)
    44144429{
    44154430    RT_NOREF(fFlags);
    4416     PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    44174431
    44184432    /*
     
    44244438
    44254439    PPDMIBASE pDrvBase;
    4426     int rc = PDMDevHlpDriverAttach(pDevIns, uLUN,
     4440    int rc = PDMDevHlpDriverAttach(pThis->pDevInsR3, uLUN,
    44274441                                   &pThis->IBase, &pDrvBase, pszDesc);
    44284442    if (RT_SUCCESS(rc))
    44294443    {
    4430         if (pDrv == NULL)
    4431             pDrv = (PHDADRIVER)RTMemAllocZ(sizeof(HDADRIVER));
     4444        PHDADRIVER pDrv = (PHDADRIVER)RTMemAllocZ(sizeof(HDADRIVER));
    44324445        if (pDrv)
    44334446        {
     
    44534466                pDrv->fAttached = true;
    44544467            }
     4468
     4469            if (ppDrv)
     4470                *ppDrv = pDrv;
    44554471        }
    44564472        else
     
    44724488
    44734489/**
    4474  * Attach command.
     4490 * Detach command, internal version.
    44754491 *
    4476  * This is called to let the device attach to a driver for a specified LUN
    4477  * during runtime. This is not called during VM construction, the device
    4478  * constructor has to attach to all the available drivers.
     4492 * This is called to let the device detach from a driver for a specified LUN
     4493 * during runtime.
    44794494 *
    44804495 * @returns VBox status code.
    4481  * @param   pDevIns     The device instance.
    4482  * @param   uLUN        The logical unit which is being detached.
     4496 * @param   pThis       HDA state.
     4497 * @param   pDrv        Driver to detach device from.
    44834498 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    44844499 */
     4500static int hdaDetachInternal(PHDASTATE pThis, PHDADRIVER pDrv, uint32_t fFlags)
     4501{
     4502    RT_NOREF(fFlags);
     4503
     4504    AudioMixerSinkRemoveStream(pThis->SinkFront.pMixSink,     pDrv->Front.pMixStrm);
     4505    AudioMixerStreamDestroy(pDrv->Front.pMixStrm);
     4506    pDrv->Front.pMixStrm = NULL;
     4507
     4508#ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
     4509    AudioMixerSinkRemoveStream(pThis->SinkCenterLFE.pMixSink, pDrv->CenterLFE.pMixStrm);
     4510    AudioMixerStreamDestroy(pDrv->CenterLFE.pMixStrm);
     4511    pDrv->CenterLFE.pMixStrm = NULL;
     4512
     4513    AudioMixerSinkRemoveStream(pThis->SinkRear.pMixSink,      pDrv->Rear.pMixStrm);
     4514    AudioMixerStreamDestroy(pDrv->Rear.pMixStrm);
     4515    pDrv->Rear.pMixStrm = NULL;
     4516#endif
     4517
     4518    AudioMixerSinkRemoveStream(pThis->SinkLineIn.pMixSink,    pDrv->LineIn.pMixStrm);
     4519    AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm);
     4520    pDrv->LineIn.pMixStrm = NULL;
     4521
     4522#ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     4523    AudioMixerSinkRemoveStream(pThis->SinkMicIn.pMixSink,     pDrv->MicIn.pMixStrm);
     4524    AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm);
     4525    pDrv->MicIn.pMixStrm = NULL;
     4526#endif
     4527
     4528    RTListNodeRemove(&pDrv->Node);
     4529
     4530    LogFunc(("uLUN=%u, fFlags=0x%x\n", pDrv->uLUN, fFlags));
     4531    return VINF_SUCCESS;
     4532}
     4533
     4534/**
     4535 * @interface_method_impl{PDMDEVREG,pfnAttach}
     4536 */
    44854537static DECLCALLBACK(int) hdaAttach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
    44864538{
     
    44894541    DEVHDA_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE);
    44904542
    4491     int rc = hdaAttachInternal(pDevIns, NULL /* pDrv */, uLUN, fFlags);
     4543    PHDADRIVER pDrv;
     4544    int rc2 = hdaAttachInternal(pThis, uLUN, fFlags, &pDrv);
     4545    if (RT_SUCCESS(rc2))
     4546    {
     4547        PHDASTREAM pStream = hdaGetStreamFromSink(pThis, &pThis->SinkFront);
     4548        if (DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     4549            hdaMixerAddDrvStream(pThis, pThis->SinkFront.pMixSink,     &pStream->State.Cfg, pDrv);
     4550
     4551#ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
     4552        pStream = hdaGetStreamFromSink(pThis, &pThis->SinkCenterLFE);
     4553        if (DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     4554            hdaMixerAddDrvStream(pThis, pThis->SinkCenterLFE.pMixSink, &pStream->State.Cfg, pDrv);
     4555
     4556        pStream = hdaGetStreamFromSink(pThis, &pThis->SinkRear);
     4557        if (DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     4558            hdaMixerAddDrvStream(pThis, pThis->SinkRear.pMixSink,      &pStream->State.Cfg, pDrv);
     4559#endif
     4560        pStream = hdaGetStreamFromSink(pThis, &pThis->SinkLineIn);
     4561        if (DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     4562            hdaMixerAddDrvStream(pThis, pThis->SinkLineIn.pMixSink,    &pStream->State.Cfg, pDrv);
     4563
     4564#ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     4565        pStream = hdaGetStreamFromSink(pThis, &pThis->SinkMicIn);
     4566        if (DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     4567            hdaMixerAddDrvStream(pThis, pThis->SinkMicIn.pMixSink,     &pStream->State.Cfg, pDrv);
     4568#endif
     4569    }
    44924570
    44934571    DEVHDA_UNLOCK(pThis);
    44944572
    4495     return rc;
    4496 }
    4497 
     4573    return VINF_SUCCESS;
     4574}
     4575
     4576/**
     4577 * @interface_method_impl{PDMDEVREG,pfnDetach}
     4578 */
    44984579static DECLCALLBACK(void) hdaDetach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
    44994580{
    4500     RT_NOREF(pDevIns, uLUN, fFlags);
    4501     LogFunc(("iLUN=%u, fFlags=0x%x\n", uLUN, fFlags));
    4502 }
    4503 
    4504 /**
    4505  * Powers off the device.
    4506  *
    4507  * @param   pDevIns             Device instance to power off.
    4508  */
    4509 static DECLCALLBACK(void) hdaPowerOff(PPDMDEVINS pDevIns)
    4510 {
    45114581    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    45124582
    4513     DEVHDA_LOCK_RETURN_VOID(pThis);
    4514 
    4515     LogRel2(("HDA: Powering off ...\n"));
    4516 
    4517     /* Ditto goes for the codec, which in turn uses the mixer. */
    4518     hdaCodecPowerOff(pThis->pCodec);
    4519 
    4520     /**
    4521      * Note: Destroy the mixer while powering off and *not* in hdaDestruct,
    4522      *       giving the mixer the chance to release any references held to
    4523      *       PDM audio streams it maintains.
    4524      */
    4525     if (pThis->pMixer)
    4526     {
    4527         AudioMixerDestroy(pThis->pMixer);
    4528         pThis->pMixer = NULL;
     4583    LogFunc(("uLUN=%u, fFlags=0x%x\n", uLUN, fFlags));
     4584
     4585    DEVHDA_LOCK(pThis);
     4586
     4587    PHDADRIVER pDrv, pDrvNext;
     4588    RTListForEachSafe(&pThis->lstDrv, pDrv, pDrvNext, HDADRIVER, Node)
     4589    {
     4590        if (pDrv->uLUN == uLUN)
     4591        {
     4592            int rc2 = hdaDetachInternal(pThis, pDrv, fFlags);
     4593            if (RT_SUCCESS(rc2))
     4594            {
     4595                RTMemFree(pDrv);
     4596                pDrv = NULL;
     4597            }
     4598
     4599            break;
     4600        }
    45294601    }
    45304602
     
    45334605
    45344606/**
    4535  * Re-attaches a new driver to the device's driver chain.
     4607 * Re-attaches (replaces) a driver with a new driver.
    45364608 *
    45374609 * @returns VBox status code.
     
    45414613 *                      to the driver list.
    45424614 * @param   uLUN        The logical unit which is being re-detached.
    4543  * @param   pszDriver   Driver name.
    4544  */
    4545 static int hdaReattach(PHDASTATE pThis, PHDADRIVER pDrv, uint8_t uLUN, const char *pszDriver)
     4615 * @param   pszDriver   New driver name to attach.
     4616 */
     4617static int hdaReattachInternal(PHDASTATE pThis, PHDADRIVER pDrv, uint8_t uLUN, const char *pszDriver)
    45464618{
    45474619    AssertPtrReturn(pThis,     VERR_INVALID_POINTER);
    45484620    AssertPtrReturn(pszDriver, VERR_INVALID_POINTER);
     4621
     4622    int rc;
     4623
     4624    if (pDrv)
     4625    {
     4626        rc = hdaDetachInternal(pThis, pDrv, 0 /* fFlags */);
     4627        if (RT_SUCCESS(rc))
     4628            rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */);
     4629
     4630        if (RT_FAILURE(rc))
     4631            return rc;
     4632
     4633        pDrv = NULL;
     4634    }
    45494635
    45504636    PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);
     
    45554641    CFGMR3RemoveNode(CFGMR3GetChildF(pDev0, "LUN#%u/", uLUN));
    45564642
    4557     if (pDrv)
    4558     {
    4559         /* Re-use a driver instance => detach the driver before. */
    4560         int rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */);
    4561         if (RT_FAILURE(rc))
    4562             return rc;
    4563     }
    4564 
    45654643#define RC_CHECK() if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; }
    45664644
    4567     int rc = VINF_SUCCESS;
    45684645    do
    45694646    {
     
    45834660
    45844661    if (RT_SUCCESS(rc))
    4585         rc = hdaAttachInternal(pThis->pDevInsR3, pDrv, uLUN, 0 /* fFlags */);
     4662        rc = hdaAttachInternal(pThis, uLUN, 0 /* fFlags */, NULL /* ppDrv */);
    45864663
    45874664    LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, uLUN, pszDriver, rc));
     
    45904667
    45914668    return rc;
     4669}
     4670
     4671/**
     4672 * Powers off the device.
     4673 *
     4674 * @param   pDevIns             Device instance to power off.
     4675 */
     4676static DECLCALLBACK(void) hdaPowerOff(PPDMDEVINS pDevIns)
     4677{
     4678    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
     4679
     4680    DEVHDA_LOCK_RETURN_VOID(pThis);
     4681
     4682    LogRel2(("HDA: Powering off ...\n"));
     4683
     4684    /* Ditto goes for the codec, which in turn uses the mixer. */
     4685    hdaCodecPowerOff(pThis->pCodec);
     4686
     4687    /**
     4688     * Note: Destroy the mixer while powering off and *not* in hdaDestruct,
     4689     *       giving the mixer the chance to release any references held to
     4690     *       PDM audio streams it maintains.
     4691     */
     4692    if (pThis->pMixer)
     4693    {
     4694        AudioMixerDestroy(pThis->pMixer);
     4695        pThis->pMixer = NULL;
     4696    }
     4697
     4698    DEVHDA_UNLOCK(pThis);
    45924699}
    45934700
     
    47634870    {
    47644871        LogFunc(("Trying to attach driver for LUN #%RU32 ...\n", uLUN));
    4765         rc = hdaAttachInternal(pDevIns, NULL /* pDrv */, uLUN, 0 /* fFlags */);
     4872        rc = hdaAttachInternal(pThis, uLUN, 0 /* fFlags */, NULL /* ppDrv */);
    47664873        if (RT_FAILURE(rc))
    47674874        {
     
    47704877            else if (rc == VERR_AUDIO_BACKEND_INIT_FAILED)
    47714878            {
    4772                 hdaReattach(pThis, NULL /* pDrv */, uLUN, "NullAudio");
     4879                hdaReattachInternal(pThis, NULL /* pDrv */, uLUN, "NullAudio");
    47734880                PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
    47744881                    N_("Host audio backend initialization has failed. Selecting the NULL audio backend "
     
    48985005
    48995006                hdaReset(pDevIns);
    4900                 hdaReattach(pThis, pDrv, pDrv->uLUN, "NullAudio");
     5007                hdaReattachInternal(pThis, pDrv, pDrv->uLUN, "NullAudio");
    49015008
    49025009                PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
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