Index: trunk/src/VBox/Devices/Audio/DevHda.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevHda.cpp	(revision 88904)
+++ trunk/src/VBox/Devices/Audio/DevHda.cpp	(revision 88905)
@@ -2401,10 +2401,9 @@
         RTListForEach(&pThisCC->lstDrv, pDrv, HDADRIVER, Node)
         {
+            /* We ignore failures here because one non-working driver shouldn't
+               be allowed to spoil it for everyone else. */
             int rc2 = hdaR3MixerAddDrvStream(pDevIns, pMixSink, pCfg, pDrv);
             if (RT_FAILURE(rc2))
-                LogFunc(("Attaching stream failed with %Rrc\n", rc2));
-
-            /* Do not pass failure to rc here, as there might be drivers which aren't
-             * configured / ready yet. */
+                LogFunc(("Attaching stream failed with %Rrc (ignored)\n", rc2));
         }
     }
@@ -4389,9 +4388,5 @@
 
 /**
- * Attach command, internal version.
- *
- * This is called to let the device attach to a driver for a specified LUN
- * during runtime. This is not called during VM construction, the device
- * constructor has to attach to all the available drivers.
+ * Worker for hdaR3Construct() and hdaR3Attach().
  *
  * @returns VBox status code.
@@ -4400,17 +4395,13 @@
  * @param   pThisCC     The ring-3 HDA device state.
  * @param   uLUN        The logical unit which is being detached.
- * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
  * @param   ppDrv       Attached driver instance on success. Optional.
  */
