Index: /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp	(revision 24704)
+++ /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp	(revision 24705)
@@ -227,5 +227,12 @@
 
 /*****************************************************************************/
-RT_C_DECLS_BEGIN
+#define virtioGetHostFeatures        vnetGetHostFeatures        
+#define virtioGetHostMinimalFeatures vnetGetHostMinimalFeatures 
+#define virtioSetHostFeatures        vnetSetHostFeatures        
+#define virtioGetConfig              vnetGetConfig              
+#define virtioSetConfig              vnetSetConfig              
+#define virtioReset                  vnetReset                  
+#define virtioReady                  vnetReady                  
+
 PDMBOTHCBDECL(uint32_t) vnetGetHostFeatures(void *pState);
 PDMBOTHCBDECL(uint32_t) vnetGetHostMinimalFeatures(void *pState);
@@ -235,5 +242,4 @@
 PDMBOTHCBDECL(void)     vnetReset(void *pState);
 PDMBOTHCBDECL(void)     vnetReady(void *pState);
-RT_C_DECLS_END
 
 /*****************************************************************************/
@@ -242,35 +248,20 @@
 
 #ifdef IN_RING3
-const struct VirtioPCIDevices
-{
-    uint16_t    uPCIVendorId;
-    uint16_t    uPCIDeviceId;
-    uint16_t    uPCISubsystemVendorId;
-    uint16_t    uPCISubsystemId;
-    uint16_t    uPCIClass;
-    unsigned    nQueues;
-    const char *pcszName;
-    const char *pcszNameFmt;
-    uint32_t  (*pfnGetHostFeatures)(void *pvState);
-    uint32_t  (*pfnGetHostMinimalFeatures)(void *pvState);
-    void      (*pfnSetHostFeatures)(void *pvState, uint32_t uFeatures);
-    int       (*pfnGetConfig)(void *pvState, uint32_t port, uint32_t cb, void *data);
-    int       (*pfnSetConfig)(void *pvState, uint32_t port, uint32_t cb, void *data);
-    void      (*pfnReset)(void *pvState);
-    void      (*pfnReady)(void *pvState);
-} g_VPCIDevices[] =
-{
-    /*  Vendor  Device SSVendor SubSys             Class   NQ Name          Instance */
-    { /* Virtio Network Device */
-        0x1AF4, 0x1000, 0x1AF4, 1 + VIRTIO_NET_ID, 0x0200, VNET_NQUEUES,
-                                                              "virtio-net", "vnet%d",
-        vnetGetHostFeatures, vnetGetHostMinimalFeatures, vnetSetHostFeatures,
-        vnetGetConfig, vnetSetConfig, vnetReset, vnetReady
-    },
+
+#define DEVICE_PCI_VENDOR_ID           0x1AF4
+#define DEVICE_PCI_DEVICE_ID           0x1000
+#define DEVICE_PCI_SUBSYSTEM_VENDOR_ID 0x1AF4
+#define DEVICE_PCI_SUBSYSTEM_ID        1 + VIRTIO_NET_ID
+#define DEVICE_PCI_CLASS               0x0200
+#define DEVICE_N_QUEUES                3
+#define DEVICE_NAME                    "virtio-net"
+#define DEVICE_NAME_FMT                "vnet%d"
+#if 0
     { /* Virtio Block Device */
         0x1AF4, 0x1001, 0x1AF4, 1 + VIRTIO_BLK_ID, 0x0180, 2, "virtio-blk", "vblk%d",
         NULL, NULL, NULL, NULL, NULL, NULL, NULL
     },
-};
+#endif
+
 #endif
 
@@ -295,8 +286,4 @@
 #define VPCI_STATUS_DRV_OK  0x04
 #define VPCI_STATUS_FAILED  0x80
-
-/** @todo use+extend RTNETIPV4 */
-
-/** @todo use+extend RTNETTCP */
 
 #ifndef VBOX_DEVICE_STRUCT_TESTCASE
@@ -519,5 +506,4 @@
 }
 
-#ifdef IN_RING3
 void vpciReset(PVPCISTATE pState)
 {
@@ -530,5 +516,4 @@
         vqueueReset(&pState->Queues[i]);
 }
-#endif
 
 
@@ -556,4 +541,5 @@
         return rc;
 
+    STAM_COUNTER_INC(&pState->StatIntsRaised);
     LogFlow(("%s vpciRaiseInterrupt: u8IntCause=%x\n",
              INSTANCE(pState), u8IntCause));
