Index: trunk/include/VBox/pci.h
===================================================================
--- trunk/include/VBox/pci.h	(revision 23252)
+++ trunk/include/VBox/pci.h	(revision 23253)
@@ -199,5 +199,5 @@
     union
     {
-#ifdef __PCIDEVICEINT_DECLARED__
+#ifdef PCIDEVICEINT_DECLARED
         PCIDEVICEINT        s;
 #endif
Index: trunk/src/VBox/Devices/Bus/DevPCI.cpp
===================================================================
--- trunk/src/VBox/Devices/Bus/DevPCI.cpp	(revision 23252)
+++ trunk/src/VBox/Devices/Bus/DevPCI.cpp	(revision 23253)
@@ -933,5 +933,5 @@
                 /* VGA: map frame buffer to default Bochs VBE address */
                 pci_set_io_region_addr(pGlobals, uBus, uDevFn, 0, 0xE0000000);
-                /* 
+                /*
                  * Legacy VGA I/O ports are implicitly decoded by a VGA class device. But
                  * only the framebuffer (i.e., a memory region) is explicitly registered via
@@ -1258,4 +1258,33 @@
 
 /**
+ * Common worker for pciR3SaveExec and pcibridgeR3SaveExec.
+ *
+ * @returns VBox status code.
+ * @param   pBus            The bus to save.
+ * @param   pSSM            The saved state handle.
+ */
+static int pciR3CommonSaveExec(PPCIBUS pBus, PSSMHANDLE pSSM)
+{
+    /*
+     * Iterate thru all the devices.
+     */
+    for (uint32_t i = 0; i < RT_ELEMENTS(pBus->devices); i++)
+    {
+        PPCIDEVICE pDev = pBus->devices[i];
+        if (pDev)
+        {
+            SSMR3PutU32(pSSM, i);
+            SSMR3PutMem(pSSM, pDev->config, sizeof(pDev->config));
+
+            int rc = SSMR3PutS32(pSSM, pDev->Int.s.uIrqPinState);
+            if (RT_FAILURE(rc))
+                return rc;
+        }
+    }
+    return SSMR3PutU32(pSSM, UINT32_MAX); /* terminator */
+}
+
+
+/**
  * Saves a state of the PCI device.
  *
@@ -1269,5 +1298,4 @@
     uint32_t    i;
     PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
-    PPCIBUS     pBus =  &pThis->PciBus;
 
     /*
@@ -1291,21 +1319,7 @@
 
     /*
-     * Iterate thru all the devices.
-     */
-    for (i = 0; i < RT_ELEMENTS(pBus->devices); i++)
-    {
-        PPCIDEVICE pDev = pBus->devices[i];
-        if (pDev)
-        {
-            int rc;
-            SSMR3PutU32(pSSMHandle, i);
-            SSMR3PutMem(pSSMHandle, pDev->config, sizeof(pDev->config));
-
-            rc = SSMR3PutS32(pSSMHandle, pDev->Int.s.uIrqPinState);
-            if (RT_FAILURE(rc))
-                return rc;
-        }
-    }
-    return SSMR3PutU32(pSSMHandle, ~0); /* terminator */
+     * Join paths with pcibridgeR3SaveExec.
+     */
+    return pciR3CommonSaveExec(&pThis->PciBus, pSSMHandle);
 }
 