-static int hdaR3AttachInternal(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC, unsigned uLUN, uint32_t fFlags, PHDADRIVER *ppDrv)
-{
-    RT_NOREF(fFlags);
-
+static int hdaR3AttachInternal(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC, unsigned uLUN, PHDADRIVER *ppDrv)
+{
     /*
      * Attach driver.
      */
-    char *pszDesc;
-    if (RTStrAPrintf(&pszDesc, "Audio driver port (HDA) for LUN#%u", uLUN) <= 0)
-        AssertLogRelFailedReturn(VERR_NO_MEMORY);
+    char *pszDesc = RTStrAPrintf2("Audio driver port (HDA) for LUN#%u", uLUN);
+    AssertLogRelReturn(pszDesc, VERR_NO_STR_MEMORY);
 
     PPDMIBASE pDrvBase;
@@ -4421,50 +4412,59 @@
         if (pDrv)
         {
-            pDrv->pDrvBase          = pDrvBase;
-            pDrv->pHDAStateShared   = pThis;
-            pDrv->pHDAStateR3       = pThisCC;
-            pDrv->uLUN              = uLUN;
-            pDrv->pConnector        = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR);
-            AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN#%u has no host audio interface, rc=%Rrc\n", uLUN, rc));
-
-            /*
-             * For now we always set the driver at LUN 0 as our primary
-             * host backend. This might change in the future.
-             */
-            if (pDrv->uLUN == 0)
-                pDrv->fFlags |= PDMAUDIODRVFLAGS_PRIMARY;
-
-            LogFunc(("LUN#%u: pCon=%p, drvFlags=0x%x\n", uLUN, pDrv->pConnector, pDrv->fFlags));
-
-            /* Attach to driver list if not attached yet. */
-            if (!pDrv->fAttached)
+            pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR);
+            AssertPtr(pDrv->pConnector);
+            if (RT_VALID_PTR(pDrv->pConnector))
             {
-                RTListAppend(&pThisCC->lstDrv, &pDrv->Node);
-                pDrv->fAttached = true;
+                pDrv->pDrvBase          = pDrvBase;
+                pDrv->pHDAStateShared   = pThis;
+                pDrv->pHDAStateR3       = pThisCC;
+                pDrv->uLUN              = uLUN;
+                AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN#%u has no host audio interface, rc=%Rrc\n", uLUN, rc));
+
+                /*
+                 * For now we always set the driver at LUN 0 as our primary
+                 * host backend. This might change in the future.
+                 */
+                if (pDrv->uLUN == 0)
+                    pDrv->fFlags |= PDMAUDIODRVFLAGS_PRIMARY;
+
+                LogFunc(("LUN#%u: pCon=%p, drvFlags=0x%x\n", uLUN, pDrv->pConnector, pDrv->fFlags));
+
+                /* Attach to driver list if not attached yet. */
+                if (!pDrv->fAttached)
+                {
+                    RTListAppend(&pThisCC->lstDrv, &pDrv->Node);
+                    pDrv->fAttached = true;
+                }
+
+                if (ppDrv)
+                    *ppDrv = pDrv;
+
+                /*
+                 * While we're here, give the windows backends a hint about our typical playback
+                 * configuration.
+                 * Note! If 48000Hz is advertised to the guest, add it here.
+                 */
+                if (   pDrv->pConnector
+                    && pDrv->pConnector->pfnStreamConfigHint)
+                {
+                    PDMAUDIOSTREAMCFG Cfg;
+                    RT_ZERO(Cfg);
+                    Cfg.enmDir                        = PDMAUDIODIR_OUT;
+                    Cfg.u.enmDst                      = PDMAUDIOPLAYBACKDST_FRONT;
+                    Cfg.enmLayout                     = PDMAUDIOSTREAMLAYOUT_INTERLEAVED;
+                    Cfg.Device.cMsSchedulingHint      = 10;
+                    Cfg.Backend.cFramesPreBuffering   = UINT32_MAX;
+                    PDMAudioPropsInit(&Cfg.Props, 2, true /*fSigned*/, 2, 44100);
+                    RTStrPrintf(Cfg.szName, sizeof(Cfg.szName), "output 44.1kHz 2ch S16 (HDA config hint)");
+
+                    pDrv->pConnector->pfnStreamConfigHint(pDrv->pConnector, &Cfg); /* (may trash CfgReq) */
+                }
+
+                LogFunc(("LUN#%u: VINF_SUCCESS\n", uLUN));
+                return VINF_SUCCESS;
             }
 
-            if (ppDrv)
-                *ppDrv = pDrv;
-
-            /*
-             * While we're here, give the windows backends a hint about our typical playback
-             * configuration.
-             * Note! If 48000Hz is advertised to the guest, add it here.
-             */
-            if (   pDrv->pConnector
-                && pDrv->pConnector->pfnStreamConfigHint)
-            {
-                PDMAUDIOSTREAMCFG Cfg;
-                RT_ZERO(Cfg);
-                Cfg.enmDir                        = PDMAUDIODIR_OUT;
-                Cfg.u.enmDst                      = PDMAUDIOPLAYBACKDST_FRONT;
-                Cfg.enmLayout                     = PDMAUDIOSTREAMLAYOUT_INTERLEAVED;
-                Cfg.Device.cMsSchedulingHint      = 10;
-                Cfg.Backend.cFramesPreBuffering   = UINT32_MAX;
-                PDMAudioPropsInit(&Cfg.Props, 2, true /*fSigned*/, 2, 44100);
-                RTStrPrintf(Cfg.szName, sizeof(Cfg.szName), "output 44.1kHz 2ch S16 (HDA config hint)");
-
-                pDrv->pConnector->pfnStreamConfigHint(pDrv->pConnector, &Cfg); /* (may trash CfgReq) */
-            }
+            rc = VERR_PDM_MISSING_INTERFACE_BELOW;
         }
         else
@@ -4473,32 +4473,51 @@
     else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
         LogFunc(("No attached driver for LUN #%u\n", uLUN));