@@ -576,11 +562,9 @@
 }
 
-#ifdef IN_RING3
 DECLINLINE(uint32_t) vpciGetHostFeatures(PVPCISTATE pState)
 {
-    return g_VPCIDevices[pState->enmDevType].pfnGetHostFeatures(pState)
+    return virtioGetHostFeatures(pState)
         | VPCI_F_NOTIFY_ON_EMPTY;
 }
-#endif
 
 /**
@@ -609,9 +593,5 @@
         case VPCI_HOST_FEATURES:
             /* Tell the guest what features we support. */
-#ifdef IN_RING3
             *pu32 = vpciGetHostFeatures(pState) | VPCI_F_BAD_FEATURE;
-#else
-            rc = VINF_IOM_HC_IOPORT_READ;
-#endif
             break;
 
@@ -649,9 +629,5 @@
             if (port >= VPCI_CONFIG)
             {
-#ifdef IN_RING3
-                rc = g_VPCIDevices[pState->enmDevType].pfnGetConfig(pState, port - VPCI_CONFIG, cb, pu32);
-#else
-                rc = VINF_IOM_HC_IOPORT_READ;
-#endif
+                rc = virtioGetConfig(pState, port - VPCI_CONFIG, cb, pu32);
             }
             else
@@ -696,10 +672,9 @@
         case VPCI_GUEST_FEATURES:
             /* Check if the guest negotiates properly, fall back to basics if it does not. */
-#ifdef IN_RING3
             if (VPCI_F_BAD_FEATURE & u32)
             {
                 Log(("%s WARNING! Guest failed to negotiate properly (guest=%x)\n",
                      INSTANCE(pState), u32));
-                pState->uGuestFeatures = g_VPCIDevices[pState->enmDevType].pfnGetHostMinimalFeatures(pState);
+                pState->uGuestFeatures = virtioGetHostMinimalFeatures(pState);
             }
             /* The guest may potentially desire features we don't support! */
@@ -712,12 +687,8 @@
             else
                 pState->uGuestFeatures = u32;
-            g_VPCIDevices[pState->enmDevType].pfnSetHostFeatures(pState, pState->uGuestFeatures);
-#else
-            rc = VINF_IOM_HC_IOPORT_WRITE;
-#endif
+            virtioSetHostFeatures(pState, pState->uGuestFeatures);
             break;
 
         case VPCI_QUEUE_PFN:
-#ifdef IN_RING3
             /*
              * The guest is responsible for allocating the pages for queues,
@@ -730,8 +701,5 @@
                 vqueueInit(&pState->Queues[pState->uQueueSelector], u32);
             else
-                g_VPCIDevices[pState->enmDevType].pfnReset(pState);
-#else
-            rc = VINF_IOM_HC_IOPORT_WRITE;
-#endif
+                virtioReset(pState);
             break;
 
@@ -763,5 +731,4 @@
 
         case VPCI_STATUS:
-#ifdef IN_RING3
             Assert(cb == 1);
             u32 &= 0xFF;
@@ -770,21 +737,14 @@
             /* Writing 0 to the status port triggers device reset. */
             if (u32 == 0)
-                g_VPCIDevices[pState->enmDevType].pfnReset(pState);
+                virtioReset(pState);
             else if (fHasBecomeReady)
-                g_VPCIDevices[pState->enmDevType].pfnReady(pState);
-#else
-            rc = VINF_IOM_HC_IOPORT_WRITE;
-#endif
+                virtioReady(pState);
             break;
 
         default:
-#ifdef IN_RING3
             if (port >= VPCI_CONFIG)
-                rc = g_VPCIDevices[pState->enmDevType].pfnSetConfig(pState, port - VPCI_CONFIG, cb, &u32);
+                rc = virtioSetConfig(pState, port - VPCI_CONFIG, cb, &u32);
             else
                 rc = PDMDeviceDBGFStop(pDevIns, RT_SRC_POS, "%s virtioIOPortOut: no valid port at offset port=%RTiop cb=%08x\n", szInst, port, cb);
-#else
-            rc = VINF_IOM_HC_IOPORT_WRITE;
-#endif
             break;
     }
@@ -1062,5 +1022,5 @@
         }
         else