@@ -1522,52 +1536,19 @@
 
 /**
- * Loads a saved PCI device state.
+ * Common worker for pciR3LoadExec and pcibridgeR3LoadExec.
  *
  * @returns VBox status code.
- * @param   pDevIns     The device instance.
- * @param   pSSMHandle  The handle to the saved state.
- * @param   uVersion    The data unit version number.
- * @param   uPass       The data pass.
- */
-static DECLCALLBACK(int) pciR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t uVersion, uint32_t uPass)
-{
-    PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
-    PPCIBUS     pBus  = &pThis->PciBus;
+ * @param   pBus                The bus which data is being loaded.
+ * @param   pSSMHandle          The saved state handle.
+ * @param   uVersion            The data version.
+ * @param   uPass               The pass.
+ */
+static DECLCALLBACK(int) pciR3CommonLoadExec(PPCIBUS pBus, PSSMHANDLE pSSMHandle, uint32_t uVersion, uint32_t uPass)
+{
     uint32_t    u32;
     uint32_t    i;
     int         rc;
 
-    /*
-     * Check the version.
-     */
-    if (uVersion > VBOX_PCI_SAVED_STATE_VERSION)
-        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
     Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
-
-    /*
-     * Bus state data.
-     */
-    SSMR3GetU32(pSSMHandle, &pThis->uConfigReg);
-    if (uVersion > 1)
-        SSMR3GetBool(pSSMHandle, &pThis->fUseIoApic);
-
-    /* Load IRQ states. */
-    if (uVersion > 2)
-    {
-        for (uint8_t i = 0; i < PCI_IRQ_PINS; i++)
-            SSMR3GetU32(pSSMHandle, (uint32_t *)&pThis->pci_irq_levels[i]);
-        for (uint8_t i = 0; i < PCI_APIC_IRQ_PINS; i++)
-            SSMR3GetU32(pSSMHandle, (uint32_t *)&pThis->pci_apic_irq_levels[i]);
-
-        SSMR3GetU32(pSSMHandle, &pThis->acpi_irq_level);
-        SSMR3GetS32(pSSMHandle, &pThis->acpi_irq);
-    }
-
-    /* separator */
-    rc = SSMR3GetU32(pSSMHandle, &u32);
-    if (RT_FAILURE(rc))
-        return rc;
-    if (u32 != (uint32_t)~0)
-        AssertMsgFailedReturn(("u32=%#x\n", u32), rc);
 
     /*
@@ -1604,5 +1585,5 @@
         }
 
-        /* Get the data */
+        /* get the data */
         DevTmp.Int.s.uIrqPinState = ~0; /* Invalid value in case we have an older saved state to force a state change in pciSetIrq. */
         SSMR3GetMem(pSSMHandle, DevTmp.config, sizeof(DevTmp.config));
@@ -1649,4 +1630,61 @@
 
     return VINF_SUCCESS;
+}
+
+
+/**
+ * Loads a saved PCI device state.
+ *
+ * @returns VBox status code.
+ * @param   pDevIns     The device instance.
+ * @param   pSSMHandle  The handle to the saved state.
+ * @param   uVersion    The data unit version number.
+ * @param   uPass       The data pass.
+ */
+static DECLCALLBACK(int) pciR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t uVersion, uint32_t uPass)
+{
+    PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
+    PPCIBUS     pBus  = &pThis->PciBus;
+    uint32_t    u32;
+    uint32_t    i;
+    int         rc;
+
+    /*
+     * Check the version.
+     */
+    if (uVersion > VBOX_PCI_SAVED_STATE_VERSION)
+        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
+    Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
+
+    /*
+     * Bus state data.
+     */
+    SSMR3GetU32(pSSMHandle, &pThis->uConfigReg);
+    if (uVersion > 1)
+        SSMR3GetBool(pSSMHandle, &pThis->fUseIoApic);
+
+    /* Load IRQ states. */
+    if (uVersion > 2)
+    {
+        for (uint8_t i = 0; i < PCI_IRQ_PINS; i++)
+            SSMR3GetU32(pSSMHandle, (uint32_t *)&pThis->pci_irq_levels[i]);
+        for (uint8_t i = 0; i < PCI_APIC_IRQ_PINS; i++)
+            SSMR3GetU32(pSSMHandle, (uint32_t *)&pThis->pci_apic_irq_levels[i]);
+
+        SSMR3GetU32(pSSMHandle, &pThis->acpi_irq_level);
+        SSMR3GetS32(pSSMHandle, &pThis->acpi_irq);
+    }
+
+    /* separator */
+    rc = SSMR3GetU32(pSSMHandle, &u32);
+    if (RT_FAILURE(rc))
+        return rc;
+    if (u32 != (uint32_t)~0)
+        AssertMsgFailedReturn(("u32=%#x\n", u32), rc);
+
+    /*
+     * The devices.
+     */
+    return pciR3CommonLoadExec(pBus, pSSMHandle, uVersion, uPass);
 }
 
@@ -2284,26 +2322,6 @@
 static DECLCALLBACK(int) pcibridgeR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
 {
-/** @todo make common with pciR3SaveExec! */
-    uint32_t    i;
     PPCIBUS pThis = PDMINS_2_DATA(pDevIns, PPCIBUS);
-
-    /*
-     * Iterate all the devices.
-     */
-    for (i = 0; i < RT_ELEMENTS(pThis->devices); i++)
-    {
-        PPCIDEVICE pDev = pThis->devices[i];
-        if (pDev)
-        {
-            int rc;
-            SSMR3PutU32(pSSMHandle, i);
-            SSMR3PutMem(pSSMHandle, pDev->config, sizeof(pDev->config));
-
-            rc = SSMR3PutS32(pSSMHandle, pDev->Int.s.uIrqPinState);
-            if (RT_FAILURE(rc))
-                return rc;
-        }
-    }
-    return SSMR3PutU32(pSSMHandle, ~0); /* terminator */
+    return pciR3CommonSaveExec(pThis, pSSMHandle);
 }
 