-
-    if (RT_FAILURE(rc))
-    {
-        /* Only free this string on failure;
-         * must remain valid for the live of the driver instance. */
-        RTStrFree(pszDesc);
-    }
-
-    LogFunc(("uLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
+    else
+        LogFunc(("Failed attaching driver for LUN #%u: %Rrc\n", uLUN, rc));
+
+    RTStrFree(pszDesc);
+    LogFunc(("LUN#%u: rc=%Rrc\n", uLUN, rc));
     return rc;
 }
 
-/**
- * Detach command, internal version.
+
+/**
+ * @interface_method_impl{PDMDEVREG,pfnAttach}
+ */
+static DECLCALLBACK(int) hdaR3Attach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
+{
+    PHDASTATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
+    PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3);
+    RT_NOREF(fFlags);
+    LogFunc(("uLUN=%u, fFlags=0x%x\n", uLUN, fFlags));
+
+    DEVHDA_LOCK_RETURN(pDevIns, pThis, VERR_IGNORED);
+
+    PHDADRIVER pDrv;
+    int rc = hdaR3AttachInternal(pDevIns, pThis, pThisCC, uLUN, &pDrv);
+    if (RT_SUCCESS(rc))
+    {
+        int rc2 = hdaR3MixerAddDrv(pDevIns, pThisCC, pDrv);
+        if (RT_FAILURE(rc2))
+            LogFunc(("hdaR3MixerAddDrv failed with %Rrc (ignored)\n", rc2));
+    }
+
+    DEVHDA_UNLOCK(pDevIns, pThis);
+    return rc;
+}
+
+
+/**
+ * Worker for hdaR3Detach that does all but free pDrv.
  *
  * This is called to let the device detach from a driver for a specified LUN
- * during runtime.
+ * at runtime.
  *
- * @returns VBox status code.
  * @param   pDevIns     The device instance.
  * @param   pThisCC     The ring-3 HDA device state.
  * @param   pDrv        Driver to detach from device.
- * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
- */
-static int hdaR3DetachInternal(PPDMDEVINS pDevIns, PHDASTATER3 pThisCC, PHDADRIVER pDrv, uint32_t fFlags)
-{
-    RT_NOREF(fFlags);
-
+ */
+static void hdaR3DetachInternal(PPDMDEVINS pDevIns, PHDASTATER3 pThisCC, PHDADRIVER pDrv)
+{
     /* First, remove the driver from our list and destory it's associated streams.
      * This also will un-set the driver as a recording source (if associated). */
@@ -4539,63 +4558,34 @@
     }
 
-    LogFunc(("uLUN=%u, fFlags=0x%x\n", pDrv->uLUN, fFlags));
-    return VINF_SUCCESS;
-}
-
-
-/**
- * @interface_method_impl{PDMDEVREG,pfnAttach}
- */
-static DECLCALLBACK(int) hdaR3Attach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
+    LogFunc(("LUN#%u detached\n", pDrv->uLUN));
+}
+
+
+/**
+ * @interface_method_impl{PDMDEVREG,pfnDetach}
+ */
+static DECLCALLBACK(void) hdaR3Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
 {
     PHDASTATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
     PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3);
-
-    DEVHDA_LOCK_RETURN(pDevIns, pThis, VERR_IGNORED);
-
-    LogFunc(("uLUN=%u, fFlags=0x%x\n", uLUN, fFlags));
+    RT_NOREF(fFlags);
+    LogFunc(("iLUN=%u, fFlags=%#x\n", iLUN, fFlags));
+
+    DEVHDA_LOCK(pDevIns, pThis);
 
     PHDADRIVER pDrv;
-    int rc2 = hdaR3AttachInternal(pDevIns, pThis, pThisCC, uLUN, fFlags, &pDrv);
-    if (RT_SUCCESS(rc2))
-        rc2 = hdaR3MixerAddDrv(pDevIns, pThisCC, pDrv);
-
-    if (RT_FAILURE(rc2))
-        LogFunc(("Failed with %Rrc\n", rc2));
+    RTListForEach(&pThisCC->lstDrv, pDrv, HDADRIVER, Node)
+    {
+        if (pDrv->uLUN == iLUN)
+        {
+            hdaR3DetachInternal(pDevIns, pThisCC, pDrv);
+            RTMemFree(pDrv);
+            DEVHDA_UNLOCK(pDevIns, pThis);
+            return;
+        }
+    }
 
     DEVHDA_UNLOCK(pDevIns, pThis);
-
-    return VINF_SUCCESS;
-}
-
-
-/**
- * @interface_method_impl{PDMDEVREG,pfnDetach}
- */
-static DECLCALLBACK(void) hdaR3Detach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
-{
-    PHDASTATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PHDASTATE);
-    PHDASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PHDASTATER3);
-
-    DEVHDA_LOCK(pDevIns, pThis);
-
-    LogFunc(("uLUN=%u, fFlags=0x%x\n", uLUN, fFlags));
-
-    PHDADRIVER pDrv, pDrvNext;
-    RTListForEachSafe(&pThisCC->lstDrv, pDrv, pDrvNext, HDADRIVER, Node)
-    {
-        if (pDrv->uLUN == uLUN)
-        {
-            int rc2 = hdaR3DetachInternal(pDevIns, pThisCC, pDrv, fFlags);
-            if (RT_SUCCESS(rc2))
-            {
-                RTMemFree(pDrv);
-                pDrv = NULL;
-            }
-            break;
-        }
-    }
-
-    DEVHDA_UNLOCK(pDevIns, pThis);
+    LogFunc(("LUN#%u was not found\n", iLUN));
 }
 
