VirtualBox

Changeset 68903 in vbox


Ignore:
Timestamp:
Sep 28, 2017 9:56:21 AM (7 years ago)
Author:
vboxsync
Message:

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

File:
1 edited

Legend:

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

    r68719 r68903  
    304304    /** Criticial section for this stream. */
    305305    RTCRITSECT            CritSect;
     306    /** The stream's current configuration. */
     307    PDMAUDIOSTREAMCFG     Cfg;
     308    uint32_t              Padding;
    306309#ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
    307310    /** Asynchronous I/O state members. */
     
    572575static void               ichac97DoTransfers(PAC97STATE pThis);
    573576
     577static int                ichac97MixerAddDrvStream(PAC97STATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PAC97DRIVER pDrv);
    574578static int                ichac97MixerAddDrvStreams(PAC97STATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg);
     579static void               ichac97MixerRemoveDrvStream(PAC97STATE pThis, PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir, PDMAUDIODESTSOURCE dstSrc, PAC97DRIVER pDrv);
    575580static void               ichac97MixerRemoveDrvStreams(PAC97STATE pThis, PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir, PDMAUDIODESTSOURCE dstSrc);
    576581
     
    14931498
    14941499/**
    1495  * Adds audio streams for all drivers to a specific mixer sink.
     1500 * Adds a driver stream to a specific mixer sink.
     1501 *
     1502 * @returns IPRT status code.
     1503 * @param   pThis               AC'97 state.
     1504 * @param   pMixSink            Mixer sink to add driver stream to.
     1505 * @param   pCfg                Stream configuration to use.
     1506 * @param   pDrv                Driver stream to add.
     1507 */
     1508static int ichac97MixerAddDrvStream(PAC97STATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PAC97DRIVER pDrv)
     1509{
     1510    AssertPtrReturn(pThis,    VERR_INVALID_POINTER);
     1511    AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
     1512    AssertPtrReturn(pCfg,     VERR_INVALID_POINTER);
     1513
     1514    PPDMAUDIOSTREAMCFG pStreamCfg = DrvAudioHlpStreamCfgDup(pCfg);
     1515    if (!pStreamCfg)
     1516        return VERR_NO_MEMORY;
     1517
     1518    if (!RTStrPrintf(pStreamCfg->szName, sizeof(pStreamCfg->szName), "%s", pCfg->szName))
     1519    {
     1520        RTMemFree(pStreamCfg);
     1521        return VERR_BUFFER_OVERFLOW;
     1522    }
     1523
     1524    LogFunc(("[LUN#%RU8] %s\n", pDrv->uLUN, pStreamCfg->szName));
     1525
     1526    int rc;
     1527
     1528    PAC97DRIVERSTREAM pDrvStream = ichac97MixerGetDrvStream(pThis, pDrv, pStreamCfg->enmDir, pStreamCfg->DestSource);
     1529    if (pDrvStream)
     1530    {
     1531        AssertMsg(pDrvStream->pMixStrm == NULL, ("[LUN#%RU8] Driver stream already present when it must not\n", pDrv->uLUN));
     1532
     1533        PAUDMIXSTREAM pMixStrm;
     1534        rc = AudioMixerSinkCreateStream(pMixSink, pDrv->pConnector, pStreamCfg, 0 /* fFlags */, &pMixStrm);
     1535        if (RT_SUCCESS(rc))
     1536        {
     1537            rc = AudioMixerSinkAddStream(pMixSink, pMixStrm);
     1538            LogFlowFunc(("LUN#%RU8: Created stream \"%s\", rc=%Rrc\n", pDrv->uLUN, pCfg->szName, rc));
     1539        }
     1540
     1541        if (RT_SUCCESS(rc))
     1542            pDrvStream->pMixStrm = pMixStrm;
     1543    }
     1544    else
     1545        rc = VERR_INVALID_PARAMETER;
     1546
     1547    if (pStreamCfg)
     1548    {
     1549        RTMemFree(pStreamCfg);
     1550        pStreamCfg = NULL;
     1551    }
     1552
     1553    LogFlowFuncLeaveRC(rc);
     1554    return rc;
     1555}
     1556
     1557/**
     1558 * Adds all current driver streams to a specific mixer sink.
    14961559 *
    14971560 * @returns IPRT status code.
     
    15161579    RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node)
    15171580    {
    1518         PPDMAUDIOSTREAMCFG pStreamCfg = DrvAudioHlpStreamCfgDup(pCfg);
    1519         if (!pStreamCfg)
    1520         {
    1521             rc = VERR_NO_MEMORY;
    1522             break;
    1523         }
    1524 
    1525         if (!RTStrPrintf(pStreamCfg->szName, sizeof(pStreamCfg->szName), "%s", pCfg->szName))
    1526         {
    1527             RTMemFree(pStreamCfg);
    1528 
    1529             rc = VERR_BUFFER_OVERFLOW;
    1530             break;
    1531         }
    1532 
    1533         LogFunc(("[LUN#%RU8] %s\n", pDrv->uLUN, pStreamCfg->szName));
    1534 
    1535         int rc2 = VINF_SUCCESS;
    1536 
    1537         PAC97DRIVERSTREAM pDrvStream = ichac97MixerGetDrvStream(pThis, pDrv, pStreamCfg->enmDir, pStreamCfg->DestSource);
    1538         if (pDrvStream)
    1539         {
    1540             AssertMsg(pDrvStream->pMixStrm == NULL, ("[LUN#%RU8] Driver stream already present when it must not\n", pDrv->uLUN));
    1541 
    1542             PAUDMIXSTREAM pMixStrm;
    1543             rc2 = AudioMixerSinkCreateStream(pMixSink, pDrv->pConnector, pStreamCfg, 0 /* fFlags */, &pMixStrm);
    1544             if (RT_SUCCESS(rc2))
    1545             {
    1546                 rc2 = AudioMixerSinkAddStream(pMixSink, pMixStrm);
    1547                 LogFlowFunc(("LUN#%RU8: Created stream \"%s\", rc=%Rrc\n", pDrv->uLUN, pCfg->szName, rc2));
    1548             }
    1549 
    1550             if (RT_SUCCESS(rc2))
    1551                 pDrvStream->pMixStrm = pMixStrm;
    1552 
    1553             /* If creating a stream fails, be forgiving and continue -- don't pass rc2 to rc here. */
    1554         }
    1555 
    1556         if (pStreamCfg)
    1557         {
    1558             RTMemFree(pStreamCfg);
    1559             pStreamCfg = NULL;
    1560         }
     1581        int rc2 = ichac97MixerAddDrvStream(pThis, pMixSink, pCfg, pDrv);
     1582        if (RT_SUCCESS(rc))
     1583            rc = rc2;
    15611584    }
    15621585
     
    15661589
    15671590/**
    1568  * Removes specific audio streams for all drivers.
     1591 * Removes a driver stream from a specific mixer sink.
    15691592 *
    15701593 * @param   pThis               AC'97 state.
     
    15721595 * @param   enmDir              Stream direction to remove.
    15731596 * @param   dstSrc              Stream destination / source to remove.
     1597 * @param   pDrv                Driver stream to remove.
     1598 */
     1599static void ichac97MixerRemoveDrvStream(PAC97STATE pThis, PAUDMIXSINK pMixSink,
     1600                                        PDMAUDIODIR enmDir, PDMAUDIODESTSOURCE dstSrc, PAC97DRIVER pDrv)
     1601{
     1602    AssertPtrReturnVoid(pThis);
     1603    AssertPtrReturnVoid(pMixSink);
     1604
     1605    PAC97DRIVERSTREAM pDrvStream = ichac97MixerGetDrvStream(pThis, pDrv, enmDir, dstSrc);
     1606    if (pDrvStream)
     1607    {
     1608        if (pDrvStream->pMixStrm)
     1609        {
     1610            AudioMixerSinkRemoveStream(pMixSink, pDrvStream->pMixStrm);
     1611
     1612            AudioMixerStreamDestroy(pDrvStream->pMixStrm);
     1613            pDrvStream->pMixStrm = NULL;
     1614        }
     1615    }
     1616}
     1617
     1618/**
     1619 * Removes all driver streams from a specific mixer sink.
     1620 *
     1621 * @param   pThis               AC'97 state.
     1622 * @param   pMixSink            Mixer sink to remove audio streams from.
     1623 * @param   enmDir              Stream direction to remove.
     1624 * @param   dstSrc              Stream destination / source to remove.
    15741625 */
    15751626static void ichac97MixerRemoveDrvStreams(PAC97STATE pThis, PAUDMIXSINK pMixSink,
     
    15811632    PAC97DRIVER pDrv;
    15821633    RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node)
    1583     {
    1584         PAC97DRIVERSTREAM pDrvStream = ichac97MixerGetDrvStream(pThis, pDrv, enmDir, dstSrc);
    1585         if (pDrvStream)
    1586         {
    1587             if (pDrvStream->pMixStrm)
    1588             {
    1589                 AudioMixerSinkRemoveStream(pMixSink, pDrvStream->pMixStrm);
    1590 
    1591                 AudioMixerStreamDestroy(pDrvStream->pMixStrm);
    1592                 pDrvStream->pMixStrm = NULL;
    1593             }
    1594         }
    1595     }
     1634        ichac97MixerRemoveDrvStream(pThis, pMixSink, enmDir, dstSrc, pDrv);
    15961635}
    15971636
     
    16121651    LogFunc(("[SD%RU8]\n", pStream->u8SD));
    16131652
    1614     PDMAUDIOSTREAMCFG streamCfg;
    1615     RT_ZERO(streamCfg);
    1616 
    1617     PAUDMIXSINK pMixSink = NULL;
     1653    RT_ZERO(pStream->State.Cfg);
     1654
     1655    PPDMAUDIOSTREAMCFG pCfg     = &pStream->State.Cfg;
     1656    PAUDMIXSINK        pMixSink = NULL;
    16181657
    16191658    switch (pStream->u8SD)
     
    16211660        case AC97SOUNDSOURCE_PI_INDEX:
    16221661        {
    1623             streamCfg.Props.uHz         = ichac97MixerGet(pThis, AC97_PCM_LR_ADC_Rate);
    1624             streamCfg.enmDir            = PDMAUDIODIR_IN;
    1625             streamCfg.DestSource.Source = PDMAUDIORECSOURCE_LINE;
    1626             streamCfg.enmLayout         = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
    1627 
    1628             RTStrPrintf2(streamCfg.szName, sizeof(streamCfg.szName), "Line-In");
    1629 
    1630             pMixSink                    = pThis->pSinkLineIn;
     1662            pCfg->Props.uHz         = ichac97MixerGet(pThis, AC97_PCM_LR_ADC_Rate);
     1663            pCfg->enmDir            = PDMAUDIODIR_IN;
     1664            pCfg->DestSource.Source = PDMAUDIORECSOURCE_LINE;
     1665            pCfg->enmLayout         = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
     1666
     1667            RTStrPrintf2(pCfg->szName, sizeof(pCfg->szName), "Line-In");
     1668
     1669            pMixSink                = pThis->pSinkLineIn;
    16311670            break;
    16321671        }
     
    16341673        case AC97SOUNDSOURCE_MC_INDEX:
    16351674        {
    1636             streamCfg.Props.uHz         = ichac97MixerGet(pThis, AC97_MIC_ADC_Rate);
    1637             streamCfg.enmDir            = PDMAUDIODIR_IN;
    1638             streamCfg.DestSource.Source = PDMAUDIORECSOURCE_MIC;
    1639             streamCfg.enmLayout         = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
    1640 
    1641             RTStrPrintf2(streamCfg.szName, sizeof(streamCfg.szName), "Mic-In");
    1642 
    1643             pMixSink                    = pThis->pSinkMicIn;
     1675            pCfg->Props.uHz         = ichac97MixerGet(pThis, AC97_MIC_ADC_Rate);
     1676            pCfg->enmDir            = PDMAUDIODIR_IN;
     1677            pCfg->DestSource.Source = PDMAUDIORECSOURCE_MIC;
     1678            pCfg->enmLayout         = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
     1679
     1680            RTStrPrintf2(pCfg->szName, sizeof(pCfg->szName), "Mic-In");
     1681
     1682            pMixSink                = pThis->pSinkMicIn;
    16441683            break;
    16451684        }
     
    16471686        case AC97SOUNDSOURCE_PO_INDEX:
    16481687        {
    1649             streamCfg.Props.uHz         = ichac97MixerGet(pThis, AC97_PCM_Front_DAC_Rate);
    1650             streamCfg.enmDir            = PDMAUDIODIR_OUT;
    1651             streamCfg.DestSource.Dest   = PDMAUDIOPLAYBACKDEST_FRONT;
    1652             streamCfg.enmLayout         = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
    1653 
    1654             RTStrPrintf2(streamCfg.szName, sizeof(streamCfg.szName), "Output");
    1655 
    1656             pMixSink                    = pThis->pSinkOut;
     1688            pCfg->Props.uHz         = ichac97MixerGet(pThis, AC97_PCM_Front_DAC_Rate);
     1689            pCfg->enmDir            = PDMAUDIODIR_OUT;
     1690            pCfg->DestSource.Dest   = PDMAUDIOPLAYBACKDEST_FRONT;
     1691            pCfg->enmLayout         = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
     1692
     1693            RTStrPrintf2(pCfg->szName, sizeof(pCfg->szName), "Output");
     1694
     1695            pMixSink                = pThis->pSinkOut;
    16571696            break;
    16581697        }
     
    16651704    if (RT_SUCCESS(rc))
    16661705    {
    1667         ichac97MixerRemoveDrvStreams(pThis, pMixSink, streamCfg.enmDir, streamCfg.DestSource);
    1668 
    1669         if (streamCfg.Props.uHz)
    1670         {
    1671             Assert(streamCfg.enmDir != PDMAUDIODIR_UNKNOWN);
    1672 
    1673             streamCfg.Props.cChannels = 2;
    1674             streamCfg.Props.cBits     = 16;
    1675             streamCfg.Props.fSigned   = true;
    1676             streamCfg.Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(streamCfg.Props.cBits, streamCfg.Props.cChannels);
    1677 
    1678             rc = ichac97MixerAddDrvStreams(pThis, pMixSink, &streamCfg);
     1706        ichac97MixerRemoveDrvStreams(pThis, pMixSink, pCfg->enmDir, pCfg->DestSource);
     1707
     1708        if (pCfg->Props.uHz)
     1709        {
     1710            Assert(pCfg->enmDir != PDMAUDIODIR_UNKNOWN);
     1711
     1712            pCfg->Props.cChannels = 2;
     1713            pCfg->Props.cBits     = 16;
     1714            pCfg->Props.fSigned   = true;
     1715            pCfg->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cBits, pCfg->Props.cChannels);
     1716
     1717            rc = ichac97MixerAddDrvStreams(pThis, pMixSink, pCfg);
    16791718        }
    16801719    }
     
    33923431 *
    33933432 * @returns VBox status code.
    3394  * @param   pDevIns     The device instance.
    3395  * @param   pDrv        Driver to (re-)use for (re-)attaching to.
    3396  *                      If NULL is specified, a new driver will be created and appended
    3397  *                      to the driver list.
     3433 * @param   pThis       AC'97 state.
    33983434 * @param   uLUN        The logical unit which is being detached.
    33993435 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    3400  */
    3401 static DECLCALLBACK(int) ichac97AttachInternal(PPDMDEVINS pDevIns, PAC97DRIVER pDrv, unsigned uLUN, uint32_t fFlags)
     3436 * @param   ppDrv       Attached driver instance on success. Optional.
     3437 */
     3438static int ichac97AttachInternal(PAC97STATE pThis, unsigned uLUN, uint32_t fFlags, PAC97DRIVER *ppDrv)
    34023439{
    34033440    RT_NOREF(fFlags);
    3404     PAC97STATE pThis = PDMINS_2_DATA(pDevIns, PAC97STATE);
    34053441
    34063442    /*
     
    34123448
    34133449    PPDMIBASE pDrvBase;
    3414     int rc = PDMDevHlpDriverAttach(pDevIns, uLUN,
     3450    int rc = PDMDevHlpDriverAttach(pThis->pDevInsR3, uLUN,
    34153451                                   &pThis->IBase, &pDrvBase, pszDesc);
    34163452    if (RT_SUCCESS(rc))
    34173453    {
    3418         if (pDrv == NULL)
    3419             pDrv = (PAC97DRIVER)RTMemAllocZ(sizeof(AC97DRIVER));
     3454        PAC97DRIVER pDrv = (PAC97DRIVER)RTMemAllocZ(sizeof(AC97DRIVER));
    34203455        if (pDrv)
    34213456        {
     
    34413476                pDrv->fAttached = true;
    34423477            }
     3478
     3479            if (ppDrv)
     3480                *ppDrv = pDrv;
    34433481        }
    34443482        else
     
    34553493    }
    34563494
    3457     LogFunc(("iLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
     3495    LogFunc(("uLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
    34583496    return rc;
    34593497}
    34603498
    3461 
    3462 /**
    3463  * Attach command.
    3464  *
    3465  * This is called to let the device attach to a driver for a specified LUN
    3466  * during runtime. This is not called during VM construction, the device
    3467  * constructor has to attach to all the available drivers.
     3499/**
     3500 * Detach command, internal version.
     3501 *
     3502 * This is called to let the device detach from a driver for a specified LUN
     3503 * during runtime.
    34683504 *
    34693505 * @returns VBox status code.
    3470  * @param   pDevIns     The device instance.
    3471  * @param   uLUN        The logical unit which is being detached.
     3506 * @param   pThis       AC'97 state.
     3507 * @param   pDrv        Driver to detach device from.
    34723508 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    34733509 */
     3510static int ichac97DetachInternal(PAC97STATE pThis, PAC97DRIVER pDrv, uint32_t fFlags)
     3511{
     3512    AudioMixerSinkRemoveStream(pThis->pSinkMicIn,  pDrv->MicIn.pMixStrm);
     3513    AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm);
     3514    pDrv->MicIn.pMixStrm = NULL;
     3515
     3516    AudioMixerSinkRemoveStream(pThis->pSinkLineIn, pDrv->LineIn.pMixStrm);
     3517    AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm);
     3518    pDrv->LineIn.pMixStrm = NULL;
     3519
     3520    AudioMixerSinkRemoveStream(pThis->pSinkOut,    pDrv->Out.pMixStrm);
     3521    AudioMixerStreamDestroy(pDrv->Out.pMixStrm);
     3522    pDrv->Out.pMixStrm = NULL;
     3523
     3524    RTListNodeRemove(&pDrv->Node);
     3525
     3526    LogFunc(("uLUN=%u, fFlags=0x%x\n", pDrv->uLUN, fFlags));
     3527    return VINF_SUCCESS;
     3528}
     3529
     3530/**
     3531 * @interface_method_impl{PDMDEVREG,pfnAttach}
     3532 */
    34743533static DECLCALLBACK(int) ichac97Attach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
    34753534{
    3476     return ichac97AttachInternal(pDevIns, NULL /* pDrv */, uLUN, fFlags);
    3477 }
    3478 
     3535    PAC97STATE pThis = PDMINS_2_DATA(pDevIns, PAC97STATE);
     3536
     3537    LogFunc(("uLUN=%u, fFlags=0x%x\n", uLUN, fFlags));
     3538
     3539    DEVAC97_LOCK(pThis);
     3540
     3541    PAC97DRIVER pDrv;
     3542    int rc2 = ichac97AttachInternal(pThis, uLUN, fFlags, &pDrv);
     3543    if (RT_SUCCESS(rc2))
     3544    {
     3545        PPDMIAUDIOCONNECTOR pCon = pDrv->pConnector;
     3546        AssertPtr(pCon);
     3547
     3548        if (DrvAudioHlpStreamCfgIsValid(&pThis->StreamLineIn.State.Cfg))
     3549        {
     3550            rc2 = ichac97MixerAddDrvStream(pThis, pThis->pSinkLineIn, &pThis->StreamLineIn.State.Cfg, pDrv);
     3551            AssertRC(rc2);
     3552        }
     3553
     3554        if (DrvAudioHlpStreamCfgIsValid(&pThis->StreamMicIn.State.Cfg))
     3555        {
     3556            rc2 = ichac97MixerAddDrvStream(pThis, pThis->pSinkMicIn,  &pThis->StreamMicIn.State.Cfg, pDrv);
     3557            AssertRC(rc2);
     3558        }
     3559
     3560        if (DrvAudioHlpStreamCfgIsValid(&pThis->StreamOut.State.Cfg))
     3561        {
     3562            rc2 = ichac97MixerAddDrvStream(pThis, pThis->pSinkOut,    &pThis->StreamOut.State.Cfg, pDrv);
     3563            AssertRC(rc2);
     3564        }
     3565    }
     3566
     3567    DEVAC97_UNLOCK(pThis);
     3568
     3569    return VINF_SUCCESS;
     3570}
     3571
     3572/**
     3573 * @interface_method_impl{PDMDEVREG,pfnDetach}
     3574 */
    34793575static DECLCALLBACK(void) ichac97Detach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
    34803576{
    3481     RT_NOREF(pDevIns, uLUN, fFlags);
    3482     LogFunc(("iLUN=%u, fFlags=0x%x\n", uLUN, fFlags));
    3483 }
    3484 
    3485 /**
    3486  * Re-attach.
     3577    PAC97STATE pThis = PDMINS_2_DATA(pDevIns, PAC97STATE);
     3578
     3579    LogFunc(("uLUN=%u, fFlags=0x%x\n", uLUN, fFlags));
     3580
     3581    DEVAC97_LOCK(pThis);
     3582
     3583    PAC97DRIVER pDrv, pDrvNext;
     3584    RTListForEachSafe(&pThis->lstDrv, pDrv, pDrvNext, AC97DRIVER, Node)
     3585    {
     3586        if (pDrv->uLUN == uLUN)
     3587        {
     3588            int rc2 = ichac97DetachInternal(pThis, pDrv, fFlags);
     3589            if (RT_SUCCESS(rc2))
     3590            {
     3591                RTMemFree(pDrv);
     3592                pDrv = NULL;
     3593            }
     3594
     3595            break;
     3596        }
     3597    }
     3598
     3599    DEVAC97_UNLOCK(pThis);
     3600}
     3601
     3602/**
     3603 * Re-attaches (replaces) a driver with a new driver.
    34873604 *
    34883605 * @returns VBox status code.
     
    34923609 *                      to the driver list.
    34933610 * @param   uLUN        The logical unit which is being re-detached.
    3494  * @param   pszDriver   Driver name.
    3495  */
    3496 static int ichac97Reattach(PAC97STATE pThis, PAC97DRIVER pDrv, uint8_t uLUN, const char *pszDriver)
     3611 * @param   pszDriver   New driver name to attach.
     3612 */
     3613static int ichac97ReattachInternal(PAC97STATE pThis, PAC97DRIVER pDrv, uint8_t uLUN, const char *pszDriver)
    34973614{
    34983615    AssertPtrReturn(pThis,     VERR_INVALID_POINTER);
    34993616    AssertPtrReturn(pszDriver, VERR_INVALID_POINTER);
     3617
     3618    int rc;
     3619
     3620    if (pDrv)
     3621    {
     3622        rc = ichac97DetachInternal(pThis, pDrv, 0 /* fFlags */);
     3623        if (RT_SUCCESS(rc))
     3624            rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */);
     3625
     3626        if (RT_FAILURE(rc))
     3627            return rc;
     3628
     3629        pDrv = NULL;
     3630    }
    35003631
    35013632    PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);
     
    35063637    CFGMR3RemoveNode(CFGMR3GetChildF(pDev0, "LUN#%u/", uLUN));
    35073638
    3508     if (pDrv)
    3509     {
    3510         /* Re-use a driver instance => detach the driver before. */
    3511         int rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */);
    3512         if (RT_FAILURE(rc))
    3513             return rc;
    3514     }
    3515 
    35163639#define RC_CHECK() if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; }
    35173640
    3518     int rc;
    35193641    do
    35203642    {
     
    35343656
    35353657    if (RT_SUCCESS(rc))
    3536         rc = ichac97AttachInternal(pThis->pDevInsR3, pDrv, uLUN, 0 /* fFlags */);
     3658        rc = ichac97AttachInternal(pThis, uLUN, 0 /* fFlags */, NULL /* ppDrv */);
    35373659
    35383660    LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, uLUN, pszDriver, rc));
     
    36833805    {
    36843806        LogFunc(("Trying to attach driver for LUN #%RU8 ...\n", uLUN));
    3685         rc = ichac97AttachInternal(pDevIns, NULL /* pDrv */, uLUN, 0 /* fFlags */);
     3807        rc = ichac97AttachInternal(pThis, uLUN, 0 /* fFlags */, NULL /* ppDrv */);
    36863808        if (RT_FAILURE(rc))
    36873809        {
     
    36903812            else if (rc == VERR_AUDIO_BACKEND_INIT_FAILED)
    36913813            {
    3692                 ichac97Reattach(pThis, NULL /* pDrv */, uLUN, "NullAudio");
     3814                ichac97ReattachInternal(pThis, NULL /* pDrv */, uLUN, "NullAudio");
    36933815                PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
    36943816                        N_("Host audio backend initialization has failed. Selecting the NULL audio backend "
     
    37553877
    37563878                ichac97Reset(pDevIns);
    3757                 ichac97Reattach(pThis, pDrv, pDrv->uLUN, "NullAudio");
     3879                ichac97ReattachInternal(pThis, pDrv, pDrv->uLUN, "NullAudio");
    37583880
    37593881                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