@@ -2336,85 +2354,8 @@
 static DECLCALLBACK(int) pcibridgeR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t uVersion, uint32_t uPass)
 {
-    PPCIBUS     pBus  = PDMINS_2_DATA(pDevIns, PPCIBUS);
-    uint32_t    u32;
-    uint32_t    i;
-    int         rc;
-
-/** @todo r=bird: this is a copy of pciR3LoadExec. combine the two!  */
-
-    /*
-     * Check the version.
-     */
+    PPCIBUS pThis = PDMINS_2_DATA(pDevIns, PPCIBUS);
     if (uVersion > VBOX_PCI_SAVED_STATE_VERSION)
         return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
-    Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
-
-    /*
-     * Iterate all the devices.
-     */
-    for (i = 0;; i++)
-    {
-        PCIDEVICE   DevTmp;
-        PPCIDEVICE  pDev;
-
-        /* index / terminator */
-        rc = SSMR3GetU32(pSSMHandle, &u32);
-        if (RT_FAILURE(rc))
-            return rc;
-        if (u32 == (uint32_t)~0)
-            break;
-        if (    u32 >= RT_ELEMENTS(pBus->devices)
-            ||  u32 < i)
-        {
-            AssertMsgFailed(("u32=%#x i=%#x\n", u32, i));
-            return rc;
-        }
-
-        /* skip forward to the device checking that no new devices are present. */
-        for (; i < u32; i++)
-        {
-            if (pBus->devices[i])
-            {
-                LogRel(("New device in slot %#x, %s (vendor=%#06x device=%#06x)\n", i, pBus->devices[i]->name,
-                        PCIDevGetVendorId(pBus->devices[i]), PCIDevGetDeviceId(pBus->devices[i])));
-                if (SSMR3HandleGetAfter(pSSMHandle) != SSMAFTER_DEBUG_IT)
-                    AssertFailedReturn(VERR_SSM_LOAD_CONFIG_MISMATCH);
-            }
-        }
-
-        /* get the data */
-        DevTmp.Int.s.uIrqPinState = 0;
-        SSMR3GetMem(pSSMHandle, DevTmp.config, sizeof(DevTmp.config));
-        rc = SSMR3GetS32(pSSMHandle, &DevTmp.Int.s.uIrqPinState);
-        if (RT_FAILURE(rc))
-            return rc;
-
-        /* check that it's still around. */
-        pDev = pBus->devices[i];
-        if (!pDev)
-        {
-            LogRel(("Device in slot %#x has been removed! vendor=%#06x device=%#06x\n", i,
-                    PCIDevGetVendorId(&DevTmp), PCIDevGetDeviceId(&DevTmp)));
-            if (SSMR3HandleGetAfter(pSSMHandle) != SSMAFTER_DEBUG_IT)
-                AssertFailedReturn(VERR_SSM_LOAD_CONFIG_MISMATCH);
-            continue;
-        }
-
-        /* match the vendor id assuming that this will never be changed. */
-        if (    DevTmp.config[0] != pDev->config[0]
-            ||  DevTmp.config[1] != pDev->config[1])
-        {
-            LogRel(("Device in slot %#x (%s) vendor id mismatch! saved=%.4Rhxs current=%.4Rhxs\n",
-                    i, pDev->name, DevTmp.config, pDev->config));
-            AssertFailedReturn(VERR_SSM_LOAD_CONFIG_MISMATCH);
-        }
-
-        /* commit the loaded device config. */
-        pciR3CommonRestoreConfig(pDev, &DevTmp.config[0], false ); /** @todo fix bridge fun! */
-
-        pDev->Int.s.uIrqPinState = DevTmp.Int.s.uIrqPinState;
-    }
-
-    return VINF_SUCCESS;
+    return pciR3CommonLoadExec(pThis, pSSMHandle, uVersion, uPass);
 }
 
Index: trunk/src/VBox/Devices/Bus/PCIInternal.h
===================================================================
--- trunk/src/VBox/Devices/Bus/PCIInternal.h	(revision 23252)
+++ trunk/src/VBox/Devices/Bus/PCIInternal.h	(revision 23253)
@@ -98,5 +98,6 @@
      * If clear the device and it's functions can be relocated to satisfy the slot request of another device. */
     bool                            fRequestedDevFn;
-    /** Flag whether the device is a pci-to-pci bridge. */
+    /** Flag whether the device is a pci-to-pci bridge.
+     * This is set prior to device registration.  */
     bool                            fPciToPciBridge;
     /** Current state of the IRQ pin of the device. */
@@ -115,5 +116,5 @@
 
 /* Indicate that PCIDEVICE::Int.s can be declared. */
-#define __PCIDEVICEINT_DECLARED__
+#define PCIDEVICEINT_DECLARED
 
 #endif
