Index: /trunk/src/VBox/Devices/Storage/ATAController.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/ATAController.cpp	(revision 29757)
+++ /trunk/src/VBox/Devices/Storage/ATAController.cpp	(revision 29758)
@@ -4965,5 +4965,4 @@
 }
 
-#if 0
 /**
  * Detach notification.
@@ -4972,23 +4971,15 @@
  *
  * @param   pDevIns     The device instance.
- * @param   iLUN        The logical unit which is being detached.
+ * @param   fMaster     True if the master is detached
+ *                      false for the slave
  */
-static DECLCALLBACK(void) ataDetach(PPDMDEVINS pDevIns, unsigned iLUN)
-{
-    PCIATAState    *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
-    PAHCIATACONTROLLER  pCtl;
+void ataControllerDetach(PAHCIATACONTROLLER pCtl, bool fMaster)
+{
     AHCIATADevState    *pIf;
-    unsigned        iController;
-    unsigned        iInterface;
 
     /*
      * Locate the controller and stuff.
      */
-    iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
-    AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
-    pCtl = &pThis->aCts[iController];
-
-    iInterface  = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
-    pIf = &pCtl->aIfs[iInterface];
+    pIf = &pCtl->aIfs[fMaster ? 0 : 1];
 
     /*
@@ -4999,14 +4990,5 @@
     pIf->pDrvBlockBios = NULL;
     pIf->pDrvMount = NULL;
-
-    /*
-     * Just in case there was a medium inserted. Only required when attached to a physical drive
-     * in passthrough mode as in virtual ATAPI mode we've got an unmount notification.
-     */
-    if (pIf->fATAPIPassthrough)
-        ataMediumRemoved(pIf);
-
-}
-#endif
+}
 
 /**
@@ -5139,5 +5121,4 @@
 }
 
-#if 0
 /**
  * Attach command.
@@ -5149,22 +5130,13 @@
  * @param   iLUN        The logical unit which is being detached.
  */
