This patch adds below function pointers to abstract pci access method.
 - legacy_read8/16/32
 - legacy_write8/16/32
 - modern_read8/16/32
 - modern_write8/16/32
 - map_pci_cfg
 - unmap_pci_cfg
 - get_cfg_addr
 - read_pci_cfg
This layer will be used when virtio-net PMD supports container extension.
The legacy_xxxxx are for handling legacy virtio-net device, and
the modern_xxxxx are for handling virtio-1.0 device.
This new layer also abstract how to access to pci configuration space.

Signed-off-by: Tetsuya Mukawa <mukawa at igel.co.jp>
---
 drivers/net/virtio/virtio_ethdev.c |   4 +-
 drivers/net/virtio/virtio_pci.c    | 449 ++++++++++++++++++++++++++-----------
 drivers/net/virtio/virtio_pci.h    |  34 ++-
 3 files changed, 354 insertions(+), 133 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c 
b/drivers/net/virtio/virtio_ethdev.c
index b98d195..c477b05 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1037,7 +1037,7 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)

        pci_dev = eth_dev->pci_dev;

-       if (vtpci_init(pci_dev, hw) < 0)
+       if (vtpci_init(eth_dev, hw) < 0)
                return -1;

        /* Reset the device although not necessary at startup */
@@ -1177,7 +1177,7 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
                rte_intr_callback_unregister(&pci_dev->intr_handle,
                                                virtio_interrupt_handler,
                                                eth_dev);
-       vtpci_uninit(dev, hw)
+       vtpci_uninit(eth_dev, hw);

        PMD_INIT_LOG(DEBUG, "dev_uninit completed");

diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index ffcd2fa..20b64eb 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -68,6 +68,190 @@
 #define VIRTIO_WRITE_REG_4(hw, reg, value) \
        outl_p((unsigned int)(value), (VIRTIO_PCI_REG_ADDR((hw), (reg))))