@@ -4955,5 +4945,5 @@
         AssertBreak(iLun < UINT8_MAX);
         LogFunc(("Trying to attach driver for LUN#%u ...\n", iLun));
-        rc = hdaR3AttachInternal(pDevIns, pThis, pThisCC, iLun, 0 /* fFlags */, NULL /* ppDrv */);
+        rc = hdaR3AttachInternal(pDevIns, pThis, pThisCC, iLun, NULL /* ppDrv */);
         if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
         {
Index: trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 88904)
+++ trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 88905)
@@ -3941,7 +3941,6 @@
      * Attach driver.
      */
-    char *pszDesc;
-    if (RTStrAPrintf(&pszDesc, "Audio driver port (AC'97) for LUN #%u", iLun) <= 0)
-        AssertLogRelFailedReturn(VERR_NO_MEMORY);
+    char *pszDesc = RTStrAPrintf2("Audio driver port (AC'97) for LUN #%u", iLun);
+    AssertLogRelReturn(pszDesc, VERR_NO_STR_MEMORY);
 
     PPDMIBASE pDrvBase;
@@ -3952,28 +3951,35 @@
         if (pDrv)
         {
-            pDrv->pDrvBase   = pDrvBase;
             pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR);
-            AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n", iLun, rc));
-            pDrv->uLUN       = iLun;
-            pDrv->pszDesc    = pszDesc;
-
-            /*
-             * For now we always set the driver at LUN 0 as our primary
-             * host backend. This might change in the future.
-             */
-            if (iLun == 0)
-                pDrv->fFlags |= PDMAUDIODRVFLAGS_PRIMARY;
-
-            LogFunc(("LUN#%u: pCon=%p, drvFlags=0x%x\n", iLun, pDrv->pConnector, pDrv->fFlags));
-
-            /* Attach to driver list if not attached yet. */
-            if (!pDrv->fAttached)
+            AssertPtr(pDrv->pConnector);
+            if (pDrv->pConnector)
             {
-                RTListAppend(&pThisCC->lstDrv, &pDrv->Node);
-                pDrv->fAttached = true;
+                pDrv->pDrvBase   = pDrvBase;
+                pDrv->uLUN       = iLun;
+                pDrv->pszDesc    = pszDesc;
+
+                /*
+                 * For now we always set the driver at LUN 0 as our primary
+                 * host backend. This might change in the future.
+                 */
+                if (iLun == 0)
+                    pDrv->fFlags |= PDMAUDIODRVFLAGS_PRIMARY;
+
+                LogFunc(("LUN#%u: pCon=%p, drvFlags=0x%x\n", iLun, pDrv->pConnector, pDrv->fFlags));
+
+                /* Attach to driver list if not attached yet. */
+                if (!pDrv->fAttached)
+                {
+                    RTListAppend(&pThisCC->lstDrv, &pDrv->Node);
+                    pDrv->fAttached = true;
+                }
+
+                if (ppDrv)
+                    *ppDrv = pDrv;
+                LogFunc(("iLun=%u, fFlags=0x%x: VINF_SUCCESS\n", iLun, fFlags));
+                return VINF_SUCCESS;
             }
-
-            if (ppDrv)
-                *ppDrv = pDrv;
+            RTMemFree(pDrv);
+            rc = VERR_PDM_MISSING_INTERFACE_BELOW;
         }
         else
@@ -3982,32 +3988,50 @@
     else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
         LogFunc(("No attached driver for LUN #%u\n", iLun));
