VirtualBox

Changeset 71723 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Apr 6, 2018 9:08:00 PM (7 years ago)
Author:
vboxsync
Message:

DevHDA: Don't crash in the constructor on misconfiguration or other early failure; constructor must check pdm version; corrected the PDMDEVREG function order. (how many times times must I fix these kind of things)

File:
1 edited

Legend:

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

    r71722 r71723  
    43674367
    43684368/**
    4369  * @interface_method_impl{PDMDEVREG,pfnRelocate}
    4370  */
    4371 static DECLCALLBACK(void) hdaRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
    4372 {
    4373     NOREF(offDelta);
    4374     PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    4375     pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
    4376 }
    4377 
    4378 
    4379 /**
    4380  * @interface_method_impl{PDMDEVREG,pfnReset}
    4381  */
    4382 static DECLCALLBACK(void) hdaReset(PPDMDEVINS pDevIns)
    4383 {
    4384     PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    4385 
    4386     LogFlowFuncEnter();
    4387 
    4388     DEVHDA_LOCK_RETURN_VOID(pThis);
    4389 
    4390      /*
    4391      * 18.2.6,7 defines that values of this registers might be cleared on power on/reset
    4392      * hdaReset shouldn't affects these registers.
    4393      */
    4394     HDA_REG(pThis, WAKEEN)  = 0x0;
    4395 
    4396     hdaGCTLReset(pThis);
    4397 
    4398     /* Indicate that HDA is not in reset. The firmware is supposed to (un)reset HDA,
    4399      * but we can take a shortcut.
    4400      */
    4401     HDA_REG(pThis, GCTL)    = HDA_GCTL_CRST;
    4402 
    4403     DEVHDA_UNLOCK(pThis);
    4404 }
    4405 
    4406 
    4407 /**
    4408  * @interface_method_impl{PDMDEVREG,pfnDestruct}
    4409  */
    4410 static DECLCALLBACK(int) hdaDestruct(PPDMDEVINS pDevIns)
    4411 {
    4412     PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    4413 
    4414     DEVHDA_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE);
    4415 
    4416     PHDADRIVER pDrv;
    4417     while (!RTListIsEmpty(&pThis->lstDrv))
    4418     {
    4419         pDrv = RTListGetFirst(&pThis->lstDrv, HDADRIVER, Node);
    4420 
    4421         RTListNodeRemove(&pDrv->Node);
    4422         RTMemFree(pDrv);
    4423     }
    4424 
    4425     if (pThis->pCodec)
    4426     {
    4427         hdaCodecDestruct(pThis->pCodec);
    4428 
    4429         RTMemFree(pThis->pCodec);
    4430         pThis->pCodec = NULL;
    4431     }
    4432 
    4433     RTMemFree(pThis->pu32CorbBuf);
    4434     pThis->pu32CorbBuf = NULL;
    4435 
    4436     RTMemFree(pThis->pu64RirbBuf);
    4437     pThis->pu64RirbBuf = NULL;
    4438 
    4439     for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++)
    4440         hdaStreamDestroy(&pThis->aStreams[i]);
    4441 
    4442     DEVHDA_UNLOCK(pThis);
    4443 
    4444     return VINF_SUCCESS;
    4445 }
    4446 
    4447 
    4448 /**
    44494369 * Attach command, internal version.
    44504370 *
     
    46404560
    46414561/**
     4562 * Powers off the device.
     4563 *
     4564 * @param   pDevIns             Device instance to power off.
     4565 */
     4566static DECLCALLBACK(void) hdaPowerOff(PPDMDEVINS pDevIns)
     4567{
     4568    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
     4569
     4570    DEVHDA_LOCK_RETURN_VOID(pThis);
     4571
     4572    LogRel2(("HDA: Powering off ...\n"));
     4573
     4574    /* Ditto goes for the codec, which in turn uses the mixer. */
     4575    hdaCodecPowerOff(pThis->pCodec);
     4576
     4577    /*
     4578     * Note: Destroy the mixer while powering off and *not* in hdaDestruct,
     4579     *       giving the mixer the chance to release any references held to
     4580     *       PDM audio streams it maintains.
     4581     */
     4582    if (pThis->pMixer)
     4583    {
     4584        AudioMixerDestroy(pThis->pMixer);
     4585        pThis->pMixer = NULL;
     4586    }
     4587
     4588    DEVHDA_UNLOCK(pThis);
     4589}
     4590
     4591
     4592/**
    46424593 * Re-attaches (replaces) a driver with a new driver.
     4594 *
     4595 * This is only used by to attach the Null driver when it failed to attach the
     4596 * one that was configured.
    46434597 *
    46444598 * @returns VBox status code.
     
    47044658}
    47054659
    4706 /**
    4707  * Powers off the device.
    4708  *
    4709  * @param   pDevIns             Device instance to power off.
    4710  */
    4711 static DECLCALLBACK(void) hdaPowerOff(PPDMDEVINS pDevIns)
     4660
     4661/**
     4662 * @interface_method_impl{PDMDEVREG,pfnReset}
     4663 */
     4664static DECLCALLBACK(void) hdaReset(PPDMDEVINS pDevIns)
    47124665{
    47134666    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
    47144667
     4668    LogFlowFuncEnter();
     4669
    47154670    DEVHDA_LOCK_RETURN_VOID(pThis);
    47164671
    4717     LogRel2(("HDA: Powering off ...\n"));
    4718 
    4719     /* Ditto goes for the codec, which in turn uses the mixer. */
    4720     hdaCodecPowerOff(pThis->pCodec);
    4721 
    4722     /*
    4723      * Note: Destroy the mixer while powering off and *not* in hdaDestruct,
    4724      *       giving the mixer the chance to release any references held to
    4725      *       PDM audio streams it maintains.
     4672     /*
     4673     * 18.2.6,7 defines that values of this registers might be cleared on power on/reset
     4674     * hdaReset shouldn't affects these registers.
    47264675     */
    4727     if (pThis->pMixer)
    4728     {
    4729         AudioMixerDestroy(pThis->pMixer);
    4730         pThis->pMixer = NULL;
    4731     }
     4676    HDA_REG(pThis, WAKEEN)  = 0x0;
     4677
     4678    hdaGCTLReset(pThis);
     4679
     4680    /* Indicate that HDA is not in reset. The firmware is supposed to (un)reset HDA,
     4681     * but we can take a shortcut.
     4682     */
     4683    HDA_REG(pThis, GCTL)    = HDA_GCTL_CRST;
    47324684
    47334685    DEVHDA_UNLOCK(pThis);
    47344686}
     4687
     4688
     4689/**
     4690 * @interface_method_impl{PDMDEVREG,pfnRelocate}
     4691 */
     4692static DECLCALLBACK(void) hdaRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
     4693{
     4694    NOREF(offDelta);
     4695    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
     4696    pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
     4697}
     4698
     4699
     4700/**
     4701 * @interface_method_impl{PDMDEVREG,pfnDestruct}
     4702 */
     4703static DECLCALLBACK(int) hdaDestruct(PPDMDEVINS pDevIns)
     4704{
     4705    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
     4706    PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
     4707    DEVHDA_LOCK(pThis);
     4708
     4709    PHDADRIVER pDrv;
     4710    while (!RTListIsEmpty(&pThis->lstDrv))
     4711    {
     4712        pDrv = RTListGetFirst(&pThis->lstDrv, HDADRIVER, Node);
     4713
     4714        RTListNodeRemove(&pDrv->Node);
     4715        RTMemFree(pDrv);
     4716    }
     4717
     4718    if (pThis->pCodec)
     4719    {
     4720        hdaCodecDestruct(pThis->pCodec);
     4721
     4722        RTMemFree(pThis->pCodec);
     4723        pThis->pCodec = NULL;
     4724    }
     4725
     4726    RTMemFree(pThis->pu32CorbBuf);
     4727    pThis->pu32CorbBuf = NULL;
     4728
     4729    RTMemFree(pThis->pu64RirbBuf);
     4730    pThis->pu64RirbBuf = NULL;
     4731
     4732    for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++)
     4733        hdaStreamDestroy(&pThis->aStreams[i]);
     4734
     4735    DEVHDA_UNLOCK(pThis);
     4736    return VINF_SUCCESS;
     4737}
     4738
    47354739
    47364740/**
     
    47484752     */
    47494753    pThis->uAlignmentCheckMagic = HDASTATE_ALIGNMENT_CHECK_MAGIC;
    4750     /** @todo r=bird: we'll crash checking if the list is empty!    */
     4754    RTListInit(&pThis->lstDrv);
     4755    /** @todo r=bird: There are probably other things which should be
     4756     *        initialized here before we start failing. */
    47514757
    47524758    /*
     
    49364942    if (RT_FAILURE(rc))
    49374943        return rc;
    4938 
    4939     RTListInit(&pThis->lstDrv);
    49404944
    49414945#ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO
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