+static uint8_t
+phys_legacy_read8(struct virtio_hw *hw, uint8_t *addr)
+{
+       return VIRTIO_READ_REG_1(hw, (uint64_t)addr);
+}
+
+static uint16_t
+phys_legacy_read16(struct virtio_hw *hw, uint16_t *addr)
+{
+       return VIRTIO_READ_REG_2(hw, (uint64_t)addr);
+}
+
+static uint32_t
+phys_legacy_read32(struct virtio_hw *hw, uint32_t *addr)
+{
+       return VIRTIO_READ_REG_4(hw, (uint64_t)addr);
+}
+
+static void
+phys_legacy_write8(struct virtio_hw *hw, uint8_t *addr, uint8_t val)
+{
+       return VIRTIO_WRITE_REG_1(hw, (uint64_t)addr, val);
+}
+
+static void
+phys_legacy_write16(struct virtio_hw *hw, uint16_t *addr, uint16_t val)
+{
+       return VIRTIO_WRITE_REG_2(hw, (uint64_t)addr, val);
+}
+
+static void
+phys_legacy_write32(struct virtio_hw *hw, uint32_t *addr, uint32_t val)
+{
+       return VIRTIO_WRITE_REG_4(hw, (uint64_t)addr, val);
+}
+
+#define MODERN_READ_DEF(nr_bits, type)                 \
+static inline type                             \
+io_read##nr_bits(type *addr)                   \
+{                                              \
+       return *(volatile type *)addr;          \
+}
+
+#define MODERN_WRITE_DEF(nr_bits, type)        \
+static inline void                             \
+io_write##nr_bits(type *addr, type val)                \
+{                                              \
+       *(volatile type *)addr = val;           \
+}
+
+MODERN_READ_DEF (8, uint8_t)
+MODERN_WRITE_DEF(8, uint8_t)
+
+MODERN_READ_DEF (16, uint16_t)
+MODERN_WRITE_DEF(16, uint16_t)
+
+MODERN_READ_DEF (32, uint32_t)
+MODERN_WRITE_DEF(32, uint32_t)
+
+static uint8_t
+phys_modern_read8(struct virtio_hw *hw __rte_unused, uint8_t *addr)
+{
+       return io_read8((uint8_t *)addr);
+}
+
+static uint16_t
+phys_modern_read16(struct virtio_hw *hw __rte_unused, uint16_t *addr)
+{
+       return io_read16((uint16_t *)addr);
+}
+
+static uint32_t
+phys_modern_read32(struct virtio_hw *hw __rte_unused, uint32_t *addr)
+{
+       return io_read32((uint32_t *)addr);
+}
+
+static void
+phys_modern_write8(struct virtio_hw *hw __rte_unused,
+               uint8_t *addr, uint8_t val)
+{
+       return io_write8((uint8_t *)addr, val);
+}
+
+static void
+phys_modern_write16(struct virtio_hw *hw __rte_unused,
+               uint16_t *addr, uint16_t val)
+{
+       return io_write16((uint16_t *)addr, val);
+}
+
+static void
+phys_modern_write32(struct virtio_hw *hw __rte_unused,
+               uint32_t *addr, uint32_t val)
+{
+       return io_write32((uint32_t *)addr, val);
+}
+
+static int
+phys_map_pci_cfg(struct virtio_hw *hw)
+{
+       return rte_eal_pci_map_device(hw->dev);
+}
+
+static void
+phys_unmap_pci_cfg(struct virtio_hw *hw)
+{
+       rte_eal_pci_unmap_device(hw->dev);
+}
+
+static int
+phys_read_pci_cfg(struct virtio_hw *hw, void *buf, size_t len, off_t offset)
+{
+       return rte_eal_pci_read_config(hw->dev, buf, len, offset);
+}
+
+static void *
+phys_get_cfg_addr(struct virtio_hw *hw, struct virtio_pci_cap *cap)
+{
+       uint8_t  bar    = cap->bar;
+       uint32_t length = cap->length;
+       uint32_t offset = cap->offset;
+       uint8_t *base;
+
+       if (bar > 5) {
+               PMD_INIT_LOG(ERR, "invalid bar: %u", bar);
+               return NULL;
+       }
+
+       if (offset + length > hw->dev->mem_resource[bar].len) {
+               PMD_INIT_LOG(ERR,
+                       "invalid cap: overflows bar space: %u > %"PRIu64,
+                       offset + length, hw->dev->mem_resource[bar].len);
+               return NULL;
+       }
+
+       base = hw->dev->mem_resource[bar].addr;
+       if (base == NULL) {
+               PMD_INIT_LOG(ERR, "bar %u base addr is NULL", bar);
+               return NULL;
+       }
+
+       return base + offset;
+}
+
+static const struct virtio_pci_access_ops phys_access_ops = {
+       .legacy_read8           = phys_legacy_read8,
+       .legacy_read16          = phys_legacy_read16,
+       .legacy_read32          = phys_legacy_read32,
+       .legacy_write8          = phys_legacy_write8,
+       .legacy_write16         = phys_legacy_write16,
+       .legacy_write32         = phys_legacy_write32,
+
+       .modern_read8           = phys_modern_read8,
+       .modern_read16          = phys_modern_read16,
+       .modern_read32          = phys_modern_read32,
+       .modern_write8          = phys_modern_write8,
+       .modern_write16         = phys_modern_write16,
+       .modern_write32         = phys_modern_write32,
+
+       .map_pci_cfg            = phys_map_pci_cfg,
+       .unmap_pci_cfg          = phys_unmap_pci_cfg,
+       .read_pci_cfg           = phys_read_pci_cfg,
+       .get_cfg_addr           = phys_get_cfg_addr,
+};
+
+static int
+vtpci_access_init(struct rte_eth_dev *dev, struct virtio_hw *hw)
+{
+       if (dev->dev_type == RTE_ETH_DEV_PCI) {
+               hw->vtpci_access_ops = &phys_access_ops;
+               return 0;
+       }
+
+       PMD_DRV_LOG(ERR, "Unkown virtio-net device.");
+       return -1;
+}
+
+static void
+vtpci_access_uninit(struct rte_eth_dev *dev __rte_unused, struct virtio_hw *hw)
+{
+       hw->vtpci_access_ops = NULL;
+}
+
 static void
 legacy_read_dev_config(struct virtio_hw *hw, uint64_t offset,
                       void *dst, int length)
@@ -80,13 +264,16 @@ legacy_read_dev_config(struct virtio_hw *hw, uint64_t 
offset,
        for (d = dst; length > 0; d += size, off += size, length -= size) {
                if (length >= 4) {
                        size = 4;
-                       *(uint32_t *)d = VIRTIO_READ_REG_4(hw, off);
+                       *(uint32_t *)d = hw->vtpci_access_ops->legacy_read32(
+                                               hw, (uint32_t *)off);
                } else if (length >= 2) {
                        size = 2;
-                       *(uint16_t *)d = VIRTIO_READ_REG_2(hw, off);
+                       *(uint16_t *)d = hw->vtpci_access_ops->legacy_read16(
+                                               hw, (uint16_t *)off);
                } else {
                        size = 1;
-                       *d = VIRTIO_READ_REG_1(hw, off);
+                       *d = hw->vtpci_access_ops->legacy_read8(
+                                               hw, (uint8_t *)off);
                }
        }
 }