-
-    if (RT_FAILURE(rc))
-    {
-        /* Only free this string on failure;
-         * must remain valid for the live of the driver instance. */
-        RTStrFree(pszDesc);
-    }
-
-    LogFunc(("iLun=%u, fFlags=0x%x, rc=%Rrc\n", iLun, fFlags, rc));
+    else
+        LogFunc(("Attached driver for LUN #%u failed: %Rrc\n", iLun, rc));
+
+    RTStrFree(pszDesc);
+    LogFunc(("iLun=%u, fFlags=0x%x: rc=%Rrc\n", iLun, fFlags, rc));
     return rc;
 }
 
 /**
- * Detach command, internal version.
+ * @interface_method_impl{PDMDEVREGR3,pfnAttach}
+ */
+static DECLCALLBACK(int) ichac97R3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
+{
+    PAC97STATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
+    PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
+
+    LogFunc(("iLUN=%u, fFlags=0x%x\n", iLUN, fFlags));
+
+    DEVAC97_LOCK(pDevIns, pThis);
+
+    PAC97DRIVER pDrv;
+    int rc = ichac97R3AttachInternal(pDevIns, pThisCC, iLUN, fFlags, &pDrv);
+    if (RT_SUCCESS(rc))
+    {
+        int rc2 = ichac97R3MixerAddDrv(pDevIns, pThisCC, pDrv);
+        if (RT_FAILURE(rc2))
+            LogFunc(("ichac97R3MixerAddDrv failed with %Rrc (ignored)\n", rc2));
+    }
+
+    DEVAC97_UNLOCK(pDevIns, pThis);
+
+    return rc;
+}
+
+/**
+ * Worker for ichac97R3Detach that does all but freeing the pDrv structure.
  *
  * This is called to let the device detach from a driver for a specified LUN
- * during runtime.
- *
- * @returns VBox status code.
+ * at runtime.
+ *
  * @param   pDevIns     The device instance.
  * @param   pThisCC     The ring-3 AC'97 device state.
  * @param   pDrv        Driver to detach from device.
- * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
- */
-static int ichac97R3DetachInternal(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, PAC97DRIVER pDrv, uint32_t fFlags)
-{
-    RT_NOREF(fFlags);
-
+ */
+static void ichac97R3DetachInternal(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, PAC97DRIVER pDrv)
+{
     /* First, remove the driver from our list and destory it's associated streams.
      * This also will un-set the driver as a recording source (if associated). */
@@ -4049,15 +4073,15 @@
     }
 
-    LogFunc(("uLUN=%u, fFlags=0x%x\n", pDrv->uLUN, fFlags));
-    return VINF_SUCCESS;
-}
-
-/**
- * @interface_method_impl{PDMDEVREGR3,pfnAttach}
- */
-static DECLCALLBACK(int) ichac97R3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
+    LogFunc(("Detached LUN#%u\n", pDrv->uLUN));
+}
+
+/**
+ * @interface_method_impl{PDMDEVREG,pfnDetach}
+ */
+static DECLCALLBACK(void) ichac97R3Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
 {
     PAC97STATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
     PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
+    RT_NOREF(fFlags);
 
     LogFunc(("iLUN=%u, fFlags=0x%x\n", iLUN, fFlags));
@@ -4066,46 +4090,18 @@
 
     PAC97DRIVER pDrv;
-    int rc2 = ichac97R3AttachInternal(pDevIns, pThisCC, iLUN, fFlags, &pDrv);
-    if (RT_SUCCESS(rc2))
-        rc2 = ichac97R3MixerAddDrv(pDevIns, pThisCC, pDrv);
-
-    if (RT_FAILURE(rc2))
-        LogFunc(("Failed with %Rrc\n", rc2));
+    RTListForEach(&pThisCC->lstDrv, pDrv, AC97DRIVER, Node)
+    {
+        if (pDrv->uLUN == iLUN)
+        {
+            ichac97R3DetachInternal(pDevIns, pThisCC, pDrv);
+            RTStrFree(pDrv->pszDesc);
+            RTMemFree(pDrv);
+            DEVAC97_UNLOCK(pDevIns, pThis);
+            return;
+        }
+    }
 
     DEVAC97_UNLOCK(pDevIns, pThis);
-
-    return VINF_SUCCESS;
-}
-
-/**
- * @interface_method_impl{PDMDEVREG,pfnDetach}
- */
-static DECLCALLBACK(void) ichac97R3Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
-{
-    PAC97STATE   pThis   = PDMDEVINS_2_DATA(pDevIns, PAC97STATE);
-    PAC97STATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PAC97STATER3);
-
-    LogFunc(("iLUN=%u, fFlags=0x%x\n", iLUN, fFlags));
-
-    DEVAC97_LOCK(pDevIns, pThis);
-
-    PAC97DRIVER pDrv, pDrvNext;
-    RTListForEachSafe(&pThisCC->lstDrv, pDrv, pDrvNext, AC97DRIVER, Node)
-    {
-        if (pDrv->uLUN == iLUN)
-        {
-            int rc2 = ichac97R3DetachInternal(pDevIns, pThisCC, pDrv, fFlags);
-            if (RT_SUCCESS(rc2))
-            {
-                RTStrFree(pDrv->pszDesc);
-                RTMemFree(pDrv);
-                pDrv = NULL;
-            }
-
-            break;
-        }
-    }
-
-    DEVAC97_UNLOCK(pDevIns, pThis);
+    LogFunc(("LUN#%u was not found\n", iLUN));
 }
 
