VirtualBox

Changeset 80681 in vbox


Ignore:
Timestamp:
Sep 9, 2019 7:51:22 PM (5 years ago)
Author:
vboxsync
Message:

DevHDA: Simplified error handling in the constructor by returning immediately when something goes wrong instead of postponing and rechecking rc 100rd times. This is prep work for converting it to the new PDM model. bugref:9218

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

Legend:

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

    r80680 r80681  
    49774977     */
    49784978    rc = PDMDevHlpPCIRegister(pDevIns, &pThis->PciDev);
    4979     if (RT_FAILURE(rc))
    4980         return rc;
     4979    AssertRCReturn(rc, rc);
    49814980
    49824981    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, 0x4000, PCI_ADDRESS_SPACE_MEM, hdaR3PciIoRegionMap);
    4983     if (RT_FAILURE(rc))
    4984         return rc;
     4982    AssertRCReturn(rc, rc);
    49854983
    49864984#ifdef VBOX_WITH_MSI_DEVICES
     
    49994997
    50004998    rc = PDMDevHlpSSMRegister(pDevIns, HDA_SSM_VERSION, sizeof(*pThis), hdaR3SaveExec, hdaR3LoadExec);
    5001     if (RT_FAILURE(rc))
    5002         return rc;
     4999    AssertRCReturn(rc, rc);
    50035000
    50045001#ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
     
    50195016                hdaR3ReattachInternal(pThis, NULL /* pDrv */, uLUN, "NullAudio");
    50205017                PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
    5021                     N_("Host audio backend initialization has failed. Selecting the NULL audio backend "
    5022                        "with the consequence that no sound is audible"));
     5018                                           N_("Host audio backend initialization has failed. "
     5019                                              "Selecting the NULL audio backend with the consequence that no sound is audible"));
    50235020                /* Attaching to the NULL audio backend will never fail. */
    50245021                rc = VINF_SUCCESS;
    50255022            }
     5023            else
     5024                AssertRCReturn(rc, rc);
    50265025            break;
    50275026        }
     
    50305029    LogFunc(("cLUNs=%RU8, rc=%Rrc\n", uLUN, rc));
    50315030
    5032     if (RT_SUCCESS(rc))
    5033     {
    5034         rc = AudioMixerCreate("HDA Mixer", 0 /* uFlags */, &pThis->pMixer);
    5035         if (RT_SUCCESS(rc))
    5036         {
    5037             /*
    5038              * Add mixer output sinks.
    5039              */
     5031    rc = AudioMixerCreate("HDA Mixer", 0 /* uFlags */, &pThis->pMixer);
     5032    AssertRCReturn(rc, rc);
     5033
     5034    /*
     5035     * Add mixer output sinks.
     5036     */
    50405037#ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
    5041             rc = AudioMixerCreateSink(pThis->pMixer, "[Playback] Front",
    5042                                       AUDMIXSINKDIR_OUTPUT, &pThis->SinkFront.pMixSink);
    5043             AssertRC(rc);
    5044             rc = AudioMixerCreateSink(pThis->pMixer, "[Playback] Center / Subwoofer",
    5045                                       AUDMIXSINKDIR_OUTPUT, &pThis->SinkCenterLFE.pMixSink);
    5046             AssertRC(rc);
    5047             rc = AudioMixerCreateSink(pThis->pMixer, "[Playback] Rear",
    5048                                       AUDMIXSINKDIR_OUTPUT, &pThis->SinkRear.pMixSink);
    5049             AssertRC(rc);
     5038    rc = AudioMixerCreateSink(pThis->pMixer, "[Playback] Front", AUDMIXSINKDIR_OUTPUT, &pThis->SinkFront.pMixSink);
     5039    AssertRCReturn(rc, rc);
     5040    rc = AudioMixerCreateSink(pThis->pMixer, "[Playback] Center / Subwoofer", AUDMIXSINKDIR_OUTPUT, &pThis->SinkCenterLFE.pMixSink);
     5041    AssertRCReturn(rc, rc);
     5042    rc = AudioMixerCreateSink(pThis->pMixer, "[Playback] Rear", AUDMIXSINKDIR_OUTPUT, &pThis->SinkRear.pMixSink);
     5043    AssertRCReturn(rc, rc);
    50505044#else
    5051             rc = AudioMixerCreateSink(pThis->pMixer, "[Playback] PCM Output",
    5052                                       AUDMIXSINKDIR_OUTPUT, &pThis->SinkFront.pMixSink);
    5053             AssertRC(rc);
     5045    rc = AudioMixerCreateSink(pThis->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThis->SinkFront.pMixSink);
     5046    AssertRCReturn(rc, rc);
    50545047#endif
    5055             /*
    5056              * Add mixer input sinks.
    5057              */
    5058             rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Line In",
    5059                                       AUDMIXSINKDIR_INPUT, &pThis->SinkLineIn.pMixSink);
    5060             AssertRC(rc);
     5048
     5049    /*
     5050     * Add mixer input sinks.
     5051     */
     5052    rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThis->SinkLineIn.pMixSink);
     5053    AssertRCReturn(rc, rc);
    50615054#ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    5062             rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Microphone In",
    5063                                       AUDMIXSINKDIR_INPUT, &pThis->SinkMicIn.pMixSink);
    5064             AssertRC(rc);
     5055    rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThis->SinkMicIn.pMixSink);
     5056    AssertRCReturn(rc, rc);
    50655057#endif
    5066             /* There is no master volume control. Set the master to max. */
    5067             PDMAUDIOVOLUME vol = { false, 255, 255 };
    5068             rc = AudioMixerSetMasterVolume(pThis->pMixer, &vol);
    5069             AssertRC(rc);
    5070         }
    5071     }
    5072 
    5073     if (RT_SUCCESS(rc))
    5074     {
    5075         /* Allocate CORB buffer. */
    5076         pThis->cbCorbBuf   = HDA_CORB_SIZE * HDA_CORB_ELEMENT_SIZE;
    5077         pThis->pu32CorbBuf = (uint32_t *)RTMemAllocZ(pThis->cbCorbBuf);
    5078         if (pThis->pu32CorbBuf)
    5079         {
    5080             /* Allocate RIRB buffer. */
    5081             pThis->cbRirbBuf   = HDA_RIRB_SIZE * HDA_RIRB_ELEMENT_SIZE;
    5082             pThis->pu64RirbBuf = (uint64_t *)RTMemAllocZ(pThis->cbRirbBuf);
    5083             if (pThis->pu64RirbBuf)
     5058
     5059    /* There is no master volume control. Set the master to max. */
     5060    PDMAUDIOVOLUME vol = { false, 255, 255 };
     5061    rc = AudioMixerSetMasterVolume(pThis->pMixer, &vol);
     5062    AssertRCReturn(rc, rc);
     5063
     5064    /* Allocate CORB buffer. */
     5065    pThis->cbCorbBuf   = HDA_CORB_SIZE * HDA_CORB_ELEMENT_SIZE;
     5066    pThis->pu32CorbBuf = (uint32_t *)RTMemAllocZ(pThis->cbCorbBuf);
     5067    AssertReturn(pThis->pu32CorbBuf, VERR_NO_MEMORY);
     5068
     5069    /* Allocate RIRB buffer. */
     5070    pThis->cbRirbBuf   = HDA_RIRB_SIZE * HDA_RIRB_ELEMENT_SIZE;
     5071    pThis->pu64RirbBuf = (uint64_t *)RTMemAllocZ(pThis->cbRirbBuf);
     5072    AssertReturn(pThis->pu64RirbBuf, VERR_NO_MEMORY);
     5073
     5074    /* Allocate codec. */
     5075    pThis->pCodec = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC));
     5076    AssertReturn(pThis->pCodec, VERR_NO_MEMORY);
     5077
     5078    /* Set codec callbacks to this controller. */
     5079    pThis->pCodec->pfnCbMixerAddStream    = hdaR3MixerAddStream;
     5080    pThis->pCodec->pfnCbMixerRemoveStream = hdaR3MixerRemoveStream;
     5081    pThis->pCodec->pfnCbMixerControl      = hdaR3MixerControl;
     5082    pThis->pCodec->pfnCbMixerSetVolume    = hdaR3MixerSetVolume;
     5083
     5084    pThis->pCodec->pHDAState = pThis; /* Assign HDA controller state to codec. */
     5085
     5086    /* Construct the codec. */
     5087    rc = hdaCodecConstruct(pDevIns, pThis->pCodec, 0 /* Codec index */, pCfg);
     5088    AssertRCReturn(rc, rc);
     5089
     5090    /* ICH6 datasheet defines 0 values for SVID and SID (18.1.14-15), which together with values returned for
     5091       verb F20 should provide device/codec recognition. */
     5092    Assert(pThis->pCodec->u16VendorId);
     5093    Assert(pThis->pCodec->u16DeviceId);
     5094    PCIDevSetSubSystemVendorId(&pThis->PciDev, pThis->pCodec->u16VendorId); /* 2c ro - intel.) */
     5095    PCIDevSetSubSystemId(      &pThis->PciDev, pThis->pCodec->u16DeviceId); /* 2e ro. */
     5096
     5097    /*
     5098     * Create all hardware streams.
     5099     */
     5100    static const char * const s_apszNames[] =
     5101    {
     5102        "HDA SD0", "HDA SD1", "HDA SD2", "HDA SD3",
     5103        "HDA SD4", "HDA SD5", "HDA SD6", "HDA SD7",
     5104    };
     5105    AssertCompile(RT_ELEMENTS(s_apszNames) == HDA_MAX_STREAMS);
     5106    for (uint8_t i = 0; i < HDA_MAX_STREAMS; ++i)
     5107    {
     5108        /* Create the emulation timer (per stream).
     5109         *
     5110         * Note:  Use TMCLOCK_VIRTUAL_SYNC here, as the guest's HDA driver
     5111         *        relies on exact (virtual) DMA timing and uses DMA Position Buffers
     5112         *        instead of the LPIB registers.
     5113         */
     5114        rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hdaR3Timer, &pThis->aStreams[i],
     5115                                    TMTIMER_FLAGS_NO_CRIT_SECT, s_apszNames[i], &pThis->pTimer[i]);
     5116        AssertRCReturn(rc, rc);
     5117
     5118        /* Use our own critcal section for the device timer.
     5119         * That way we can control more fine-grained when to lock what. */
     5120        rc = TMR3TimerSetCritSect(pThis->pTimer[i], &pThis->CritSect);
     5121        AssertRCReturn(rc, rc);
     5122
     5123        rc = hdaR3StreamCreate(&pThis->aStreams[i], pThis, i /* u8SD */);
     5124        AssertRCReturn(rc, rc);
     5125    }
     5126
     5127#ifdef VBOX_WITH_AUDIO_HDA_ONETIME_INIT
     5128    /*
     5129     * Initialize the driver chain.
     5130     */
     5131    PHDADRIVER pDrv;
     5132    RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
     5133    {
     5134        /*
     5135         * Only primary drivers are critical for the VM to run. Everything else
     5136         * might not worth showing an own error message box in the GUI.
     5137         */
     5138        if (!(pDrv->fFlags & PDMAUDIODRVFLAGS_PRIMARY))
     5139            continue;
     5140
     5141        PPDMIAUDIOCONNECTOR pCon = pDrv->pConnector;
     5142        AssertPtr(pCon);
     5143
     5144        bool fValidLineIn = AudioMixerStreamIsValid(pDrv->LineIn.pMixStrm);
     5145# ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     5146        bool fValidMicIn  = AudioMixerStreamIsValid(pDrv->MicIn.pMixStrm);
     5147# endif
     5148        bool fValidOut    = AudioMixerStreamIsValid(pDrv->Front.pMixStrm);
     5149# ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
     5150        /** @todo Anything to do here? */
     5151# endif
     5152
     5153        if (    !fValidLineIn
     5154# ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     5155             && !fValidMicIn
     5156# endif
     5157             && !fValidOut)
     5158        {
     5159            LogRel(("HDA: Falling back to NULL backend (no sound audible)\n"));
     5160
     5161            hdaR3Reset(pDevIns);
     5162            hdaR3ReattachInternal(pThis, pDrv, pDrv->uLUN, "NullAudio");
     5163
     5164            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
     5165                                       N_("No audio devices could be opened. "
     5166                                          "Selecting the NULL audio backend with the consequence that no sound is audible"));
     5167        }
     5168        else
     5169        {
     5170            bool fWarn = false;
     5171
     5172            PDMAUDIOBACKENDCFG BackendCfg;
     5173            int rc2 = pCon->pfnGetConfig(pCon, &BackendCfg);
     5174            if (RT_SUCCESS(rc2))
    50845175            {
    5085                 /* Allocate codec. */
    5086                 pThis->pCodec = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC));
    5087                 if (!pThis->pCodec)
    5088                     rc = PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY, N_("Out of memory allocating HDA codec state"));
    5089             }
    5090             else
    5091                 rc = PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY, N_("Out of memory allocating RIRB"));
    5092         }
    5093         else
    5094             rc = PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY, N_("Out of memory allocating CORB"));
    5095 
    5096         if (RT_SUCCESS(rc))
    5097         {
    5098             /* Set codec callbacks to this controller. */
    5099             pThis->pCodec->pfnCbMixerAddStream    = hdaR3MixerAddStream;
    5100             pThis->pCodec->pfnCbMixerRemoveStream = hdaR3MixerRemoveStream;
    5101             pThis->pCodec->pfnCbMixerControl      = hdaR3MixerControl;
    5102             pThis->pCodec->pfnCbMixerSetVolume    = hdaR3MixerSetVolume;
    5103 
    5104             pThis->pCodec->pHDAState = pThis; /* Assign HDA controller state to codec. */
    5105 
    5106             /* Construct the codec. */
    5107             rc = hdaCodecConstruct(pDevIns, pThis->pCodec, 0 /* Codec index */, pCfg);
    5108             if (RT_FAILURE(rc))
    5109                 AssertRCReturn(rc, rc);
    5110 
    5111             /* ICH6 datasheet defines 0 values for SVID and SID (18.1.14-15), which together with values returned for
    5112                verb F20 should provide device/codec recognition. */
    5113             Assert(pThis->pCodec->u16VendorId);
    5114             Assert(pThis->pCodec->u16DeviceId);
    5115             PCIDevSetSubSystemVendorId(&pThis->PciDev, pThis->pCodec->u16VendorId); /* 2c ro - intel.) */
    5116             PCIDevSetSubSystemId(      &pThis->PciDev, pThis->pCodec->u16DeviceId); /* 2e ro. */
    5117         }
    5118     }
    5119 
    5120     if (RT_SUCCESS(rc))
    5121     {
    5122         /*
    5123          * Create all hardware streams.
    5124          */
    5125         static const char * const s_apszNames[] =
    5126         {
    5127             "HDA SD0", "HDA SD1", "HDA SD2", "HDA SD3",
    5128             "HDA SD4", "HDA SD5", "HDA SD6", "HDA SD7",
    5129         };
    5130         AssertCompile(RT_ELEMENTS(s_apszNames) == HDA_MAX_STREAMS);
    5131         for (uint8_t i = 0; i < HDA_MAX_STREAMS; ++i)
    5132         {
    5133             /* Create the emulation timer (per stream).
    5134              *
    5135              * Note:  Use TMCLOCK_VIRTUAL_SYNC here, as the guest's HDA driver
    5136              *        relies on exact (virtual) DMA timing and uses DMA Position Buffers
    5137              *        instead of the LPIB registers.
    5138              */
    5139             rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hdaR3Timer, &pThis->aStreams[i],
    5140                                         TMTIMER_FLAGS_NO_CRIT_SECT, s_apszNames[i], &pThis->pTimer[i]);
    5141             AssertRCReturn(rc, rc);
    5142 
    5143             /* Use our own critcal section for the device timer.
    5144              * That way we can control more fine-grained when to lock what. */
    5145             rc = TMR3TimerSetCritSect(pThis->pTimer[i], &pThis->CritSect);
    5146             AssertRCReturn(rc, rc);
    5147 
    5148             rc = hdaR3StreamCreate(&pThis->aStreams[i], pThis, i /* u8SD */);
    5149             AssertRC(rc);
    5150         }
    5151 
    5152 #ifdef VBOX_WITH_AUDIO_HDA_ONETIME_INIT
    5153         /*
    5154          * Initialize the driver chain.
    5155          */
    5156         PHDADRIVER pDrv;
    5157         RTListForEach(&pThis->lstDrv, pDrv, HDADRIVER, Node)
    5158         {
    5159             /*
    5160              * Only primary drivers are critical for the VM to run. Everything else
    5161              * might not worth showing an own error message box in the GUI.
    5162              */
    5163             if (!(pDrv->fFlags & PDMAUDIODRVFLAGS_PRIMARY))
    5164                 continue;
    5165 
    5166             PPDMIAUDIOCONNECTOR pCon = pDrv->pConnector;
    5167             AssertPtr(pCon);
    5168 
    5169             bool fValidLineIn = AudioMixerStreamIsValid(pDrv->LineIn.pMixStrm);
     5176                if (BackendCfg.cMaxStreamsIn)
     5177                {
    51705178# ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    5171             bool fValidMicIn  = AudioMixerStreamIsValid(pDrv->MicIn.pMixStrm);
    5172 # endif
    5173             bool fValidOut    = AudioMixerStreamIsValid(pDrv->Front.pMixStrm);
    5174 # ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
    5175             /** @todo Anything to do here? */
    5176 # endif
    5177 
    5178             if (    !fValidLineIn
    5179 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    5180                  && !fValidMicIn
    5181 # endif
    5182                  && !fValidOut)
    5183             {
    5184                 LogRel(("HDA: Falling back to NULL backend (no sound audible)\n"));
    5185 
    5186                 hdaR3Reset(pDevIns);
    5187                 hdaR3ReattachInternal(pThis, pDrv, pDrv->uLUN, "NullAudio");
    5188 
    5189                 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
    5190                     N_("No audio devices could be opened. Selecting the NULL audio backend "
    5191                        "with the consequence that no sound is audible"));
     5179                    /* If the audio backend supports two or more input streams at once,
     5180                     * warn if one of our two inputs (microphone-in and line-in) failed to initialize. */
     5181                    if (BackendCfg.cMaxStreamsIn >= 2)
     5182                        fWarn = !fValidLineIn || !fValidMicIn;
     5183                    /* If the audio backend only supports one input stream at once (e.g. pure ALSA, and
     5184                     * *not* ALSA via PulseAudio plugin!), only warn if both of our inputs failed to initialize.
     5185                     * One of the two simply is not in use then. */
     5186                    else if (BackendCfg.cMaxStreamsIn == 1)
     5187                        fWarn = !fValidLineIn && !fValidMicIn;
     5188                    /* Don't warn if our backend is not able of supporting any input streams at all. */
     5189# else  /* !VBOX_WITH_AUDIO_HDA_MIC_IN */
     5190                    /* We only have line-in as input source. */
     5191                    fWarn = !fValidLineIn;
     5192# endif /* !VBOX_WITH_AUDIO_HDA_MIC_IN */
     5193                }
     5194
     5195                if (   !fWarn
     5196                    && BackendCfg.cMaxStreamsOut)
     5197                    fWarn = !fValidOut;
    51925198            }
    51935199            else
    51945200            {
    5195                 bool fWarn = false;
    5196 
    5197                 PDMAUDIOBACKENDCFG backendCfg;
    5198                 int rc2 = pCon->pfnGetConfig(pCon, &backendCfg);
    5199                 if (RT_SUCCESS(rc2))
     5201                LogRel(("HDA: Unable to retrieve audio backend configuration for LUN #%RU8, rc=%Rrc\n", pDrv->uLUN, rc2));
     5202                fWarn = true;
     5203            }
     5204
     5205            if (fWarn)
     5206            {
     5207                char   szMissingStreams[255];
     5208                size_t len = 0;
     5209                if (!fValidLineIn)
    52005210                {
    5201                     if (backendCfg.cMaxStreamsIn)
    5202                     {
     5211                    LogRel(("HDA: WARNING: Unable to open PCM line input for LUN #%RU8!\n", pDrv->uLUN));
     5212                    len = RTStrPrintf(szMissingStreams, sizeof(szMissingStreams), "PCM Input");
     5213                }
    52035214# ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    5204                         /* If the audio backend supports two or more input streams at once,
    5205                          * warn if one of our two inputs (microphone-in and line-in) failed to initialize. */
    5206                         if (backendCfg.cMaxStreamsIn >= 2)
    5207                             fWarn = !fValidLineIn || !fValidMicIn;
    5208                         /* If the audio backend only supports one input stream at once (e.g. pure ALSA, and
    5209                          * *not* ALSA via PulseAudio plugin!), only warn if both of our inputs failed to initialize.
    5210                          * One of the two simply is not in use then. */
    5211                         else if (backendCfg.cMaxStreamsIn == 1)
    5212                             fWarn = !fValidLineIn && !fValidMicIn;
    5213                         /* Don't warn if our backend is not able of supporting any input streams at all. */
    5214 # else /* !VBOX_WITH_AUDIO_HDA_MIC_IN */
    5215                         /* We only have line-in as input source. */
    5216                         fWarn = !fValidLineIn;
    5217 # endif /* VBOX_WITH_AUDIO_HDA_MIC_IN */
    5218                     }
    5219 
    5220                     if (   !fWarn
    5221                         && backendCfg.cMaxStreamsOut)
    5222                     {
    5223                         fWarn = !fValidOut;
    5224                     }
     5215                if (!fValidMicIn)
     5216                {
     5217                    LogRel(("HDA: WARNING: Unable to open PCM microphone input for LUN #%RU8!\n", pDrv->uLUN));
     5218                    len += RTStrPrintf(szMissingStreams + len,
     5219                                       sizeof(szMissingStreams) - len, len ? ", PCM Microphone" : "PCM Microphone");
    52255220                }
    5226                 else
     5221# endif
     5222                if (!fValidOut)
    52275223                {
    5228                     LogRel(("HDA: Unable to retrieve audio backend configuration for LUN #%RU8, rc=%Rrc\n", pDrv->uLUN, rc2));
    5229                     fWarn = true;
     5224                    LogRel(("HDA: WARNING: Unable to open PCM output for LUN #%RU8!\n", pDrv->uLUN));
     5225                    len += RTStrPrintf(szMissingStreams + len,
     5226                                       sizeof(szMissingStreams) - len, len ? ", PCM Output" : "PCM Output");
    52305227                }
    52315228
    5232                 if (fWarn)
    5233                 {
    5234                     char   szMissingStreams[255];
    5235                     size_t len = 0;
    5236                     if (!fValidLineIn)
    5237                     {
    5238                         LogRel(("HDA: WARNING: Unable to open PCM line input for LUN #%RU8!\n", pDrv->uLUN));
    5239                         len = RTStrPrintf(szMissingStreams, sizeof(szMissingStreams), "PCM Input");
    5240                     }
    5241 # ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    5242                     if (!fValidMicIn)
    5243                     {
    5244                         LogRel(("HDA: WARNING: Unable to open PCM microphone input for LUN #%RU8!\n", pDrv->uLUN));
    5245                         len += RTStrPrintf(szMissingStreams + len,
    5246                                            sizeof(szMissingStreams) - len, len ? ", PCM Microphone" : "PCM Microphone");
    5247                     }
    5248 # endif /* VBOX_WITH_AUDIO_HDA_MIC_IN */
    5249                     if (!fValidOut)
    5250                     {
    5251                         LogRel(("HDA: WARNING: Unable to open PCM output for LUN #%RU8!\n", pDrv->uLUN));
    5252                         len += RTStrPrintf(szMissingStreams + len,
    5253                                            sizeof(szMissingStreams) - len, len ? ", PCM Output" : "PCM Output");
    5254                     }
    5255 
    5256                     PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
    5257                                                N_("Some HDA audio streams (%s) could not be opened. Guest applications generating audio "
    5258                                                   "output or depending on audio input may hang. Make sure your host audio device "
    5259                                                   "is working properly. Check the logfile for error messages of the audio "
    5260                                                   "subsystem"), szMissingStreams);
    5261                 }
     5229                PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
     5230                                           N_("Some HDA audio streams (%s) could not be opened. "
     5231                                              "Guest applications generating audio output or depending on audio input may hang. "
     5232                                              "Make sure your host audio device is working properly. "
     5233                                              "Check the logfile for error messages of the audio subsystem"), szMissingStreams);
    52625234            }
    52635235        }
     5236    }
    52645237#endif /* VBOX_WITH_AUDIO_HDA_ONETIME_INIT */
    5265     }
    5266 
    5267     if (RT_SUCCESS(rc))
    5268     {
    5269         hdaR3Reset(pDevIns);
    5270 
    5271         /*
    5272          * Debug and string formatter types.
    5273          */
    5274         PDMDevHlpDBGFInfoRegister(pDevIns, "hda",         "HDA info. (hda [register case-insensitive])",     hdaR3DbgInfo);
    5275         PDMDevHlpDBGFInfoRegister(pDevIns, "hdabdle",     "HDA stream BDLE info. (hdabdle [stream number])", hdaR3DbgInfoBDLE);
    5276         PDMDevHlpDBGFInfoRegister(pDevIns, "hdastream",   "HDA stream info. (hdastream [stream number])",    hdaR3DbgInfoStream);
    5277         PDMDevHlpDBGFInfoRegister(pDevIns, "hdcnodes",    "HDA codec nodes.",                                hdaR3DbgInfoCodecNodes);
    5278         PDMDevHlpDBGFInfoRegister(pDevIns, "hdcselector", "HDA codec's selector states [node number].",      hdaR3DbgInfoCodecSelector);
    5279         PDMDevHlpDBGFInfoRegister(pDevIns, "hdamixer",    "HDA mixer state.",                                hdaR3DbgInfoMixer);
    5280 
    5281         rc = RTStrFormatTypeRegister("bdle",    hdaR3StrFmtBDLE,    NULL);
    5282         AssertRC(rc);
    5283         rc = RTStrFormatTypeRegister("sdctl",   hdaR3StrFmtSDCTL,   NULL);
    5284         AssertRC(rc);
    5285         rc = RTStrFormatTypeRegister("sdsts",   hdaR3StrFmtSDSTS,   NULL);
    5286         AssertRC(rc);
    5287         rc = RTStrFormatTypeRegister("sdfifos", hdaR3StrFmtSDFIFOS, NULL);
    5288         AssertRC(rc);
    5289         rc = RTStrFormatTypeRegister("sdfifow", hdaR3StrFmtSDFIFOW, NULL);
    5290         AssertRC(rc);
    5291 
    5292         /*
    5293          * Some debug assertions.
    5294          */
    5295         for (unsigned i = 0; i < RT_ELEMENTS(g_aHdaRegMap); i++)
    5296         {
    5297             struct HDAREGDESC const *pReg     = &g_aHdaRegMap[i];
    5298             struct HDAREGDESC const *pNextReg = i + 1 < RT_ELEMENTS(g_aHdaRegMap) ?  &g_aHdaRegMap[i + 1] : NULL;
    5299 
    5300             /* binary search order. */
    5301             AssertReleaseMsg(!pNextReg || pReg->offset + pReg->size <= pNextReg->offset,
    5302                              ("[%#x] = {%#x LB %#x}  vs. [%#x] = {%#x LB %#x}\n",
    5303                               i, pReg->offset, pReg->size, i + 1, pNextReg->offset, pNextReg->size));
    5304 
    5305             /* alignment. */
    5306             AssertReleaseMsg(   pReg->size == 1
    5307                              || (pReg->size == 2 && (pReg->offset & 1) == 0)
    5308                              || (pReg->size == 3 && (pReg->offset & 3) == 0)
    5309                              || (pReg->size == 4 && (pReg->offset & 3) == 0),
    5310                              ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
    5311 
    5312             /* registers are packed into dwords - with 3 exceptions with gaps at the end of the dword. */
    5313             AssertRelease(((pReg->offset + pReg->size) & 3) == 0 || pNextReg);
    5314             if (pReg->offset & 3)
    5315             {
    5316                 struct HDAREGDESC const *pPrevReg = i > 0 ?  &g_aHdaRegMap[i - 1] : NULL;
    5317                 AssertReleaseMsg(pPrevReg, ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
    5318                 if (pPrevReg)
    5319                     AssertReleaseMsg(pPrevReg->offset + pPrevReg->size == pReg->offset,
    5320                                      ("[%#x] = {%#x LB %#x}  vs. [%#x] = {%#x LB %#x}\n",
    5321                                       i - 1, pPrevReg->offset, pPrevReg->size, i + 1, pReg->offset, pReg->size));
    5322             }
     5238
     5239    hdaR3Reset(pDevIns);
     5240
     5241    /*
     5242     * Info items and string formatter types.  The latter is non-optional as
     5243     * the info handles use (at least some of) the custom types and we cannot
     5244     * accept screwing formatting.
     5245     */
     5246    PDMDevHlpDBGFInfoRegister(pDevIns, "hda",         "HDA info. (hda [register case-insensitive])",     hdaR3DbgInfo);
     5247    PDMDevHlpDBGFInfoRegister(pDevIns, "hdabdle",     "HDA stream BDLE info. (hdabdle [stream number])", hdaR3DbgInfoBDLE);
     5248    PDMDevHlpDBGFInfoRegister(pDevIns, "hdastream",   "HDA stream info. (hdastream [stream number])",    hdaR3DbgInfoStream);
     5249    PDMDevHlpDBGFInfoRegister(pDevIns, "hdcnodes",    "HDA codec nodes.",                                hdaR3DbgInfoCodecNodes);
     5250    PDMDevHlpDBGFInfoRegister(pDevIns, "hdcselector", "HDA codec's selector states [node number].",      hdaR3DbgInfoCodecSelector);
     5251    PDMDevHlpDBGFInfoRegister(pDevIns, "hdamixer",    "HDA mixer state.",                                hdaR3DbgInfoMixer);
     5252
     5253    rc = RTStrFormatTypeRegister("bdle",    hdaR3StrFmtBDLE,    NULL);
     5254    AssertMsgReturn(RT_SUCCESS(rc) || rc == VERR_ALREADY_EXISTS, ("%Rrc\n", rc), rc);
     5255    rc = RTStrFormatTypeRegister("sdctl",   hdaR3StrFmtSDCTL,   NULL);
     5256    AssertMsgReturn(RT_SUCCESS(rc) || rc == VERR_ALREADY_EXISTS, ("%Rrc\n", rc), rc);
     5257    rc = RTStrFormatTypeRegister("sdsts",   hdaR3StrFmtSDSTS,   NULL);
     5258    AssertMsgReturn(RT_SUCCESS(rc) || rc == VERR_ALREADY_EXISTS, ("%Rrc\n", rc), rc);
     5259    rc = RTStrFormatTypeRegister("sdfifos", hdaR3StrFmtSDFIFOS, NULL);
     5260    AssertMsgReturn(RT_SUCCESS(rc) || rc == VERR_ALREADY_EXISTS, ("%Rrc\n", rc), rc);
     5261    rc = RTStrFormatTypeRegister("sdfifow", hdaR3StrFmtSDFIFOW, NULL);
     5262    AssertMsgReturn(RT_SUCCESS(rc) || rc == VERR_ALREADY_EXISTS, ("%Rrc\n", rc), rc);
     5263
     5264    /*
     5265     * Asserting sanity.
     5266     */
     5267    for (unsigned i = 0; i < RT_ELEMENTS(g_aHdaRegMap); i++)
     5268    {
     5269        struct HDAREGDESC const *pReg     = &g_aHdaRegMap[i];
     5270        struct HDAREGDESC const *pNextReg = i + 1 < RT_ELEMENTS(g_aHdaRegMap) ?  &g_aHdaRegMap[i + 1] : NULL;
     5271
     5272        /* binary search order. */
     5273        AssertReleaseMsg(!pNextReg || pReg->offset + pReg->size <= pNextReg->offset,
     5274                         ("[%#x] = {%#x LB %#x}  vs. [%#x] = {%#x LB %#x}\n",
     5275                          i, pReg->offset, pReg->size, i + 1, pNextReg->offset, pNextReg->size));
     5276
     5277        /* alignment. */
     5278        AssertReleaseMsg(   pReg->size == 1
     5279                         || (pReg->size == 2 && (pReg->offset & 1) == 0)
     5280                         || (pReg->size == 3 && (pReg->offset & 3) == 0)
     5281                         || (pReg->size == 4 && (pReg->offset & 3) == 0),
     5282                         ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
     5283
     5284        /* registers are packed into dwords - with 3 exceptions with gaps at the end of the dword. */
     5285        AssertRelease(((pReg->offset + pReg->size) & 3) == 0 || pNextReg);
     5286        if (pReg->offset & 3)
     5287        {
     5288            struct HDAREGDESC const *pPrevReg = i > 0 ?  &g_aHdaRegMap[i - 1] : NULL;
     5289            AssertReleaseMsg(pPrevReg, ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
     5290            if (pPrevReg)
     5291                AssertReleaseMsg(pPrevReg->offset + pPrevReg->size == pReg->offset,
     5292                                 ("[%#x] = {%#x LB %#x}  vs. [%#x] = {%#x LB %#x}\n",
     5293                                  i - 1, pPrevReg->offset, pPrevReg->size, i + 1, pReg->offset, pReg->size));
     5294        }
    53235295#if 0
    5324             if ((pReg->offset + pReg->size) & 3)
    5325             {
    5326                 AssertReleaseMsg(pNextReg, ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
    5327                 if (pNextReg)
    5328                     AssertReleaseMsg(pReg->offset + pReg->size == pNextReg->offset,
    5329                                      ("[%#x] = {%#x LB %#x}  vs. [%#x] = {%#x LB %#x}\n",
    5330                                       i, pReg->offset, pReg->size, i + 1,  pNextReg->offset, pNextReg->size));
    5331             }
     5296        if ((pReg->offset + pReg->size) & 3)
     5297        {
     5298            AssertReleaseMsg(pNextReg, ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
     5299            if (pNextReg)
     5300                AssertReleaseMsg(pReg->offset + pReg->size == pNextReg->offset,
     5301                                 ("[%#x] = {%#x LB %#x}  vs. [%#x] = {%#x LB %#x}\n",
     5302                                  i, pReg->offset, pReg->size, i + 1,  pNextReg->offset, pNextReg->size));
     5303        }
    53325304#endif
    5333             /* The final entry is a full DWORD, no gaps! Allows shortcuts. */
    5334             AssertReleaseMsg(pNextReg || ((pReg->offset + pReg->size) & 3) == 0,
    5335                              ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
    5336         }
     5305        /* The final entry is a full DWORD, no gaps! Allows shortcuts. */
     5306        AssertReleaseMsg(pNextReg || ((pReg->offset + pReg->size) & 3) == 0,
     5307                         ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size));
    53375308    }
    53385309
    53395310# ifdef VBOX_WITH_STATISTICS
    5340     if (RT_SUCCESS(rc))
    5341     {
    5342         /*
    5343          * Register statistics.
    5344          */
    5345         PDMDevHlpSTAMRegister(pDevIns, &pThis->StatTimer,            STAMTYPE_PROFILE, "/Devices/HDA/Timer",             STAMUNIT_TICKS_PER_CALL, "Profiling hdaR3Timer.");
    5346         PDMDevHlpSTAMRegister(pDevIns, &pThis->StatIn,               STAMTYPE_PROFILE, "/Devices/HDA/Input",             STAMUNIT_TICKS_PER_CALL, "Profiling input.");
    5347         PDMDevHlpSTAMRegister(pDevIns, &pThis->StatOut,              STAMTYPE_PROFILE, "/Devices/HDA/Output",            STAMUNIT_TICKS_PER_CALL, "Profiling output.");
    5348         PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesRead,        STAMTYPE_COUNTER, "/Devices/HDA/BytesRead"   ,      STAMUNIT_BYTES,          "Bytes read from HDA emulation.");
    5349         PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesWritten,     STAMTYPE_COUNTER, "/Devices/HDA/BytesWritten",      STAMUNIT_BYTES,          "Bytes written to HDA emulation.");
    5350     }
     5311    /*
     5312     * Register statistics.
     5313     */
     5314    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatTimer,            STAMTYPE_PROFILE, "/Devices/HDA/Timer",             STAMUNIT_TICKS_PER_CALL, "Profiling hdaR3Timer.");
     5315    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatIn,               STAMTYPE_PROFILE, "/Devices/HDA/Input",             STAMUNIT_TICKS_PER_CALL, "Profiling input.");
     5316    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatOut,              STAMTYPE_PROFILE, "/Devices/HDA/Output",            STAMUNIT_TICKS_PER_CALL, "Profiling output.");
     5317    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesRead,        STAMTYPE_COUNTER, "/Devices/HDA/BytesRead"   ,      STAMUNIT_BYTES,          "Bytes read from HDA emulation.");
     5318    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesWritten,     STAMTYPE_COUNTER, "/Devices/HDA/BytesWritten",      STAMUNIT_BYTES,          "Bytes written to HDA emulation.");
    53515319# endif
    53525320
    5353     LogFlowFuncLeaveRC(rc);
    5354     return rc;
     5321    return VINF_SUCCESS;
    53555322}
    53565323
  • trunk/src/VBox/Devices/Audio/HDACodec.h

    r76565 r80681  
    101101    const uint8_t           u8DacLineOut;
    102102
    103     /** Public codec functions. */
     103    /** @name Public codec functions.
     104     *  @{  */
    104105    DECLR3CALLBACKMEMBER(int,  pfnLookup, (PHDACODEC pThis, uint32_t uVerb, uint64_t *puResp));
    105106    DECLR3CALLBACKMEMBER(void, pfnReset, (PHDACODEC pThis));
    106107    DECLR3CALLBACKMEMBER(int,  pfnNodeReset, (PHDACODEC pThis, uint8_t, PCODECNODE));
     108    /** @} */
    107109
    108     /** Callbacks to the HDA controller, mostly used for multiplexing to the various host backends. */
     110    /** @name Callbacks to the HDA controller, mostly used for multiplexing to the
     111     *        various host backends.
     112     * @{ */
    109113    DECLR3CALLBACKMEMBER(int,  pfnCbMixerAddStream, (PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOSTREAMCFG pCfg));
    110114    DECLR3CALLBACKMEMBER(int,  pfnCbMixerRemoveStream, (PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl));
    111115    DECLR3CALLBACKMEMBER(int,  pfnCbMixerControl, (PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, uint8_t uSD, uint8_t uChannel));
    112116    DECLR3CALLBACKMEMBER(int,  pfnCbMixerSetVolume, (PHDASTATE pThis, PDMAUDIOMIXERCTL enmMixerCtl, PPDMAUDIOVOLUME pVol));
     117    /** @} */
    113118
    114     /** These callbacks are set by codec implementation to answer debugger requests. */
     119    /** @name These callbacks are set by codec implementation to answer debugger requests.
     120     * @{ */
    115121    DECLR3CALLBACKMEMBER(void, pfnDbgListNodes, (PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs));
    116122    DECLR3CALLBACKMEMBER(void, pfnDbgSelector, (PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs));
     123    /** @} */
    117124} HDACODEC;
    118125
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