@@ -103,13 +290,16 @@ legacy_write_dev_config(struct virtio_hw *hw, uint64_t 
offset,
        for (s = src; length > 0; s += size, off += size, length -= size) {
                if (length >= 4) {
                        size = 4;
-                       VIRTIO_WRITE_REG_4(hw, off, *(const uint32_t *)s);
+                       hw->vtpci_access_ops->legacy_write32(hw,
+                                       (uint32_t *)off, *(const uint32_t *)s);
                } else if (length >= 2) {
                        size = 2;
-                       VIRTIO_WRITE_REG_2(hw, off, *(const uint16_t *)s);
+                       hw->vtpci_access_ops->legacy_write16(hw,
+                                       (uint16_t *)off, *(const uint16_t *)s);
                } else {
                        size = 1;
-                       VIRTIO_WRITE_REG_1(hw, off, *s);
+                       hw->vtpci_access_ops->legacy_write8(hw,
+                                       (uint8_t *)off, *s);
                }
        }
 }
@@ -117,7 +307,8 @@ legacy_write_dev_config(struct virtio_hw *hw, uint64_t 
offset,
 static uint64_t
 legacy_get_features(struct virtio_hw *hw)
 {
-       return VIRTIO_READ_REG_4(hw, VIRTIO_PCI_HOST_FEATURES);
+       return hw->vtpci_access_ops->legacy_read32(hw,
+                       (uint32_t *)VIRTIO_PCI_HOST_FEATURES);
 }

 static void
@@ -128,19 +319,22 @@ legacy_set_features(struct virtio_hw *hw, uint64_t 
features)
                        "only 32 bit features are allowed for legacy virtio!");
                return;
        }
-       VIRTIO_WRITE_REG_4(hw, VIRTIO_PCI_GUEST_FEATURES, features);
+       hw->vtpci_access_ops->legacy_write32(hw,
+                       (uint32_t *)VIRTIO_PCI_GUEST_FEATURES, features);
 }

 static uint8_t
 legacy_get_status(struct virtio_hw *hw)
 {
-       return VIRTIO_READ_REG_1(hw, VIRTIO_PCI_STATUS);
+       return hw->vtpci_access_ops->legacy_read8(hw,
+                       (uint8_t *)VIRTIO_PCI_STATUS);
 }

 static void
 legacy_set_status(struct virtio_hw *hw, uint8_t status)
 {
-       VIRTIO_WRITE_REG_1(hw, VIRTIO_PCI_STATUS, status);
+       hw->vtpci_access_ops->legacy_write8(hw,
+                       (uint8_t *)VIRTIO_PCI_STATUS, status);
 }

 static void