-static DECLCALLBACK(int)  ataAttach(PPDMDEVINS pDevIns, unsigned iLUN)
-{
-    PCIATAState    *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
-    PAHCIATACONTROLLER  pCtl;
+int  ataControllerAttach(PAHCIATACONTROLLER pCtl, PPDMIBASE pDrvBase, bool fMaster)
+{
     AHCIATADevState    *pIf;
     int             rc;
-    unsigned        iController;
-    unsigned        iInterface;
 
     /*
      * Locate the controller and stuff.
      */
-    iController = iLUN / RT_ELEMENTS(pThis->aCts[0].aIfs);
-    AssertReleaseMsg(iController < RT_ELEMENTS(pThis->aCts), ("iController=%d iLUN=%d\n", iController, iLUN));
-    pCtl = &pThis->aCts[iController];
-
-    iInterface  = iLUN % RT_ELEMENTS(pThis->aCts[0].aIfs);
-    pIf = &pCtl->aIfs[iInterface];
+    pIf = &pCtl->aIfs[fMaster ? 0 : 1];
 
     /* the usual paranoia */
@@ -5172,5 +5144,4 @@
     AssertRelease(!pIf->pDrvBlock);
     Assert(ATADEVSTATE_2_CONTROLLER(pIf) == pCtl);
-    Assert(pIf->iLUN == iLUN);
 
     /*
@@ -5178,14 +5149,9 @@
      * required as well as optional.
      */
-    rc = PDMDevHlpDriverAttach(pDevIns, pIf->iLUN, &pIf->IBase, &pIf->pDrvBase, NULL);
-    if (RT_SUCCESS(rc))
-    {
-        rc = ataConfigLun(pDevIns, pIf);
-        /*
-         * In case there is a new medium inserted. In virtual ATAPI mode we get an mount
-         * notification.
-         */
-        if (pIf->fATAPIPassthrough)
-            ataMediumInserted(pIf);
+    
+    pIf->pDrvBase = pDrvBase;
+    if (pDrvBase)
+    {
+        rc = ataConfigLun(pCtl->pDevInsR3, pIf);
     }
     else
@@ -5199,5 +5165,4 @@
     return rc;
 }
-#endif
 
 
@@ -5466,5 +5431,7 @@
 }
 
-DECLCALLBACK(int) ataControllerInit(PPDMDEVINS pDevIns, PAHCIATACONTROLLER pCtl, PPDMIBASE pDrvBaseMaster, PPDMIBASE pDrvBaseSlave,
+DECLCALLBACK(int) ataControllerInit(PPDMDEVINS pDevIns, PAHCIATACONTROLLER pCtl,
+                                    unsigned iLUNMaster, PPDMIBASE pDrvBaseMaster,
+                                    unsigned iLUNSlave, PPDMIBASE pDrvBaseSlave,
                                     uint32_t *pcbSSMState, const char *szName, PPDMLED pLed,
                                     PSTAMCOUNTER pStatBytesRead, PSTAMCOUNTER pStatBytesWritten)
@@ -5484,5 +5451,5 @@
     for (uint32_t j = 0; j < RT_ELEMENTS(pCtl->aIfs); j++)
     {
-        pCtl->aIfs[j].iLUN              = j;
+        pCtl->aIfs[j].iLUN              = j == 0 ? iLUNMaster : iLUNSlave;
         pCtl->aIfs[j].pDevInsR3         = pDevIns;
         pCtl->aIfs[j].pDevInsR0         = PDMDEVINS_2_R0PTR(pDevIns);
Index: /trunk/src/VBox/Devices/Storage/ATAController.h
===================================================================
--- /trunk/src/VBox/Devices/Storage/ATAController.h	(revision 29757)
+++ /trunk/src/VBox/Devices/Storage/ATAController.h	(revision 29758)
@@ -420,5 +420,7 @@
  * @param   szName         Name of the controller (Used to initialize the critical section).
  */
-int ataControllerInit(PPDMDEVINS pDevIns, PAHCIATACONTROLLER pCtl, PPDMIBASE pDrvBaseMaster, PPDMIBASE pDrvBaseSlave,
+int ataControllerInit(PPDMDEVINS pDevIns, PAHCIATACONTROLLER pCtl,
+                      unsigned iLUNMaster, PPDMIBASE pDrvBaseMaster,
+                      unsigned iLUNSlave, PPDMIBASE pDrvBaseSlave,
                       uint32_t *pcbSSMState, const char *szName, PPDMLED pLed, PSTAMCOUNTER pStatBytesRead, PSTAMCOUNTER pStatBytesWritten);
 
@@ -483,4 +485,26 @@
 int ataControllerLoadExec(PAHCIATACONTROLLER pCtl, PSSMHANDLE pSSM);
 
+/**
+ * Attach command.
+ *
+ * This is called when we change block driver for the DVD drive.
+ *
+ * @returns VBox status code.
+ * @param   pDevIns     The device instance.
+ * @param   iLUN        The logical unit which is being detached.
+ */
+int  ataControllerAttach(PAHCIATACONTROLLER pCtl, PPDMIBASE pDrvBase, bool fMaster);
+
+/**
+ * Detach notification.
+ *
+ * The DVD drive has been unplugged.
+ *
+ * @param   pDevIns     The device instance.
+ * @param   fMaster     True if the master is detached
+ *                      false for the slave
+ */
+void ataControllerDetach(PAHCIATACONTROLLER pCtl, bool fMaster);
+
 #endif /* IN_RING3 */
 
Index: /trunk/src/VBox/Devices/Storage/DevAHCI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevAHCI.cpp	(revision 29757)
+++ /trunk/src/VBox/Devices/Storage/DevAHCI.cpp	(revision 29758)
@@ -6545,4 +6545,22 @@
     }
 
+    /* Check if the changed port uses IDE emulation. */
+    bool fMaster = false;
+    PAHCIATACONTROLLER pCtl = NULL;
+
+    for (unsigned i = 0; i < RT_ELEMENTS(pAhci->aCts); i++)
+        for (unsigned j = 0; j < RT_ELEMENTS(pAhci->aCts[0].aIfs); j++)
+        {
+            PAHCIATACONTROLLER pTmp = &pAhci->aCts[i];
+            if (pTmp->aIfs[j].iLUN == iLUN)
+            {
+                pCtl = pTmp;
+                fMaster = j == 0 ? true : false;
+            }
+        }
+
+    if (pCtl)
+        ataControllerDetach(pCtl, fMaster);
+
     /*
      * Zero some important members.
@@ -6597,30 +6615,52 @@
     else
     {
-        char szName[24];
-        RTStrPrintf(szName, sizeof(szName), "Port%d", iLUN);
-
-        if (pAhciPort->pDrvBlockAsync)
-        {
-            pAhciPort->fAsyncInterface = true;
-        }
-        else
-        {
-            pAhciPort->fAsyncInterface = false;
-
-            /* Create event semaphore. */
-            rc = RTSemEventCreate(&pAhciPort->AsyncIORequestSem);
-            if (RT_FAILURE(rc))
+        /* Check if the changed port uses IDE emulation. */
+        bool fMaster = false;
+        PAHCIATACONTROLLER pCtl = NULL;
+
+        for (unsigned i = 0; i < RT_ELEMENTS(pAhci->aCts); i++)
+            for (unsigned j = 0; j < RT_ELEMENTS(pAhci->aCts[0].aIfs); j++)
             {
-                Log(("%s: Failed to create event semaphore for %s.\n", __FUNCTION__, szName));
-                return rc;
+                PAHCIATACONTROLLER pTmp = &pAhci->aCts[i];
+                if (pTmp->aIfs[j].iLUN == iLUN)
+                {
+                    pCtl = pTmp;
+                    fMaster = j == 0 ? true : false;
+                }
             }
 
-            /* Create the async IO thread. */
-            rc = PDMDevHlpThreadCreate(pDevIns, &pAhciPort->pAsyncIOThread, pAhciPort, ahciAsyncIOLoop, ahciAsyncIOLoopWakeUp, 0,
-                                       RTTHREADTYPE_IO, szName);
-            if (RT_FAILURE(rc))
+        /* Attach to the controller if available */
+        if (pCtl)
+            rc = ataControllerAttach(pCtl, pAhciPort->pDrvBase, fMaster);
+
+        if (RT_SUCCESS(rc))
+        {
+            if (pAhciPort->pDrvBlockAsync)
             {
-                AssertMsgFailed(("%s: Async IO Thread creation for %s failed rc=%d\n", __FUNCTION__, szName, rc));
-                return rc;
+                pAhciPort->fAsyncInterface = true;
+            }
+            else
+            {
+                char szName[24];
+                RTStrPrintf(szName, sizeof(szName), "Port%d", iLUN);
+
+                pAhciPort->fAsyncInterface = false;
+
+                /* Create event semaphore. */
+                rc = RTSemEventCreate(&pAhciPort->AsyncIORequestSem);
+                if (RT_FAILURE(rc))
+                {
+                    Log(("%s: Failed to create event semaphore for %s.\n", __FUNCTION__, szName));
+                    return rc;
+                }
+
+                /* Create the async IO thread. */
+                rc = PDMDevHlpThreadCreate(pDevIns, &pAhciPort->pAsyncIOThread, pAhciPort, ahciAsyncIOLoop, ahciAsyncIOLoopWakeUp, 0,
+                                           RTTHREADTYPE_IO, szName);
+                if (RT_FAILURE(rc))
+                {
+                    AssertMsgFailed(("%s: Async IO Thread creation for %s failed rc=%d\n", __FUNCTION__, szName, rc));
+                    return rc;
+                }
             }
         }
@@ -7138,6 +7178,9 @@
         char szName[24];
         RTStrPrintf(szName, sizeof(szName), "EmulatedATA%d", i);
-        rc = ataControllerInit(pDevIns, pCtl, pThis->ahciPort[iPortMaster].pDrvBase, pThis->ahciPort[iPortSlave].pDrvBase,
-                               &cbSSMState, szName, &pThis->ahciPort[iPortMaster].Led, &pThis->ahciPort[iPortMaster].StatBytesRead,
+        rc = ataControllerInit(pDevIns, pCtl,
+                               iPortMaster, pThis->ahciPort[iPortMaster].pDrvBase,
+                               iPortSlave, pThis->ahciPort[iPortSlave].pDrvBase,
+                               &cbSSMState, szName, &pThis->ahciPort[iPortMaster].Led,
+                               &pThis->ahciPort[iPortMaster].StatBytesRead,
                                &pThis->ahciPort[iPortMaster].StatBytesWritten);
         if (RT_FAILURE(rc))
