Index: /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 59356)
+++ /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 59357)
@@ -314,5 +314,7 @@
     /** LUN # to which this driver has been assigned. */
     uint8_t                            uLUN;
-    uint8_t                            Padding[5];
+    /** Whether this driver is in an attached state or not. */
+    bool                               fAttached;
+    uint8_t                            Padding[4];
     /** Pointer to attached driver base interface. */
     R3PTRTYPE(PPDMIBASE)               pDrvBase;
@@ -2175,16 +2177,19 @@
 
 /**
- * Attach command.
+ * 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 have to attach to all the available drivers.
+ * constructor has to attach to all the available drivers.
  *
  * @returns VBox status code.
  * @param   pDevIns     The device instance.
+ * @param   pDrv        Driver to (re-)use for (re-)attaching to.
+ *                      If NULL is specified, a new driver will be created and appended
+ *                      to the driver list.
  * @param   uLUN        The logical unit which is being detached.
  * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
  */
-static DECLCALLBACK(int) ichac97Attach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
+static DECLCALLBACK(int) ichac97AttachInternal(PPDMDEVINS pDevIns, PAC97DRIVER pDrv, unsigned uLUN, uint32_t fFlags)
 {
     PAC97STATE pThis = PDMINS_2_DATA(pDevIns, PAC97STATE);
@@ -2204,5 +2209,6 @@
     if (RT_SUCCESS(rc))
     {
-        PAC97DRIVER pDrv = (PAC97DRIVER)RTMemAllocZ(sizeof(AC97DRIVER));
+        if (pDrv == NULL)
+            pDrv = (PAC97DRIVER)RTMemAllocZ(sizeof(AC97DRIVER));
         if (pDrv)
         {
@@ -2222,6 +2228,10 @@
             LogFunc(("LUN#%RU8: pCon=%p, drvFlags=0x%x\n", uLUN, pDrv->pConnector, pDrv->Flags));
 
-            /* Attach to driver list. */
-            RTListAppend(&pThis->lstDrv, &pDrv->Node);
+            /* Attach to driver list if not attached yet. */
+            if (!pDrv->fAttached)
+            {
+                RTListAppend(&pThis->lstDrv, &pDrv->Node);
+                pDrv->fAttached = true;
+            }
         }
         else
@@ -2245,4 +2255,22 @@
     LogFunc(("iLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
     return rc;
+}
+
+
+/**
+ * Attach command.
+ *
+ * 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.
+ *
+ * @returns VBox status code.
+ * @param   pDevIns     The device instance.
+ * @param   uLUN        The logical unit which is being detached.
+ * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
+ */
+static DECLCALLBACK(int) ichac97Attach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
+{
+    return ichac97AttachInternal(pDevIns, NULL /* pDrv */, uLUN, fFlags);
 }
 
@@ -2289,5 +2317,5 @@
 
     if (RT_SUCCESS(rc))
-        rc = ichac97Attach(pThis->pDevInsR3, pDrv->uLUN, 0 /* fFlags */);
+        rc = ichac97AttachInternal(pThis->pDevInsR3, pDrv, pDrv->uLUN, 0 /* fFlags */);
 
     LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, pDrv->uLUN, pszDriver, rc));
@@ -2423,5 +2451,5 @@
     {
         LogFunc(("Trying to attach driver for LUN #%RU8 ...\n", uLUN));
-        rc = ichac97Attach(pDevIns, uLUN, 0 /* fFlags */);
+        rc = ichac97AttachInternal(pDevIns, NULL /* pDrv */, uLUN, 0 /* fFlags */);
         if (RT_FAILURE(rc))
         {
@@ -2511,9 +2539,9 @@
             else if (cFailed)
             {
-                if (!pDrv->pConnector->pfnIsValidIn (pDrv->pConnector, pDrv->LineIn.pStrmIn))
+                if (!pDrv->pConnector->pfnIsValidIn (pCon, pDrv->LineIn.pStrmIn))
                     LogRel(("AC97: WARNING: Unable to open PCM line input for LUN #%RU32!\n",       pDrv->uLUN));
-                if (!pDrv->pConnector->pfnIsValidIn (pDrv->pConnector, pDrv->MicIn.pStrmIn))
+                if (!pDrv->pConnector->pfnIsValidIn (pCon, pDrv->MicIn.pStrmIn))
                     LogRel(("AC97: WARNING: Unable to open PCM microphone input for LUN #%RU32!\n", pDrv->uLUN));
-                if (!pDrv->pConnector->pfnIsValidOut(pDrv->pConnector, pDrv->Out.pStrmOut))
+                if (!pDrv->pConnector->pfnIsValidOut(pCon, pDrv->Out.pStrmOut))
                     LogRel(("AC97: WARNING: Unable to open PCM output for LUN #%RU32!\n",           pDrv->uLUN));
 
@@ -2573,5 +2601,5 @@
             /* Only register primary driver.
              * The device emulation does the output multiplexing then. */
-            if (pDrv->Flags != PDMAUDIODRVFLAG_PRIMARY)
+            if (!(pDrv->Flags & PDMAUDIODRVFLAG_PRIMARY))
                 continue;
 
Index: /trunk/src/VBox/Devices/Audio/DevIchHda.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchHda.cpp	(revision 59356)
+++ /trunk/src/VBox/Devices/Audio/DevIchHda.cpp	(revision 59357)
@@ -658,4 +658,6 @@
     /** LUN to which this driver has been assigned. */
     uint8_t                            uLUN;
+    /** Whether this driver is in an attached state or not. */
+    bool                               fAttached;
     /** Pointer to attached driver base interface. */
     R3PTRTYPE(PPDMIBASE)               pDrvBase;
@@ -4306,17 +4308,21 @@
 }
 
+
 /**
- * Attach command.
+ * 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 have to attach to all the available drivers.
+ * constructor has to attach to all the available drivers.
  *
  * @returns VBox status code.
  * @param   pDevIns     The device instance.
+ * @param   pDrv        Driver to (re-)use for (re-)attaching to.
+ *                      If NULL is specified, a new driver will be created and appended
+ *                      to the driver list.
  * @param   uLUN        The logical unit which is being detached.
  * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
  */
-static DECLCALLBACK(int) hdaAttach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
+static int hdaAttachInternal(PPDMDEVINS pDevIns, PHDADRIVER pDrv, unsigned uLUN, uint32_t fFlags)
 {
     PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE);
@@ -4336,5 +4342,6 @@
     if (RT_SUCCESS(rc))
     {
-        PHDADRIVER pDrv = (PHDADRIVER)RTMemAllocZ(sizeof(HDADRIVER));
+        if (pDrv == NULL)
+            pDrv = (PHDADRIVER)RTMemAllocZ(sizeof(HDADRIVER));
         if (pDrv)
         {
@@ -4354,6 +4361,10 @@
             LogFunc(("LUN#%u: pCon=%p, drvFlags=0x%x\n", uLUN, pDrv->pConnector, pDrv->Flags));
 
-            /* Attach to driver list. */
-            RTListAppend(&pThis->lstDrv, &pDrv->Node);
+            /* Attach to driver list if not attached yet. */
+            if (!pDrv->fAttached)
+            {
+                RTListAppend(&pThis->lstDrv, &pDrv->Node);
+                pDrv->fAttached = true;
+            }
         }
         else
@@ -4377,4 +4388,21 @@
     LogFunc(("uLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
     return rc;
+}
+
+/**
+ * Attach command.
+ *
+ * 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.
+ *
+ * @returns VBox status code.
+ * @param   pDevIns     The device instance.
+ * @param   uLUN        The logical unit which is being detached.
+ * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
+ */
+static DECLCALLBACK(int) hdaAttach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
+{
+    return hdaAttachInternal(pDevIns, NULL /* pDrv */, uLUN, fFlags);
 }
 
@@ -4421,5 +4449,5 @@
 
     if (RT_SUCCESS(rc))
-        rc = hdaAttach(pThis->pDevInsR3, pDrv->uLUN, 0 /* fFlags */);
+        rc = hdaAttachInternal(pThis->pDevInsR3, pDrv, pDrv->uLUN, 0 /* fFlags */);
 
     LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, pDrv->uLUN, pszDriver, rc));
@@ -4585,5 +4613,5 @@
     {
         LogFunc(("Trying to attach driver for LUN #%RU32 ...\n", uLUN));
-        rc = hdaAttach(pDevIns, uLUN, 0 /* fFlags */);
+        rc = hdaAttachInternal(pDevIns, NULL /* pDrv */, uLUN, 0 /* fFlags */);
         if (RT_FAILURE(rc))
         {
Index: /trunk/src/VBox/Devices/Audio/DevSB16.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 59356)
+++ /trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 59357)
@@ -97,5 +97,7 @@
     /** LUN # to which this driver has been assigned. */
     uint8_t                            uLUN;
-    uint8_t                            Padding[5];
+    /** Whether this driver is in an attached state or not. */
+    bool                               fAttached;
+    uint8_t                            Padding[4];
     /** Pointer to attached driver base interface. */
     R3PTRTYPE(PPDMIBASE)               pDrvBase;
@@ -192,16 +194,19 @@
 
 /**
- * Attach command.
+ * 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 have to attach to all the available drivers.
+ * constructor has to attach to all the available drivers.
  *
  * @returns VBox status code.
  * @param   pDevIns     The device instance.
+ * @param   pDrv        Driver to (re-)use for (re-)attaching to.
+ *                      If NULL is specified, a new driver will be created and appended
+ *                      to the driver list.
  * @param   uLUN        The logical unit which is being detached.
  * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
  */
-static DECLCALLBACK(int) sb16Attach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
+static DECLCALLBACK(int) sb16AttachInternal(PPDMDEVINS pDevIns, PSB16DRIVER pDrv, unsigned uLUN, uint32_t fFlags)
 {
     PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE);
@@ -221,5 +226,6 @@
     if (RT_SUCCESS(rc))
     {
-        PSB16DRIVER pDrv = (PSB16DRIVER)RTMemAllocZ(sizeof(SB16DRIVER));
+        if (pDrv == NULL)
+            pDrv = (PSB16DRIVER)RTMemAllocZ(sizeof(SB16DRIVER));
         if (pDrv)
         {
@@ -239,6 +245,10 @@
             LogFunc(("LUN#%RU8: pCon=%p, drvFlags=0x%x\n", uLUN, pDrv->pConnector, pDrv->Flags));
 
-            /* Attach to driver list. */
-            RTListAppend(&pThis->lstDrv, &pDrv->Node);
+            /* Attach to driver list if not attached yet. */
+            if (!pDrv->fAttached)
+            {
+                RTListAppend(&pThis->lstDrv, &pDrv->Node);
+                pDrv->fAttached = true;
+            }
         }
         else
@@ -262,4 +272,21 @@
     LogFunc(("iLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));
     return rc;
+}
+
+/**
+ * Attach command.
+ *
+ * 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.
+ *
+ * @returns VBox status code.
+ * @param   pDevIns     The device instance.
+ * @param   uLUN        The logical unit which is being detached.
+ * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
+ */
+static DECLCALLBACK(int) sb16Attach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)
+{
+    return sb16AttachInternal(pDevIns, NULL /* pDrv */, uLUN, fFlags);
 }
 
@@ -306,5 +333,5 @@
 
     if (RT_SUCCESS(rc))
-        rc = sb16Attach(pThis->pDevInsR3, pDrv->uLUN, 0 /* fFlags */);
+        rc = sb16AttachInternal(pThis->pDevInsR3, pDrv, pDrv->uLUN, 0 /* fFlags */);
 
     LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, pDrv->uLUN, pszDriver, rc));
@@ -2241,5 +2268,5 @@
     {
         LogFunc(("Trying to attach driver for LUN #%RU8 ...\n", uLUN));
-        rc = sb16Attach(pDevIns, uLUN, 0 /* fFlags */);
+        rc = sb16AttachInternal(pDevIns, NULL /* pDrv */, uLUN, 0 /* fFlags */);
         if (RT_FAILURE(rc))
         {
Index: /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
===================================================================
--- /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 59356)
+++ /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 59357)
@@ -1849,4 +1849,5 @@
     GEN_CHECK_OFF(AC97DRIVER, Flags);
     GEN_CHECK_OFF(AC97DRIVER, uLUN);
+    GEN_CHECK_OFF(AC97DRIVER, fAttached);
     GEN_CHECK_OFF(AC97DRIVER, pConnector);
     GEN_CHECK_OFF(AC97DRIVER, LineIn);
@@ -1867,4 +1868,5 @@
     GEN_CHECK_OFF(HDADRIVER, Flags);
     GEN_CHECK_OFF(HDADRIVER, uLUN);
+    GEN_CHECK_OFF(HDADRIVER, fAttached);
     GEN_CHECK_OFF(HDADRIVER, pConnector);
     GEN_CHECK_OFF(HDADRIVER, LineIn);