@@ -152,45 +346,56 @@ legacy_reset(struct virtio_hw *hw)
 static uint8_t
 legacy_get_isr(struct virtio_hw *hw)
 {
-       return VIRTIO_READ_REG_1(hw, VIRTIO_PCI_ISR);
+       return hw->vtpci_access_ops->legacy_read8(hw,
+                       (uint8_t *)VIRTIO_PCI_ISR);
 }

 /* Enable one vector (0) for Link State Intrerrupt */
 static uint16_t
 legacy_set_config_irq(struct virtio_hw *hw, uint16_t vec)
 {
-       VIRTIO_WRITE_REG_2(hw, VIRTIO_MSI_CONFIG_VECTOR, vec);
-       return VIRTIO_READ_REG_2(hw, VIRTIO_MSI_CONFIG_VECTOR);
+       hw->vtpci_access_ops->legacy_write16(hw,
+                       (uint16_t *)VIRTIO_MSI_CONFIG_VECTOR, vec);
+       return hw->vtpci_access_ops->legacy_read16(hw,
+                       (uint16_t *)VIRTIO_MSI_CONFIG_VECTOR);
 }

 static uint16_t
 legacy_get_queue_num(struct virtio_hw *hw, uint16_t queue_id)
 {
-       VIRTIO_WRITE_REG_2(hw, VIRTIO_PCI_QUEUE_SEL, queue_id);
-       return VIRTIO_READ_REG_2(hw, VIRTIO_PCI_QUEUE_NUM);
+       hw->vtpci_access_ops->legacy_write16(hw,
+                       (uint16_t *)VIRTIO_PCI_QUEUE_SEL, queue_id);
+       return hw->vtpci_access_ops->legacy_read16(hw,
+                       (uint16_t *)VIRTIO_PCI_QUEUE_NUM);
 }

 static void
 legacy_setup_queue(struct virtio_hw *hw, struct virtqueue *vq)
 {
-       VIRTIO_WRITE_REG_2(hw, VIRTIO_PCI_QUEUE_SEL, vq->vq_queue_index);
+       hw->vtpci_access_ops->legacy_write16(hw,
+                       (uint16_t *)VIRTIO_PCI_QUEUE_SEL, vq->vq_queue_index);

-       VIRTIO_WRITE_REG_4(hw, VIRTIO_PCI_QUEUE_PFN,
-               vq->mz->phys_addr >> VIRTIO_PCI_QUEUE_ADDR_SHIFT);
+       hw->vtpci_access_ops->legacy_write32(hw,
+                       (uint32_t *)VIRTIO_PCI_QUEUE_PFN,
+                       vq->vq_ring_mem >> VIRTIO_PCI_QUEUE_ADDR_SHIFT);
 }

 static void
 legacy_del_queue(struct virtio_hw *hw, struct virtqueue *vq)
 {
-       VIRTIO_WRITE_REG_2(hw, VIRTIO_PCI_QUEUE_SEL, vq->vq_queue_index);
+       hw->vtpci_access_ops->legacy_write16(hw,
+                       (uint16_t *)VIRTIO_PCI_QUEUE_SEL, vq->vq_queue_index);

-       VIRTIO_WRITE_REG_4(hw, VIRTIO_PCI_QUEUE_PFN, 0);
+       hw->vtpci_access_ops->legacy_write32(hw,
+                       (uint32_t *)VIRTIO_PCI_QUEUE_PFN, 0);
 }

 static void
 legacy_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
 {
-       VIRTIO_WRITE_REG_2(hw, VIRTIO_PCI_QUEUE_NOTIFY, vq->vq_queue_index);
+       hw->vtpci_access_ops->legacy_write16(hw,
+                       (uint16_t *)VIRTIO_PCI_QUEUE_NOTIFY,
+                       vq->vq_queue_index);
 }

 #ifdef RTE_EXEC_ENV_LINUXAPP
@@ -468,35 +673,12 @@ static const struct virtio_pci_ops legacy_ops = {
        .notify_queue   = legacy_notify_queue,
 };

-
-#define MODERN_READ_DEF(nr_bits, type)         \
-static inline type                             \
-io_read##nr_bits(type *addr)                   \
-{                                              \
-       return *(volatile type *)addr;          \
-}
-
-#define MODERN_WRITE_DEF(nr_bits, type)                \
-static inline void                             \
-io_write##nr_bits(type *addr, type val)                \
-{                                              \
-       *(volatile type *)addr = val;           \
-}
-
-MODERN_READ_DEF (8, uint8_t)
-MODERN_WRITE_DEF(8, uint8_t)
-
-MODERN_READ_DEF (16, uint16_t)
-MODERN_WRITE_DEF(16, uint16_t)
-
-MODERN_READ_DEF (32, uint32_t)
-MODERN_WRITE_DEF(32, uint32_t)
-
 static inline void
-io_write64_twopart(uint32_t *lo, uint32_t *hi, uint64_t val)
+io_write64_twopart(struct virtio_hw *hw,
+                  uint32_t *lo, uint32_t *hi, uint64_t val)
 {
-       io_write32(lo, (uint32_t)val);
-       io_write32(hi, val >> 32);
+       hw->vtpci_access_ops->modern_write32(hw, lo, (uint32_t)val);
+       hw->vtpci_access_ops->modern_write32(hw, hi, val >> 32);
 }

 static void
@@ -508,13 +690,16 @@ modern_read_dev_config(struct virtio_hw *hw, uint64_t 
offset,
        uint8_t old_gen, new_gen;

        do {
-               old_gen = io_read8(&hw->common_cfg->config_generation);
+               old_gen = hw->vtpci_access_ops->modern_read8(hw,
+                               &hw->common_cfg->config_generation);

                p = dst;
                for (i = 0;  i < length; i++)
-                       *p++ = io_read8((uint8_t *)hw->dev_cfg + offset + i);
+                       *p++ = hw->vtpci_access_ops->modern_read8(hw,
+                                       (uint8_t *)hw->dev_cfg + offset + i);

-               new_gen = io_read8(&hw->common_cfg->config_generation);
+               new_gen = hw->vtpci_access_ops->modern_read8(hw,
+                               &hw->common_cfg->config_generation);
        } while (old_gen != new_gen);
 }