Index: trunk/src/VBox/Devices/Audio/DevSB16.cpp
===================================================================
--- trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 88904)
+++ trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 88905)
@@ -1934,5 +1934,5 @@
 
 /*********************************************************************************************************************************
-*   Driver handling                                                                                                              *
+*   LUN (driver) management                                                                                                      *
 *********************************************************************************************************************************/
 
@@ -1950,8 +1950,7 @@
 
     if (enmDir == PDMAUDIODIR_IN)
-    {
         return NULL; /** @todo Recording not implemented yet. */
-    }
-    else if (enmDir == PDMAUDIODIR_OUT)
+
+    if (enmDir == PDMAUDIODIR_OUT)
     {
         LogFunc(("enmDst=%RU32\n", dstSrc.enmDst));
@@ -2124,6 +2123,6 @@
         if (AudioHlpStreamCfgIsValid(&pThis->aStreams[i].Cfg))
         {
-            int rc2 = sb16AddDrvStream(pDevIns,
-                                       sb16StreamIndexToSink(pThis, pThis->aStreams[i].uIdx), &pThis->aStreams[i].Cfg, pDrv);
+            int rc2 = sb16AddDrvStream(pDevIns, sb16StreamIndexToSink(pThis, pThis->aStreams[i].uIdx),
+                                       &pThis->aStreams[i].Cfg, pDrv);
             if (RT_SUCCESS(rc))
                 rc = rc2;
@@ -2137,4 +2136,6 @@
  * Removes a specific SB16 driver from the driver chain and destroys its
  * associated streams.
+ *
+ * This is only used by sb16Detach.
  *
  * @param   pDevIns     The device instance.
@@ -2866,5 +2867,5 @@
 
     /*
-     * Attach driver.
+     * Allocate a new driver structure and try attach the driver.
      */
     PSB16DRIVER pDrv = (PSB16DRIVER)RTMemAllocZ(sizeof(SB16DRIVER));
@@ -2876,84 +2877,66 @@
     if (RT_SUCCESS(rc))
     {
-        pDrv->pDrvBase   = pDrvBase;
         pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR);
-        AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n", uLUN, rc));
-        pDrv->pSB16State = pThis;
-        pDrv->uLUN       = uLUN;
-
-        /*
-         * For now we always set the driver at LUN 0 as our primary
-         * host backend. This might change in the future.
-         */
-        if (pDrv->uLUN == 0)
-            pDrv->fFlags |= PDMAUDIODRVFLAGS_PRIMARY;
-
-        LogFunc(("LUN#%u: pCon=%p, drvFlags=0x%x\n", uLUN, pDrv->pConnector, pDrv->fFlags));
-
-        /* Attach to driver list if not attached yet. */
-        if (!pDrv->fAttached)
+        AssertPtr(pDrv->pConnector);
+        if (RT_VALID_PTR(pDrv->pConnector))
         {
-            RTListAppend(&pThis->lstDrv, &pDrv->Node);
-            pDrv->fAttached = true;
+            pDrv->pDrvBase   = pDrvBase;
+            pDrv->pSB16State = pThis;
+            pDrv->uLUN       = uLUN;
+
+            /*
+             * For now we always set the driver at LUN 0 as our primary
+             * host backend. This might change in the future.
+             */
+            if (pDrv->uLUN == 0)
+                pDrv->fFlags |= PDMAUDIODRVFLAGS_PRIMARY;
+
+            LogFunc(("LUN#%u: pCon=%p, drvFlags=0x%x\n", uLUN, pDrv->pConnector, pDrv->fFlags));
+
+            /* Attach to driver list if not attached yet. */
+            if (!pDrv->fAttached)
+            {
+                RTListAppend(&pThis->lstDrv, &pDrv->Node);
+                pDrv->fAttached = true;
+            }
+
+            if (ppDrv)
+                *ppDrv = pDrv;
+            LogFunc(("iLUN=%u, fFlags=0x%x: VINF_SUCCESS\n", uLUN, fFlags));
+            return VINF_SUCCESS;
         }
-
-        if (ppDrv)
-            *ppDrv = pDrv;
-    }
+        rc = VERR_PDM_MISSING_INTERFACE_BELOW;
+    }
+    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
+        LogFunc(("No attached driver for LUN #%u\n", uLUN));
     else