-            pState->nQueues = g_VPCIDevices[pState->enmDevType].nQueues;
+            pState->nQueues = DEVICE_N_QUEUES;
         for (unsigned i = 0; i < pState->nQueues; i++)
         {
@@ -1093,10 +1053,9 @@
 static DECLCALLBACK(void) vpciConfigure(PCIDEVICE& pci, VirtioDeviceType enmType)
 {
-    Assert(enmType < (int)RT_ELEMENTS(g_VPCIDevices));
     /* Configure PCI Device, assume 32-bit mode ******************************/
-    PCIDevSetVendorId(&pci, g_VPCIDevices[enmType].uPCIVendorId);
-    PCIDevSetDeviceId(&pci, g_VPCIDevices[enmType].uPCIDeviceId);
-    vpciCfgSetU16(pci, VBOX_PCI_SUBSYSTEM_VENDOR_ID, g_VPCIDevices[enmType].uPCISubsystemVendorId);
-    vpciCfgSetU16(pci, VBOX_PCI_SUBSYSTEM_ID, g_VPCIDevices[enmType].uPCISubsystemId);
+    PCIDevSetVendorId(&pci, DEVICE_PCI_VENDOR_ID);
+    PCIDevSetDeviceId(&pci, DEVICE_PCI_DEVICE_ID);
+    vpciCfgSetU16(pci, VBOX_PCI_SUBSYSTEM_VENDOR_ID, DEVICE_PCI_SUBSYSTEM_VENDOR_ID);
+    vpciCfgSetU16(pci, VBOX_PCI_SUBSYSTEM_ID, DEVICE_PCI_SUBSYSTEM_ID);
 
     /* ABI version, must be equal 0 as of 2.6.30 kernel. */
@@ -1104,5 +1063,5 @@
     /* Ethernet adapter */
     vpciCfgSetU8( pci, VBOX_PCI_CLASS_PROG,           0x00);
-    vpciCfgSetU16(pci, VBOX_PCI_CLASS_DEVICE, g_VPCIDevices[enmType].uPCIClass);
+    vpciCfgSetU16(pci, VBOX_PCI_CLASS_DEVICE, DEVICE_PCI_CLASS);
     /* Interrupt Pin: INTA# */
     vpciCfgSetU8( pci, VBOX_PCI_INTERRUPT_PIN,        0x01);
@@ -1116,5 +1075,5 @@
     int rc = VINF_SUCCESS;
     /* Init handles and log related stuff. */
-    RTStrPrintf(pState->szInstance, sizeof(pState->szInstance), g_VPCIDevices[enmDevType].pcszNameFmt, iInstance);
+    RTStrPrintf(pState->szInstance, sizeof(pState->szInstance), DEVICE_NAME_FMT, iInstance);
     pState->enmDevType   = enmDevType;
 
@@ -1151,5 +1110,5 @@
     pState->pLedsConnector = (PPDMILEDCONNECTORS)pBase->pfnQueryInterface(pBase, PDMINTERFACE_LED_CONNECTORS);
 
-    pState->nQueues = g_VPCIDevices[pState->enmDevType].nQueues;
+    pState->nQueues = DEVICE_N_QUEUES;
 
 #if defined(VBOX_WITH_STATISTICS)
@@ -1440,5 +1399,4 @@
 }
 
-#ifdef IN_RING3
 /**
  * Hardware reset. Revert all registers to initial values.
@@ -1458,4 +1416,5 @@
 }
 
+#ifdef IN_RING3
 /**
  * Wakeup the RX thread.
@@ -1722,4 +1681,5 @@
         return rc;
 
+    STAM_PROFILE_ADV_START(&pState->StatReceive, a);
     vpciSetReadLed(&pState->VPCI, true);
     if (vnetAddressFilter(pState, pvBuf, cb))
@@ -1729,4 +1689,5 @@
     }
     vpciSetReadLed(&pState->VPCI, false);
+    STAM_PROFILE_ADV_STOP(&pState->StatReceive, a);
 
     return rc;
@@ -1828,4 +1789,5 @@
         else
         {
+            STAM_PROFILE_ADV_START(&pState->StatTransmit, a);
             /* Assemble a complete frame. */
             for (unsigned int i = 1; i < elem.nOut && uOffset < VNET_MAX_FRAME_SIZE; i++)
@@ -1848,4 +1810,5 @@
         vqueuePut(&pState->VPCI, pQueue, &elem, sizeof(VNETHDR) + uOffset);
         vqueueSync(&pState->VPCI, pQueue);
+        STAM_PROFILE_ADV_STOP(&pState->StatTransmit, a);
     }
     vpciSetWriteLed(&pState->VPCI, false);