@@ -526,7 +711,8 @@ modern_write_dev_config(struct virtio_hw *hw, uint64_t 
offset,
        const uint8_t *p = src;

        for (i = 0;  i < length; i++)
-               io_write8((uint8_t *)hw->dev_cfg + offset + i, *p++);
+               hw->vtpci_access_ops->modern_write8(hw,
+                               (uint8_t *)hw->dev_cfg + offset + i, *p++);
 }

 static uint64_t
@@ -534,11 +720,15 @@ modern_get_features(struct virtio_hw *hw)
 {
        uint32_t features_lo, features_hi;

-       io_write32(&hw->common_cfg->device_feature_select, 0);
-       features_lo = io_read32(&hw->common_cfg->device_feature);
+       hw->vtpci_access_ops->modern_write32(hw,
+                       &hw->common_cfg->device_feature_select, 0);
+       features_lo = hw->vtpci_access_ops->modern_read32(hw,
+                       &hw->common_cfg->device_feature);

-       io_write32(&hw->common_cfg->device_feature_select, 1);
-       features_hi = io_read32(&hw->common_cfg->device_feature);
+       hw->vtpci_access_ops->modern_write32(hw,
+                       &hw->common_cfg->device_feature_select, 1);
+       features_hi = hw->vtpci_access_ops->modern_read32(hw,
+                       &hw->common_cfg->device_feature);

        return ((uint64_t)(features_hi) << 32) | features_lo;
 }
@@ -546,25 +736,30 @@ modern_get_features(struct virtio_hw *hw)
 static void
 modern_set_features(struct virtio_hw *hw, uint64_t features)
 {
-       io_write32(&hw->common_cfg->guest_feature_select, 0);
-       io_write32(&hw->common_cfg->guest_feature,
-                  features & ((1ULL << 32) - 1));
+       hw->vtpci_access_ops->modern_write32(hw,
+                       &hw->common_cfg->guest_feature_select, 0);
+       hw->vtpci_access_ops->modern_write32(hw,
+                       &hw->common_cfg->guest_feature,
+                       features & ((1ULL << 32) - 1));

-       io_write32(&hw->common_cfg->guest_feature_select, 1);
-       io_write32(&hw->common_cfg->guest_feature,
-                  features >> 32);
+       hw->vtpci_access_ops->modern_write32(hw,
+                       &hw->common_cfg->guest_feature_select, 1);
+       hw->vtpci_access_ops->modern_write32(hw,
+                       &hw->common_cfg->guest_feature, features >> 32);
 }

 static uint8_t
 modern_get_status(struct virtio_hw *hw)
 {
-       return io_read8(&hw->common_cfg->device_status);
+       return hw->vtpci_access_ops->modern_read8(hw,
+                       &hw->common_cfg->device_status);
 }

 static void
 modern_set_status(struct virtio_hw *hw, uint8_t status)
 {
-       io_write8(&hw->common_cfg->device_status, status);
+       hw->vtpci_access_ops->modern_write8(hw,
+                       &hw->common_cfg->device_status, status);
 }

 static void
@@ -577,21 +772,25 @@ modern_reset(struct virtio_hw *hw)
 static uint8_t
 modern_get_isr(struct virtio_hw *hw)
 {
-       return io_read8(hw->isr);
+       return hw->vtpci_access_ops->modern_read8(hw, hw->isr);
 }

 static uint16_t
 modern_set_config_irq(struct virtio_hw *hw, uint16_t vec)
 {
-       io_write16(&hw->common_cfg->msix_config, vec);
-       return io_read16(&hw->common_cfg->msix_config);
+       hw->vtpci_access_ops->modern_write16(hw,
+                       &hw->common_cfg->msix_config, vec);
+       return hw->vtpci_access_ops->modern_read16(hw,
+                       &hw->common_cfg->msix_config);
 }

 static uint16_t
 modern_get_queue_num(struct virtio_hw *hw, uint16_t queue_id)
 {
-       io_write16(&hw->common_cfg->queue_select, queue_id);
-       return io_read16(&hw->common_cfg->queue_size);
+       hw->vtpci_access_ops->modern_write16(hw,
+                       &hw->common_cfg->queue_select, queue_id);
+       return hw->vtpci_access_ops->modern_read16(hw,
+                       &hw->common_cfg->queue_size);
 }

 static void