-    {
-        if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
-            LogFunc(("No attached driver for LUN #%u\n", uLUN));
-        RTMemFree(pDrv);
-    }
-
-    LogFunc(("iLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
+        LogFunc(("Failed to attached driver for LUN #%u: %Rrc\n", uLUN, rc));
+    RTMemFree(pDrv);
+
+    LogFunc(("iLUN=%u, fFlags=0x%x: rc=%Rrc\n", uLUN, fFlags, rc));
     return rc;
 }
 
 /**
- * Detach command, internal version.
- *
- * This is called to let the device detach from a driver for a specified LUN
- * during runtime.
- *
- * @returns VBox status code.
- * @param   pDevIns     The device instance.
- * @param   pThis       The SB16 device state.
- * @param   pDrv        Driver to detach from device.
- * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
- */
-static int sb16DetachInternal(PPDMDEVINS pDevIns, PSB16STATE pThis, PSB16DRIVER pDrv, uint32_t fFlags)
-{
-    RT_NOREF(fFlags);
+ * @interface_method_impl{PDMDEVREG,pfnAttach}
+ */
+static DECLCALLBACK(int) sb16Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
+{
+    PSB16STATE pThis = PDMDEVINS_2_DATA(pDevIns, PSB16STATE);
+
+    LogFunc(("iLUN=%u, fFlags=0x%x\n", iLUN, fFlags));
 
     /** @todo r=andy Any locking required here? */
 
-    sb16RemoveDrv(pDevIns, pThis, pDrv);
-
-    LogFunc(("uLUN=%u, fFlags=0x%x\n", pDrv->uLUN, fFlags));
-    return VINF_SUCCESS;
-}
-
-/**
- * @interface_method_impl{PDMDEVREG,pfnAttach}
- */
-static DECLCALLBACK(int) sb16Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
-{
-    PSB16STATE pThis = PDMDEVINS_2_DATA(pDevIns, PSB16STATE);
-
-    LogFunc(("iLUN=%u, fFlags=0x%x\n", iLUN, fFlags));
-
-    /** @todo r=andy Any locking required here? */
-
     PSB16DRIVER pDrv;
-    int rc2 = sb16AttachInternal(pThis, iLUN, fFlags, &pDrv);
-    if (RT_SUCCESS(rc2))
-        rc2 = sb16AddDrv(pDevIns, pThis, pDrv);
-
-    if (RT_FAILURE(rc2))
-        LogFunc(("Failed with %Rrc\n", rc2));
-
-    return VINF_SUCCESS;
+    int rc = sb16AttachInternal(pThis, iLUN, fFlags, &pDrv);
+    if (RT_SUCCESS(rc))
+    {
+        int rc2 = sb16AddDrv(pDevIns, pThis, pDrv);
+        if (RT_FAILURE(rc2))
+            LogFunc(("sb16AddDrv failed with %Rrc (ignored)\n", rc2));
+    }
+
+    return rc;
 }
 
@@ -2968,18 +2951,15 @@
     LogFunc(("iLUN=%u, fFlags=0x%x\n", iLUN, fFlags));
 
-    PSB16DRIVER pDrv, pDrvNext;
-    RTListForEachSafe(&pThis->lstDrv, pDrv, pDrvNext, SB16DRIVER, Node)
+    PSB16DRIVER pDrv;
+    RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
     {
         if (pDrv->uLUN == iLUN)
         {
-            int rc2 = sb16DetachInternal(pDevIns, pThis, pDrv, fFlags);
-            if (RT_SUCCESS(rc2))
-            {
-                RTMemFree(pDrv);
-                pDrv = NULL;
-            }
-            break;
+            sb16RemoveDrv(pDevIns, pThis, pDrv);
+            RTMemFree(pDrv);
+            return;
         }
     }
+    LogFunc(("LUN#%u was not found\n", iLUN));
 }
 
