Index: /trunk/include/VBox/pci.h
===================================================================
--- /trunk/include/VBox/pci.h	(revision 41810)
+++ /trunk/include/VBox/pci.h	(revision 41811)
@@ -538,4 +538,9 @@
 } PCIDEVICE;
 
+#ifdef IN_RING3
+int PCIDevPhysRead(PPCIDEVICE pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
+int PCIDevPhysWrite(PPCIDEVICE pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
+#endif
+
 /* @todo: handle extended space access */
 DECLINLINE(void)     PCIDevSetByte(PPCIDEVICE pPciDev, uint32_t uOffset, uint8_t u8Value)
@@ -643,4 +648,14 @@
 {
     return PCIDevGetWord(pPciDev, VBOX_PCI_COMMAND);
+}
+
+/**
+ * Checks if the given PCI device is a bus master.
+ * @returns true if the device is a bus master, false if not.
+ * @param   pPciDev         The PCI device.
+ */
+DECLINLINE(bool) PCIDevIsBusmaster(PPCIDEVICE pPciDev)
+{
+    return (PCIDevGetCommand(pPciDev) & VBOX_PCI_COMMAND_MASTER) != 0;
 }
 
Index: /trunk/src/VBox/Devices/Bus/DevPCI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPCI.cpp	(revision 41810)
+++ /trunk/src/VBox/Devices/Bus/DevPCI.cpp	(revision 41811)
@@ -242,4 +242,51 @@
 
 #ifdef IN_RING3
+/**
+ * Reads data via bus mastering, if enabled. If no bus mastering is available,
+ * this function does nothing and returns VINF_SUCCESS.
+ *
+ * @return  IPRT status code.
+ */
+int PCIDevPhysRead(PPCIDEVICE pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
+{
+    AssertPtrReturn(pPciDev, VERR_INVALID_POINTER);
+    AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
+    AssertReturn(cbRead, VERR_INVALID_PARAMETER);
+
+    if (!PCIDevIsBusmaster(pPciDev))
+    {
+#ifdef DEBUG
+        Log2(("%s: %RU16:%RU16: No bus master (anymore), skipping read %p (%z)\n", __FUNCTION__,
+              PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbRead));
+#endif
+        return VINF_SUCCESS;
+    }
+
+    return PDMDevHlpPhysRead(pPciDev->pDevIns, GCPhys, pvBuf, cbRead);
+}
+
+/**
+ * Writes data via bus mastering, if enabled. If no bus mastering is available,
+ * this function does nothing and returns VINF_SUCCESS.
+ *
+ * @return  IPRT status code.
+ */
+int PCIDevPhysWrite(PPCIDEVICE pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
+{
+    AssertPtrReturn(pPciDev, VERR_INVALID_POINTER);
+    AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
+    AssertReturn(cbWrite, VERR_INVALID_PARAMETER);
+
+    if (!PCIDevIsBusmaster(pPciDev))
+    {
+#ifdef DEBUG
+        Log2(("%s: %RU16:%RU16: No bus master (anymore), skipping write %p (%z)\n", __FUNCTION__,
+              PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbWrite));
+#endif
+        return VINF_SUCCESS;
+    }
+
+    return PDMDevHlpPhysWrite(pPciDev->pDevIns, GCPhys, pvBuf, cbWrite);
+}
 
 static void pci_update_mappings(PCIDevice *d)
@@ -758,5 +805,4 @@
 
 #ifdef IN_RING3
-
 /**
  * Finds a bridge on the bus which contains the destination bus.
Index: /trunk/src/VBox/Devices/Storage/DevATA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevATA.cpp	(revision 41810)
+++ /trunk/src/VBox/Devices/Storage/DevATA.cpp	(revision 41811)
@@ -5013,8 +5013,12 @@
                 Log2(("%s: DMA desc %#010x: addr=%#010x size=%#010x orig_size=%#010x\n", __FUNCTION__,
                        (int)pDesc, pBuffer, cbBuffer, RT_LE2H_U32(DMADesc.cbBuffer) & 0xfffe));
+
+                PCIATAState *pATAState = PDMINS_2_DATA(pDevIns, PCIATAState *);
+                AssertPtr(pATAState);
                 if (uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
-                    PDMDevHlpPhysWrite(pDevIns, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
+                    PCIDevPhysWrite(&pATAState->dev, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
                 else
-                    PDMDevHlpPhysRead(pDevIns, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
+                    PCIDevPhysRead(&pATAState->dev, pBuffer, s->CTX_SUFF(pbIOBuffer) + iIOBufferCur, dmalen);
+
                 iIOBufferCur += dmalen;
                 cbTotalTransfer -= dmalen;
@@ -5739,7 +5743,14 @@
     PCIATAState   *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
     PATACONTROLLER pCtl = &pThis->aCts[i];
-    int rc;
-
-    rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_READ);
+
+    bool fBm = PCIDevIsBusmaster(&pThis->dev);
+#ifdef DEBUG_andy
+    Log2(("%s: Ctl#%d: Bus master = %RTbool\n",
+          __FUNCTION__, ATACONTROLLER_IDX(pCtl), fBm));
+#endif
+    if (!fBm)
+        return VINF_SUCCESS; /** @todo Correct? */
+
+    int rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_READ);
     if (rc != VINF_SUCCESS)
         return rc;
@@ -5773,7 +5784,14 @@
     PCIATAState   *pThis = PDMINS_2_DATA(pDevIns, PCIATAState *);
     PATACONTROLLER pCtl = &pThis->aCts[i];
-    int rc;
-
-    rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_WRITE);
+
+    bool fBm = PCIDevIsBusmaster(&pThis->dev);
+#ifdef DEBUG_andy
+    Log2(("%s: Ctl#%d: Bus master = %RTbool\n",
+          __FUNCTION__, ATACONTROLLER_IDX(pCtl), fBm));
+#endif
+    if (!fBm)
+        return VINF_SUCCESS; /** @todo Correct? */
+
+    int rc = PDMCritSectEnter(&pCtl->lock, VINF_IOM_R3_IOPORT_WRITE);
     if (rc != VINF_SUCCESS)
         return rc;