@@ -606,20 +805,23 @@ modern_setup_queue(struct virtio_hw *hw, struct virtqueue 
*vq)
                                                         ring[vq->vq_nentries]),
                                   VIRTIO_PCI_VRING_ALIGN);

-       io_write16(&hw->common_cfg->queue_select, vq->vq_queue_index);
+       hw->vtpci_access_ops->modern_write16(hw,
+                       &hw->common_cfg->queue_select, vq->vq_queue_index);

-       io_write64_twopart(&hw->common_cfg->queue_desc_lo,
+       io_write64_twopart(hw, &hw->common_cfg->queue_desc_lo,
                           &hw->common_cfg->queue_desc_hi, desc_addr);
-       io_write64_twopart(&hw->common_cfg->queue_avail_lo,
+       io_write64_twopart(hw, &hw->common_cfg->queue_avail_lo,
                           &hw->common_cfg->queue_avail_hi, avail_addr);
-       io_write64_twopart(&hw->common_cfg->queue_used_lo,
+       io_write64_twopart(hw, &hw->common_cfg->queue_used_lo,
                           &hw->common_cfg->queue_used_hi, used_addr);

-       notify_off = io_read16(&hw->common_cfg->queue_notify_off);
+       notify_off = hw->vtpci_access_ops->modern_read16(hw,
+                               &hw->common_cfg->queue_notify_off);
        vq->notify_addr = (void *)((uint8_t *)hw->notify_base +
                                notify_off * hw->notify_off_multiplier);

-       io_write16(&hw->common_cfg->queue_enable, 1);
+       hw->vtpci_access_ops->modern_write16(hw,
+                       &hw->common_cfg->queue_enable, 1);

        PMD_INIT_LOG(DEBUG, "queue %u addresses:", vq->vq_queue_index);
        PMD_INIT_LOG(DEBUG, "\t desc_addr: %"PRIx64, desc_addr);
@@ -632,22 +834,24 @@ modern_setup_queue(struct virtio_hw *hw, struct virtqueue 
*vq)
 static void
 modern_del_queue(struct virtio_hw *hw, struct virtqueue *vq)
 {
-       io_write16(&hw->common_cfg->queue_select, vq->vq_queue_index);
+       hw->vtpci_access_ops->modern_write16(hw,
+                       &hw->common_cfg->queue_select, vq->vq_queue_index);

-       io_write64_twopart(&hw->common_cfg->queue_desc_lo,
+       io_write64_twopart(hw, &hw->common_cfg->queue_desc_lo,
                           &hw->common_cfg->queue_desc_hi, 0);
-       io_write64_twopart(&hw->common_cfg->queue_avail_lo,
+       io_write64_twopart(hw, &hw->common_cfg->queue_avail_lo,
                           &hw->common_cfg->queue_avail_hi, 0);
-       io_write64_twopart(&hw->common_cfg->queue_used_lo,
+       io_write64_twopart(hw, &hw->common_cfg->queue_used_lo,
                           &hw->common_cfg->queue_used_hi, 0);

-       io_write16(&hw->common_cfg->queue_enable, 0);
+       hw->vtpci_access_ops->modern_write16(hw,
+                       &hw->common_cfg->queue_enable, 0);
 }

 static void
 modern_notify_queue(struct virtio_hw *hw __rte_unused, struct virtqueue *vq)
 {
-       io_write16(vq->notify_addr, 1);
+       hw->vtpci_access_ops->modern_write16(hw, vq->notify_addr, 1);
 }

 static const struct virtio_pci_ops modern_ops = {
@@ -666,7 +870,6 @@ static const struct virtio_pci_ops modern_ops = {
        .notify_queue   = modern_notify_queue,
 };

-
 void
 vtpci_read_dev_config(struct virtio_hw *hw, uint64_t offset,
                      void *dst, int length)
@@ -739,55 +942,28 @@ vtpci_irq_config(struct virtio_hw *hw, uint16_t vec)
        return hw->vtpci_ops->set_config_irq(hw, vec);
 }

-static void *
-get_cfg_addr(struct rte_pci_device *dev, struct virtio_pci_cap *cap)
-{
-       uint8_t  bar    = cap->bar;
-       uint32_t length = cap->length;
-       uint32_t offset = cap->offset;
-       uint8_t *base;
-
-       if (bar > 5) {
-               PMD_INIT_LOG(ERR, "invalid bar: %u", bar);
-               return NULL;
-       }
-
-       if (offset + length > dev->mem_resource[bar].len) {
-               PMD_INIT_LOG(ERR,
-                       "invalid cap: overflows bar space: %u > %"PRIu64,
-                       offset + length, dev->mem_resource[bar].len);
-               return NULL;
-       }
-
-       base = dev->mem_resource[bar].addr;
-       if (base == NULL) {
-               PMD_INIT_LOG(ERR, "bar %u base addr is NULL", bar);
-               return NULL;
-       }
-
-       return base + offset;
-}
-
 static int
-virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
+virtio_read_caps(struct virtio_hw *hw)
 {
        uint8_t pos;
        struct virtio_pci_cap cap;
        int ret;

-       if (rte_eal_pci_map_device(dev) < 0) {
+       if (hw->vtpci_access_ops->map_pci_cfg(hw) < 0) {
                PMD_INIT_LOG(DEBUG, "failed to map pci device!");
                return -1;
        }

-       ret = rte_eal_pci_read_config(dev, &pos, 1, PCI_CAPABILITY_LIST);
+       ret = hw->vtpci_access_ops->read_pci_cfg(
+                       hw, &pos, 1, PCI_CAPABILITY_LIST);
        if (ret < 0) {
                PMD_INIT_LOG(DEBUG, "failed to read pci capability list");
                return -1;
        }

        while (pos) {
-               ret = rte_eal_pci_read_config(dev, &cap, sizeof(cap), pos);
+               ret = hw->vtpci_access_ops->read_pci_cfg(
+                               hw, &cap, sizeof(cap), pos);
                if (ret < 0) {
                        PMD_INIT_LOG(ERR,
                                "failed to read pci cap at pos: %x", pos);
@@ -807,18 +983,22 @@ virtio_read_caps(struct rte_pci_device *dev, struct 
virtio_hw *hw)

                switch (cap.cfg_type) {
                case VIRTIO_PCI_CAP_COMMON_CFG:
-                       hw->common_cfg = get_cfg_addr(dev, &cap);
+                       hw->common_cfg =
+                               hw->vtpci_access_ops->get_cfg_addr(hw, &cap);
                        break;
                case VIRTIO_PCI_CAP_NOTIFY_CFG:
-                       rte_eal_pci_read_config(dev, &hw->notify_off_multiplier,
+                       hw->vtpci_access_ops->read_pci_cfg(hw,
+                                               &hw->notify_off_multiplier,
                                                4, pos + sizeof(cap));
-                       hw->notify_base = get_cfg_addr(dev, &cap);
+                       hw->notify_base =
+                               hw->vtpci_access_ops->get_cfg_addr(hw, &cap);
                        break;
                case VIRTIO_PCI_CAP_DEVICE_CFG:
-                       hw->dev_cfg = get_cfg_addr(dev, &cap);
+                       hw->dev_cfg =
+                               hw->vtpci_access_ops->get_cfg_addr(hw, &cap);
                        break;
                case VIRTIO_PCI_CAP_ISR_CFG:
-                       hw->isr = get_cfg_addr(dev, &cap);
+                       hw->isr = hw->vtpci_access_ops->get_cfg_addr(hw, &cap);
                        break;
                }

@@ -844,42 +1024,53 @@ virtio_read_caps(struct rte_pci_device *dev, struct 
virtio_hw *hw)
 }

 int
-vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw)
+vtpci_init(struct rte_eth_dev *eth_dev, struct virtio_hw *hw)
 {
-       hw->dev = dev;
+       struct rte_pci_device *pci_dev = eth_dev->pci_dev;
+
+       hw->dev = pci_dev;
+
+       if (pci_dev == NULL) {
+               PMD_INIT_LOG(INFO, "No pci device specified.");
+               return -1;
+       }
+
+       if (vtpci_access_init(eth_dev, hw) < 0)
+               return -1;

        /*
         * Try if we can succeed reading virtio pci caps, which exists
         * only on modern pci device. If failed, we fallback to legacy
         * virtio handling.
         */
-       if (virtio_read_caps(dev, hw) == 0) {
+       if (virtio_read_caps(hw) == 0) {
                PMD_INIT_LOG(INFO, "modern virtio pci detected.");
                hw->vtpci_ops = &modern_ops;
                hw->modern    = 1;
-               dev->driver->drv_flags |= RTE_PCI_DRV_INTR_LSC;
+               pci_dev->driver->drv_flags |= RTE_PCI_DRV_INTR_LSC;
                return 0;
        }

        PMD_INIT_LOG(INFO, "trying with legacy virtio pci.");
-       if (legacy_virtio_resource_init(dev) < 0)
+       if (legacy_virtio_resource_init(pci_dev) < 0)
                return -1;

        hw->vtpci_ops = &legacy_ops;
-       hw->use_msix = legacy_virtio_has_msix(&dev->addr);
-       hw->io_base  = (uint32_t)(uintptr_t)dev->mem_resource[0].addr;
+       hw->use_msix = legacy_virtio_has_msix(&pci_dev->addr);
+       hw->io_base  = (uint32_t)(uintptr_t)pci_dev->mem_resource[0].addr;
        hw->modern   = 0;

        return 0;
 }

 void
-vtpci_uninit(struct rte_pci_device *dev, struct virtio_hw *hw)
+vtpci_uninit(struct rte_eth_dev *eth_dev, struct virtio_hw *hw)
 {
        hw->dev  = NULL;
        hw->vtpci_ops = NULL;
        hw->use_msix = 0;
        hw->io_base  = 0;
        hw->modern   = 0;
-       rte_eal_pci_unmap_device(dev);
+       hw->vtpci_access_ops->unmap_pci_cfg(hw);
+       vtpci_access_uninit(eth_dev, hw);
 }
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index ec1d46b..b102679 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -222,6 +222,35 @@ struct virtio_pci_common_cfg {

 struct virtio_hw;

+struct virtio_pci_access_ops {
+       uint8_t (*legacy_read8)(struct virtio_hw *hw, uint8_t *addr);
+       uint16_t (*legacy_read16)(struct virtio_hw *hw, uint16_t *addr);
+       uint32_t (*legacy_read32)(struct virtio_hw *hw, uint32_t *addr);
+       void (*legacy_write8)(struct virtio_hw *hw,
+                               uint8_t *addr, uint8_t val);
+       void (*legacy_write16)(struct virtio_hw *hw,
+                               uint16_t *addr, uint16_t val);
+       void (*legacy_write32)(struct virtio_hw *hw,
+                               uint32_t *addr, uint32_t val);
+
+       uint8_t (*modern_read8)(struct virtio_hw *hw, uint8_t *addr);
+       uint16_t (*modern_read16)(struct virtio_hw *hw, uint16_t *addr);
+       uint32_t (*modern_read32)(struct virtio_hw *hw, uint32_t *addr);
+       void (*modern_write8)(struct virtio_hw *hw,
+                               uint8_t *addr, uint8_t val);
+       void (*modern_write16)(struct virtio_hw *hw,
+                               uint16_t *addr, uint16_t val);
+       void (*modern_write32)(struct virtio_hw *hw,
+                               uint32_t *addr, uint32_t val);
+
+       int (*map_pci_cfg)(struct virtio_hw *hw);
+       void (*unmap_pci_cfg)(struct virtio_hw *hw);
+       void *(*get_cfg_addr)(struct virtio_hw *hw,
+                               struct virtio_pci_cap *cap);
+       int (*read_pci_cfg)(struct virtio_hw *hw,
+                               void *buf, size_t len, off_t offset);
+};
+
 struct virtio_pci_ops {
        void (*read_dev_cfg)(struct virtio_hw *hw, uint64_t offset,
                             void *dst, int len);
@@ -266,6 +295,7 @@ struct virtio_hw {
        struct virtio_pci_common_cfg *common_cfg;
        struct virtio_net_config *dev_cfg;
        const struct virtio_pci_ops *vtpci_ops;
+       const struct virtio_pci_access_ops *vtpci_access_ops;
 };

 /*
@@ -327,8 +357,8 @@ vtpci_with_feature(struct virtio_hw *hw, uint64_t bit)
 /*
  * Function declaration from virtio_pci.c
  */
-int vtpci_init(struct rte_pci_device *, struct virtio_hw *);
-void vtpci_uninit(struct rte_pci_device *dev, struct virtio_hw *);
+int vtpci_init(struct rte_eth_dev *, struct virtio_hw *);
+void vtpci_uninit(struct rte_eth_dev *, struct virtio_hw *);
 void vtpci_reset(struct virtio_hw *);

 void vtpci_reinit_complete(struct virtio_hw *);
-- 
2.1.4

Reply via email to