DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL
@ 2017-08-25  9:04 Gaetan Rivet
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 01/13] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
                   ` (13 more replies)
  0 siblings, 14 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-08-25  9:04 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Hi all,

Here is a new version of the PCI bus move out of the EAL.

The EAL PCI implementation is divided in two parts:

  - librte_pci: library offering helpers to handle PCI objects
  - librte_bus_pci: bus driver for PCI devices

This allows other libraries / tools to use PCI elements (location, mappings,
parsing operations, etc) without forcing a dependency on a bus driver.

The latter should not have to export helpers that others might need. It
is focused on defining the rte_pci_device, rte_pci_driver objects and
their handling.

The cryptodev library has hard dependencies on rte_pci_devices (used by
generic probe function). Other similar libs (ether and eventdev) avoided
the issue by inlining such functions and expecting users to include the
relevant headers once the PCI bus has already been built.

Declan, I proposed a solution that would avoid inlining those functions,
which does not feel right. Let me know what you think of it or if you
think of a better solution. I think it would be best to have cryptodev
completely independent from PCI / vdev as far as the lib in concerned
(the vdev bus will move as well).

TODO:

  - Verify that the lib / bus divide is correct.
  - Expose additional EAL functions the PCI bus is dependent upon.
    The PCI bus is currently dirty. It should be fixed.
  - rte_eal_using_phys_addrs is currently linux-only, the symbol will be
    exposed on BSD as well (even if not implemented). This remark has
    been made already last release, but wasn't properly addressed.

Gaetan Rivet (13):
  eal: expose rte_eal_using_phys_addrs
  ethdev: remove useless PCI dependency
  bus: properly include rte_debug
  eal: remove references to PCI
  pci: introduce PCI lib and bus
  pci: avoid inlining functions
  pci: avoid over-complicated macro
  pci: deprecate misnamed functions
  lib: include rte_bus_pci
  drivers: include rte_bus_pci
  test: include rte_bus_pci
  app/testpmd: include rte_bus_pci
  cryptodev: move PCI specific helpers to drivers/crypto

 app/test-pmd/testpmd.h                           |   1 +
 config/common_base                               |  15 +
 doc/guides/rel_notes/deprecation.rst             |  10 +
 drivers/Makefile                                 |   2 +-
 drivers/bus/Makefile                             |   2 +
 drivers/bus/pci/Makefile                         |  60 ++
 drivers/bus/pci/bsd/Makefile                     |  32 +
 drivers/bus/pci/bsd/rte_pci.c                    | 671 +++++++++++++++++++++
 drivers/bus/pci/include/rte_bus_pci.h            | 387 ++++++++++++
 drivers/bus/pci/linux/Makefile                   |  37 ++
 drivers/bus/pci/linux/rte_pci.c                  | 724 +++++++++++++++++++++++
 drivers/bus/pci/linux/rte_pci_init.h             |  97 +++
 drivers/bus/pci/linux/rte_pci_uio.c              | 568 ++++++++++++++++++
 drivers/bus/pci/linux/rte_pci_vfio.c             | 675 +++++++++++++++++++++
 drivers/bus/pci/linux/rte_vfio_mp_sync.c         | 425 +++++++++++++
 drivers/bus/pci/private.h                        | 174 ++++++
 drivers/bus/pci/rte_bus_pci_version.map          |  21 +
 drivers/bus/pci/rte_pci_common.c                 | 543 +++++++++++++++++
 drivers/bus/pci/rte_pci_common_uio.c             | 235 ++++++++
 drivers/crypto/Makefile                          |   4 +-
 drivers/crypto/pci/Makefile                      |  52 ++
 drivers/crypto/pci/rte_cryptodev_pci.c           | 128 ++++
 drivers/crypto/pci/rte_cryptodev_pci.h           |  94 +++
 drivers/crypto/pci/rte_cryptodev_pci_version.map |   7 +
 drivers/crypto/qat/qat_qp.c                      |   1 +
 drivers/event/octeontx/ssovf_probe.c             |   1 +
 drivers/net/ark/ark_ethdev.c                     |   1 +
 drivers/net/avp/avp_ethdev.c                     |   2 +
 drivers/net/bnxt/bnxt.h                          |   1 +
 drivers/net/bonding/rte_eth_bond_args.c          |   1 +
 drivers/net/cxgbe/base/adapter.h                 |   1 +
 drivers/net/cxgbe/cxgbe_ethdev.c                 |   1 +
 drivers/net/e1000/em_ethdev.c                    |   1 +
 drivers/net/e1000/igb_ethdev.c                   |   1 +
 drivers/net/e1000/igb_pf.c                       |   1 +
 drivers/net/ena/ena_ethdev.h                     |   1 +
 drivers/net/enic/base/vnic_dev.h                 |   4 +-
 drivers/net/enic/enic_ethdev.c                   |   1 +
 drivers/net/enic/enic_main.c                     |   1 +
 drivers/net/i40e/i40e_ethdev.c                   |   1 +
 drivers/net/i40e/i40e_ethdev_vf.c                |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c                 |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.h                 |   1 +
 drivers/net/mlx5/mlx5.c                          |   1 +
 drivers/net/mlx5/mlx5_ethdev.c                   |   1 +
 drivers/net/sfc/sfc.h                            |   1 +
 drivers/net/sfc/sfc_ethdev.c                     |   1 +
 drivers/net/thunderx/nicvf_ethdev.c              |   1 +
 drivers/net/virtio/virtio_ethdev.c               |   1 +
 drivers/net/virtio/virtio_pci.h                  |   1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c             |   1 +
 lib/Makefile                                     |   2 +
 lib/librte_cryptodev/Makefile                    |   1 -
 lib/librte_cryptodev/rte_cryptodev_pci.h         |  92 ---
 lib/librte_cryptodev/rte_cryptodev_pmd.c         |  94 ---
 lib/librte_cryptodev/rte_cryptodev_version.map   |   2 -
 lib/librte_eal/bsdapp/eal/Makefile               |   3 -
 lib/librte_eal/bsdapp/eal/eal.c                  |   1 -
 lib/librte_eal/bsdapp/eal/eal_pci.c              | 670 ---------------------
 lib/librte_eal/common/Makefile                   |   2 +-
 lib/librte_eal/common/eal_common_bus.c           |   1 +
 lib/librte_eal/common/eal_common_pci.c           | 580 ------------------
 lib/librte_eal/common/eal_common_pci_uio.c       | 233 --------
 lib/librte_eal/common/eal_private.h              | 143 -----
 lib/librte_eal/common/include/rte_pci.h          | 598 -------------------
 lib/librte_eal/linuxapp/eal/Makefile             |  12 +-
 lib/librte_eal/linuxapp/eal/eal.c                |   1 -
 lib/librte_eal/linuxapp/eal/eal_interrupts.c     |   1 -
 lib/librte_eal/linuxapp/eal/eal_memory.c         |   3 +-
 lib/librte_eal/linuxapp/eal/eal_pci.c            | 722 ----------------------
 lib/librte_eal/linuxapp/eal/eal_pci_init.h       |  97 ---
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c        | 567 ------------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c       | 674 ---------------------
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c   | 424 -------------
 lib/librte_eal/linuxapp/eal/rte_eal_version.map  |   1 +
 lib/librte_eal/linuxapp/eal/rte_memory_linux.h   |  64 ++
 lib/librte_ether/rte_ethdev.c                    |   1 -
 lib/librte_ether/rte_ethdev.h                    |   2 -
 lib/librte_ether/rte_ethdev_pci.h                |   1 +
 lib/librte_eventdev/rte_eventdev_pmd_pci.h       |   1 +
 lib/librte_pci/Makefile                          |  49 ++
 lib/librte_pci/include/rte_pci.h                 | 285 +++++++++
 lib/librte_pci/rte_pci.c                         | 210 +++++++
 lib/librte_pci/rte_pci_version.map               |  16 +
 mk/rte.app.mk                                    |   3 +
 test/test/virtual_pmd.c                          |   1 +
 86 files changed, 5631 insertions(+), 4921 deletions(-)
 create mode 100644 drivers/bus/pci/Makefile
 create mode 100644 drivers/bus/pci/bsd/Makefile
 create mode 100644 drivers/bus/pci/bsd/rte_pci.c
 create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
 create mode 100644 drivers/bus/pci/linux/Makefile
 create mode 100644 drivers/bus/pci/linux/rte_pci.c
 create mode 100644 drivers/bus/pci/linux/rte_pci_init.h
 create mode 100644 drivers/bus/pci/linux/rte_pci_uio.c
 create mode 100644 drivers/bus/pci/linux/rte_pci_vfio.c
 create mode 100644 drivers/bus/pci/linux/rte_vfio_mp_sync.c
 create mode 100644 drivers/bus/pci/private.h
 create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
 create mode 100644 drivers/bus/pci/rte_pci_common.c
 create mode 100644 drivers/bus/pci/rte_pci_common_uio.c
 create mode 100644 drivers/crypto/pci/Makefile
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.c
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.h
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci_version.map
 delete mode 100644 lib/librte_cryptodev/rte_cryptodev_pci.h
 delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
 delete mode 100644 lib/librte_eal/common/include/rte_pci.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
 create mode 100644 lib/librte_eal/linuxapp/eal/rte_memory_linux.h
 create mode 100644 lib/librte_pci/Makefile
 create mode 100644 lib/librte_pci/include/rte_pci.h
 create mode 100644 lib/librte_pci/rte_pci.c
 create mode 100644 lib/librte_pci/rte_pci_version.map

-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH 01/13] eal: expose rte_eal_using_phys_addrs
  2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
@ 2017-08-25  9:04 ` Gaetan Rivet
  2017-09-04 13:24   ` Burakov, Anatoly
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 02/13] ethdev: remove useless PCI dependency Gaetan Rivet
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 156+ messages in thread
From: Gaetan Rivet @ 2017-08-25  9:04 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

This function was previously private to the EAL layer.
Other subsystems requires it, such as the PCI bus.

This function is only exposed for linuxapps.

In order not to force other components to include stdbool, which is
incompatible with several NIC drivers, the return type has
been changed from bool to int.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_private.h             | 11 -----
 lib/librte_eal/linuxapp/eal/Makefile            |  2 +
 lib/librte_eal/linuxapp/eal/eal_memory.c        |  3 +-
 lib/librte_eal/linuxapp/eal/eal_pci.c           |  1 +
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  1 +
 lib/librte_eal/linuxapp/eal/rte_memory_linux.h  | 64 +++++++++++++++++++++++++
 6 files changed, 70 insertions(+), 12 deletions(-)
 create mode 100644 lib/librte_eal/linuxapp/eal/rte_memory_linux.h

diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 597d82e..10a7078 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -333,17 +333,6 @@ int rte_eal_hugepage_init(void);
 int rte_eal_hugepage_attach(void);
 
 /**
- * Returns true if the system is able to obtain
- * physical addresses. Return false if using DMA
- * addresses through an IOMMU.
- *
- * Drivers based on uio will not load unless physical
- * addresses are obtainable. It is only possible to get
- * physical addresses when running as a privileged user.
- */
-bool rte_eal_using_phys_addrs(void);
-
-/**
  * Find a bus capable of identifying a device.
  *
  * @param str
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 90bca4d..ad7e34a 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -135,4 +135,6 @@ INC := rte_interrupts.h rte_kni_common.h rte_dom0_common.h
 SYMLINK-$(CONFIG_RTE_EXEC_ENV_LINUXAPP)-include/exec-env := \
 	$(addprefix include/exec-env/,$(INC))
 
+SYMLINK-$(CONFIG_RTE_EXEC_ENV_LINUXAPP)-include += rte_memory_linux.h
+
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
index 5279128..6639670 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -72,6 +72,7 @@
 #include "eal_internal_cfg.h"
 #include "eal_filesystem.h"
 #include "eal_hugepages.h"
+#include "rte_memory_linux.h"
 
 #define PFN_MASK_SIZE	8
 
@@ -1542,7 +1543,7 @@ rte_eal_hugepage_attach(void)
 	return -1;
 }
 
-bool
+int
 rte_eal_using_phys_addrs(void)
 {
 	return phys_addrs_available;
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 8951ce7..8f658d6 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -45,6 +45,7 @@
 #include "eal_filesystem.h"
 #include "eal_private.h"
 #include "eal_pci_init.h"
+#include "rte_memory_linux.h"
 
 /**
  * @file
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 3a8f154..5cfd934 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -206,6 +206,7 @@ DPDK_17.08 {
 	rte_bus_find_by_device;
 	rte_bus_find_by_name;
 	rte_log_get_level;
+	rte_eal_using_phys_addrs;
 
 } DPDK_17.05;
 
diff --git a/lib/librte_eal/linuxapp/eal/rte_memory_linux.h b/lib/librte_eal/linuxapp/eal/rte_memory_linux.h
new file mode 100644
index 0000000..0400711
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/rte_memory_linux.h
@@ -0,0 +1,64 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_MEMORY_LINUX_H_
+#define _RTE_MEMORY_LINUX_H_
+
+/**
+ * @file
+ *
+ * Memory-related Linux-specific RTE API.
+ */
+
+#include <rte_memory.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Drivers based on uio will not load unless physical
+ * addresses are obtainable. It is only possible to get
+ * physical addresses when running as a privileged user.
+ *
+ * @return
+ *   1 if the system is able to obtain physical addresses.
+ *   0 if using DMA addresses through an IOMMU.
+ */
+int rte_eal_using_phys_addrs(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_MEMORY_LINUX_H_ */
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH 02/13] ethdev: remove useless PCI dependency
  2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 01/13] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
@ 2017-08-25  9:04 ` Gaetan Rivet
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 03/13] bus: properly include rte_debug Gaetan Rivet
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-08-25  9:04 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ether/rte_ethdev.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 0597641..9b879f7 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -47,7 +47,6 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_interrupts.h>
-#include <rte_pci.h>
 #include <rte_memory.h>
 #include <rte_memcpy.h>
 #include <rte_memzone.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH 03/13] bus: properly include rte_debug
  2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 01/13] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 02/13] ethdev: remove useless PCI dependency Gaetan Rivet
@ 2017-08-25  9:04 ` Gaetan Rivet
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 04/13] eal: remove references to PCI Gaetan Rivet
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-08-25  9:04 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_bus.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
index 08bec2d..9d1be8a 100644
--- a/lib/librte_eal/common/eal_common_bus.c
+++ b/lib/librte_eal/common/eal_common_bus.c
@@ -35,6 +35,7 @@
 #include <sys/queue.h>
 
 #include <rte_bus.h>
+#include <rte_debug.h>
 
 #include "eal_private.h"
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH 04/13] eal: remove references to PCI
  2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
                   ` (2 preceding siblings ...)
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 03/13] bus: properly include rte_debug Gaetan Rivet
@ 2017-08-25  9:04 ` Gaetan Rivet
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 05/13] pci: introduce PCI lib and bus Gaetan Rivet
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-08-25  9:04 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/bsdapp/eal/eal.c              |   1 -
 lib/librte_eal/common/eal_private.h          | 132 ---------------------------
 lib/librte_eal/linuxapp/eal/eal.c            |   1 -
 lib/librte_eal/linuxapp/eal/eal_interrupts.c |   1 -
 4 files changed, 135 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 5fa5988..b7c045f 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -66,7 +66,6 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_bus.h>
-#include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_version.h>
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 10a7078..fc504ef 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,7 +36,6 @@
 
 #include <stdbool.h>
 #include <stdio.h>
-#include <rte_pci.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -109,137 +108,6 @@ int rte_eal_timer_init(void);
  */
 int rte_eal_log_init(const char *id, int facility);
 
-struct rte_pci_driver;
-struct rte_pci_device;
-
-/**
- * Find the name of a PCI device.
- */
-void pci_name_set(struct rte_pci_device *dev);
-
-/**
- * Add a PCI device to the PCI Bus (append to PCI Device list). This function
- * also updates the bus references of the PCI Device (and the generic device
- * object embedded within.
- *
- * @param pci_dev
- *	PCI device to add
- * @return void
- */
-void rte_pci_add_device(struct rte_pci_device *pci_dev);
-
-/**
- * Insert a PCI device in the PCI Bus at a particular location in the device
- * list. It also updates the PCI Bus reference of the new devices to be
- * inserted.
- *
- * @param exist_pci_dev
- *	Existing PCI device in PCI Bus
- * @param new_pci_dev
- *	PCI device to be added before exist_pci_dev
- * @return void
- */
-void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
-		struct rte_pci_device *new_pci_dev);
-
-/**
- * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
- * in the PCI device object as well as the generic device object.
- *
- * @param pci_device
- *	PCI device to be removed from PCI Bus
- * @return void
- */
-void rte_pci_remove_device(struct rte_pci_device *pci_device);
-
-/**
- * Update a pci device object by asking the kernel for the latest information.
- *
- * This function is private to EAL.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to look for
- * @return
- *   - 0 on success.
- *   - negative on error.
- */
-int pci_update_device(const struct rte_pci_addr *addr);
-
-/**
- * Unbind kernel driver for this device
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int pci_unbind_kernel_driver(struct rte_pci_device *dev);
-
-/**
- * Map the PCI resource of a PCI device in virtual memory
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_map_resource(struct rte_pci_device *dev);
-
-/**
- * Unmap the PCI resource of a PCI device
- *
- * This function is private to EAL.
- */
-void pci_uio_unmap_resource(struct rte_pci_device *dev);
-
-/**
- * Allocate uio resource for PCI device
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device to allocate uio resource
- * @param uio_res
- *   Pointer to uio resource.
- *   If the function returns 0, the pointer will be filled.
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res);
-
-/**
- * Free uio resource for PCI device
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device to free uio resource
- * @param uio_res
- *   Pointer to uio resource.
- */
-void pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res);
-
-/**
- * Map device memory to uio resource
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device that has memory information.
- * @param res_idx
- *   Memory resource index of the PCI device.
- * @param uio_res
- *  uio resource that will keep mapping information.
- * @param map_idx
- *   Mapping information index of the uio resource.
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx);
-
 /**
  * Init tail queues for non-EAL library structures. This is to allow
  * the rings, mempools, etc. lists to be shared among multiple processes
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 48f12f4..f72da15 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -71,7 +71,6 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_bus.h>
-#include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_version.h>
diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
index 3e9ac41..0bebf00 100644
--- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
@@ -60,7 +60,6 @@
 #include <rte_branch_prediction.h>
 #include <rte_debug.h>
 #include <rte_log.h>
-#include <rte_pci.h>
 #include <rte_malloc.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH 05/13] pci: introduce PCI lib and bus
  2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
                   ` (3 preceding siblings ...)
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 04/13] eal: remove references to PCI Gaetan Rivet
@ 2017-08-25  9:04 ` Gaetan Rivet
  2017-08-25  9:31   ` Luca Boccassi
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 06/13] pci: avoid inlining functions Gaetan Rivet
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 156+ messages in thread
From: Gaetan Rivet @ 2017-08-25  9:04 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

The PCI lib defines the types and methods allowing to use PCI elements.

The PCI bus implements a bus driver for PCI devices by constructing
rte_bus elements using the PCI lib.

Move the relevant code out of the EAL to their expected place.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 config/common_base                             |  15 +
 drivers/bus/Makefile                           |   2 +
 drivers/bus/pci/Makefile                       |  60 ++
 drivers/bus/pci/bsd/Makefile                   |  32 ++
 drivers/bus/pci/bsd/rte_pci.c                  | 670 +++++++++++++++++++++++
 drivers/bus/pci/include/rte_bus_pci.h          | 387 +++++++++++++
 drivers/bus/pci/linux/Makefile                 |  37 ++
 drivers/bus/pci/linux/rte_pci.c                | 723 +++++++++++++++++++++++++
 drivers/bus/pci/linux/rte_pci_init.h           |  97 ++++
 drivers/bus/pci/linux/rte_pci_uio.c            | 567 +++++++++++++++++++
 drivers/bus/pci/linux/rte_pci_vfio.c           | 674 +++++++++++++++++++++++
 drivers/bus/pci/linux/rte_vfio_mp_sync.c       | 424 +++++++++++++++
 drivers/bus/pci/private.h                      | 173 ++++++
 drivers/bus/pci/rte_bus_pci_version.map        |  21 +
 drivers/bus/pci/rte_pci_common.c               | 542 ++++++++++++++++++
 drivers/bus/pci/rte_pci_common_uio.c           | 234 ++++++++
 lib/Makefile                                   |   2 +
 lib/librte_eal/bsdapp/eal/Makefile             |   3 -
 lib/librte_eal/bsdapp/eal/eal_pci.c            | 670 -----------------------
 lib/librte_eal/common/Makefile                 |   2 +-
 lib/librte_eal/common/eal_common_pci.c         | 580 --------------------
 lib/librte_eal/common/eal_common_pci_uio.c     | 233 --------
 lib/librte_eal/common/include/rte_pci.h        | 598 --------------------
 lib/librte_eal/linuxapp/eal/Makefile           |  10 -
 lib/librte_eal/linuxapp/eal/eal_pci.c          | 723 -------------------------
 lib/librte_eal/linuxapp/eal/eal_pci_init.h     |  97 ----
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c      | 567 -------------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c     | 674 -----------------------
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c | 424 ---------------
 lib/librte_ether/rte_ethdev.h                  |   2 -
 lib/librte_pci/Makefile                        |  49 ++
 lib/librte_pci/include/rte_pci.h               | 279 ++++++++++
 lib/librte_pci/rte_pci.c                       |  92 ++++
 lib/librte_pci/rte_pci_version.map             |   8 +
 mk/rte.app.mk                                  |   3 +
 35 files changed, 5092 insertions(+), 4582 deletions(-)
 create mode 100644 drivers/bus/pci/Makefile
 create mode 100644 drivers/bus/pci/bsd/Makefile
 create mode 100644 drivers/bus/pci/bsd/rte_pci.c
 create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
 create mode 100644 drivers/bus/pci/linux/Makefile
 create mode 100644 drivers/bus/pci/linux/rte_pci.c
 create mode 100644 drivers/bus/pci/linux/rte_pci_init.h
 create mode 100644 drivers/bus/pci/linux/rte_pci_uio.c
 create mode 100644 drivers/bus/pci/linux/rte_pci_vfio.c
 create mode 100644 drivers/bus/pci/linux/rte_vfio_mp_sync.c
 create mode 100644 drivers/bus/pci/private.h
 create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
 create mode 100644 drivers/bus/pci/rte_pci_common.c
 create mode 100644 drivers/bus/pci/rte_pci_common_uio.c
 delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
 delete mode 100644 lib/librte_eal/common/include/rte_pci.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
 create mode 100644 lib/librte_pci/Makefile
 create mode 100644 lib/librte_pci/include/rte_pci.h
 create mode 100644 lib/librte_pci/rte_pci.c
 create mode 100644 lib/librte_pci/rte_pci_version.map

diff --git a/config/common_base b/config/common_base
index 5e97a08..6141a65 100644
--- a/config/common_base
+++ b/config/common_base
@@ -122,6 +122,11 @@ CONFIG_RTE_EAL_PMD_PATH=""
 CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
 
 #
+# Compile the PCI library
+#
+CONFIG_RTE_LIBRTE_PCI=y
+
+#
 # Compile the argument parser library
 #
 CONFIG_RTE_LIBRTE_KVARGS=y
@@ -146,6 +151,16 @@ CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
 CONFIG_RTE_ETHDEV_TX_PREPARE_NOOP=n
 
 #
+# Support NIC bypass logic
+#
+CONFIG_RTE_NIC_BYPASS=n
+
+#
+# Compile PCI bus driver
+#
+CONFIG_RTE_LIBRTE_PCI_BUS=y
+
+#
 # Compile burst-oriented Amazon ENA PMD driver
 #
 CONFIG_RTE_LIBRTE_ENA_PMD=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 0224214..4b5bafe 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -34,5 +34,7 @@ core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
 
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DEPDIRS-fslmc = $(core-libs)
+DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
+DEPDIRS-pci = $(core-libs)
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/pci/Makefile b/drivers/bus/pci/Makefile
new file mode 100644
index 0000000..71530b7
--- /dev/null
+++ b/drivers/bus/pci/Makefile
@@ -0,0 +1,60 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+LIB = librte_bus_pci.a
+LIBABIVER := 1
+EXPORT_MAP := rte_bus_pci_version.map
+
+CFLAGS += $(WERROR_FLAGS) -O3
+CFLAGS += -I$(RTE_SDK)/drivers/bus/pci
+CFLAGS += -I$(RTE_SDK)/drivers/bus/pci/include
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),)
+SYSTEM := linux
+endif
+ifneq ($(CONFIG_RTE_EXEC_ENV_BSDAPP),)
+SYSTEM := bsd
+endif
+
+CFLAGS += -I$(RTE_SDK)/drivers/bus/pci/$(SYSTEM)
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/$(SYSTEM)app/eal
+
+include $(RTE_SDK)/drivers/bus/pci/$(SYSTEM)/Makefile
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) := $(addprefix $(SYSTEM)/,$(SRCS))
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += rte_pci_common.c
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += rte_pci_common_uio.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI_BUS)-include += include/rte_bus_pci.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/pci/bsd/Makefile b/drivers/bus/pci/bsd/Makefile
new file mode 100644
index 0000000..77cf539
--- /dev/null
+++ b/drivers/bus/pci/bsd/Makefile
@@ -0,0 +1,32 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += rte_pci.c
diff --git a/drivers/bus/pci/bsd/rte_pci.c b/drivers/bus/pci/bsd/rte_pci.c
new file mode 100644
index 0000000..5bd0f4b
--- /dev/null
+++ b/drivers/bus/pci/bsd/rte_pci.c
@@ -0,0 +1,670 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/pciio.h>
+#include <dev/pci/pcireg.h>
+
+#if defined(RTE_ARCH_X86)
+#include <machine/cpufunc.h>
+#endif
+
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_common.h>
+#include <rte_launch.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+#include <rte_debug.h>
+#include <rte_devargs.h>
+
+#include "eal_filesystem.h"
+#include "private.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in
+ * sysfs. Moreover, when a registered driver matches a device, the
+ * kernel driver currently using it is unloaded and replaced by
+ * igb_uio module, which is a very minimal userland driver for Intel
+ * network card, only providing access to PCI BAR to applications, and
+ * enabling bus master.
+ */
+
+extern struct rte_pci_bus rte_pci_bus;
+
+/* Map pci device */
+int
+rte_pci_map_device(struct rte_pci_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources */
+	switch (dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		/* map resources for devices that use uio */
+		ret = pci_uio_map_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+/* Unmap pci device */
+void
+rte_pci_unmap_device(struct rte_pci_device *dev)
+{
+	/* try unmapping the NIC resources */
+	switch (dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		/* unmap resources for devices that use uio */
+		pci_uio_unmap_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+void
+pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res)
+{
+	rte_free(uio_res);
+
+	if (dev->intr_handle.fd) {
+		close(dev->intr_handle.fd);
+		dev->intr_handle.fd = -1;
+		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	}
+}
+
+int
+pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res)
+{
+	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+
+	snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
+			dev->addr.bus, dev->addr.devid, dev->addr.function);
+
+	if (access(devname, O_RDWR) < 0) {
+		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+		return 1;
+	}
+
+	/* save fd if in primary process */
+	dev->intr_handle.fd = open(devname, O_RDWR);
+	if (dev->intr_handle.fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			devname, strerror(errno));
+		goto error;
+	}
+	dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+
+	/* allocate the mapping details for secondary processes*/
+	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
+	if (*uio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto error;
+	}
+
+	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
+	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
+
+	return 0;
+
+error:
+	pci_uio_free_resource(dev, *uio_res);
+	return -1;
+}
+
+int
+pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx)
+{
+	int fd;
+	char *devname;
+	void *mapaddr;
+	uint64_t offset;
+	uint64_t pagesz;
+	struct pci_map *maps;
+
+	maps = uio_res->maps;
+	devname = uio_res->path;
+	pagesz = sysconf(_SC_PAGESIZE);
+
+	/* allocate memory to keep path */
+	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+	if (maps[map_idx].path == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+				strerror(errno));
+		return -1;
+	}
+
+	/*
+	 * open resource file, to mmap it
+	 */
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				devname, strerror(errno));
+		goto error;
+	}
+
+	/* if matching map is found, then use it */
+	offset = res_idx * pagesz;
+	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
+			(size_t)dev->mem_resource[res_idx].len, 0);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		goto error;
+
+	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+	maps[map_idx].size = dev->mem_resource[res_idx].len;
+	maps[map_idx].addr = mapaddr;
+	maps[map_idx].offset = offset;
+	strcpy(maps[map_idx].path, devname);
+	dev->mem_resource[res_idx].addr = mapaddr;
+
+	return 0;
+
+error:
+	rte_free(maps[map_idx].path);
+	return -1;
+}
+
+static int
+pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
+{
+	struct rte_pci_device *dev;
+	struct pci_bar_io bar;
+	unsigned i, max;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL) {
+		return -1;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr.domain = conf->pc_sel.pc_domain;
+	dev->addr.bus = conf->pc_sel.pc_bus;
+	dev->addr.devid = conf->pc_sel.pc_dev;
+	dev->addr.function = conf->pc_sel.pc_func;
+
+	/* get vendor id */
+	dev->id.vendor_id = conf->pc_vendor;
+
+	/* get device id */
+	dev->id.device_id = conf->pc_device;
+
+	/* get subsystem_vendor id */
+	dev->id.subsystem_vendor_id = conf->pc_subvendor;
+
+	/* get subsystem_device id */
+	dev->id.subsystem_device_id = conf->pc_subdevice;
+
+	/* get class id */
+	dev->id.class_id = (conf->pc_class << 16) |
+			   (conf->pc_subclass << 8) |
+			   (conf->pc_progif);
+
+	/* TODO: get max_vfs */
+	dev->max_vfs = 0;
+
+	/* FreeBSD has no NUMA support (yet) */
+	dev->device.numa_node = 0;
+
+	pci_name_set(dev);
+
+	/* FreeBSD has only one pass through driver */
+	dev->kdrv = RTE_KDRV_NIC_UIO;
+
+	/* parse resources */
+	switch (conf->pc_hdr & PCIM_HDRTYPE) {
+	case PCIM_HDRTYPE_NORMAL:
+		max = PCIR_MAX_BAR_0;
+		break;
+	case PCIM_HDRTYPE_BRIDGE:
+		max = PCIR_MAX_BAR_1;
+		break;
+	case PCIM_HDRTYPE_CARDBUS:
+		max = PCIR_MAX_BAR_2;
+		break;
+	default:
+		goto skipdev;
+	}
+
+	for (i = 0; i <= max; i++) {
+		bar.pbi_sel = conf->pc_sel;
+		bar.pbi_reg = PCIR_BAR(i);
+		if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
+			continue;
+
+		dev->mem_resource[i].len = bar.pbi_length;
+		if (PCI_BAR_IO(bar.pbi_base)) {
+			dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
+			continue;
+		}
+		dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
+	}
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
+		rte_pci_add_device(dev);
+	}
+	else {
+		struct rte_pci_device *dev2 = NULL;
+		int ret;
+
+		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
+			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+			else if (ret < 0) {
+				rte_pci_insert_device(dev2, dev);
+			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->max_vfs = dev->max_vfs;
+				pci_name_set(dev2);
+				memmove(dev2->mem_resource,
+					dev->mem_resource,
+					sizeof(dev->mem_resource));
+				free(dev);
+			}
+			return 0;
+		}
+		rte_pci_add_device(dev);
+	}
+
+	return 0;
+
+skipdev:
+	free(dev);
+	return 0;
+}
+
+/*
+ * Scan the content of the PCI bus, and add the devices in the devices
+ * list. Call pci_scan_one() for each pci entry found.
+ */
+int
+rte_pci_scan(void)
+{
+	int fd;
+	unsigned dev_count = 0;
+	struct pci_conf matches[16];
+	struct pci_conf_io conf_io = {
+			.pat_buf_len = 0,
+			.num_patterns = 0,
+			.patterns = NULL,
+			.match_buf_len = sizeof(matches),
+			.matches = &matches[0],
+	};
+
+	/* for debug purposes, PCI can be disabled */
+	if (internal_config.no_pci)
+		return 0;
+
+	fd = open("/dev/pci", O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	do {
+		unsigned i;
+		if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+			RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+					__func__, strerror(errno));
+			goto error;
+		}
+
+		for (i = 0; i < conf_io.num_matches; i++)
+			if (pci_scan_one(fd, &matches[i]) < 0)
+				goto error;
+
+		dev_count += conf_io.num_matches;
+	} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
+
+	close(fd);
+
+	RTE_LOG(DEBUG, EAL, "PCI scan found %u devices\n", dev_count);
+	return 0;
+
+error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+	int fd;
+	struct pci_conf matches[2];
+	struct pci_match_conf match = {
+		.pc_sel = {
+			.pc_domain = addr->domain,
+			.pc_bus = addr->bus,
+			.pc_dev = addr->devid,
+			.pc_func = addr->function,
+		},
+	};
+	struct pci_conf_io conf_io = {
+		.pat_buf_len = 0,
+		.num_patterns = 1,
+		.patterns = &match,
+		.match_buf_len = sizeof(matches),
+		.matches = &matches[0],
+	};
+
+	fd = open("/dev/pci", O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+				__func__, strerror(errno));
+		goto error;
+	}
+
+	if (conf_io.num_matches != 1)
+		goto error;
+
+	if (pci_scan_one(fd, &matches[0]) < 0)
+		goto error;
+
+	close(fd);
+
+	return 0;
+
+error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/* Read PCI config space. */
+int rte_pci_read_config(const struct rte_pci_device *dev,
+		void *buf, size_t len, off_t offset)
+{
+	int fd = -1;
+	int size;
+	struct pci_io pi = {
+		.pi_sel = {
+			.pc_domain = dev->addr.domain,
+			.pc_bus = dev->addr.bus,
+			.pc_dev = dev->addr.devid,
+			.pc_func = dev->addr.function,
+		},
+		.pi_reg = offset,
+	};
+
+	fd = open("/dev/pci", O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	while (len > 0) {
+		size = (len >= 4) ? 4 : ((len >= 2) ? 2 : 1);
+		pi.pi_width = size;
+
+		if (ioctl(fd, PCIOCREAD, &pi) < 0)
+			goto error;
+		memcpy(buf, &pi.pi_data, size);
+
+		buf = (char *)buf + size;
+		pi.pi_reg += size;
+		len -= size;
+	}
+	close(fd);
+
+	return 0;
+
+ error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/* Write PCI config space. */
+int rte_pci_write_config(const struct rte_pci_device *dev,
+		const void *buf, size_t len, off_t offset)
+{
+	int fd = -1;
+
+	struct pci_io pi = {
+		.pi_sel = {
+			.pc_domain = dev->addr.domain,
+			.pc_bus = dev->addr.bus,
+			.pc_dev = dev->addr.devid,
+			.pc_func = dev->addr.function,
+		},
+		.pi_reg = offset,
+		.pi_data = *(const uint32_t *)buf,
+		.pi_width = len,
+	};
+
+	if (len == 3 || len > sizeof(pi.pi_data)) {
+		RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__);
+		goto error;
+	}
+
+	memcpy(&pi.pi_data, buf, len);
+
+	fd = open("/dev/pci", O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	if (ioctl(fd, PCIOCWRITE, &pi) < 0)
+		goto error;
+
+	close(fd);
+	return 0;
+
+ error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+int
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p)
+{
+	int ret;
+
+	switch (dev->kdrv) {
+#if defined(RTE_ARCH_X86)
+	case RTE_KDRV_NIC_UIO:
+		if ((uintptr_t) dev->mem_resource[bar].addr <= UINT16_MAX) {
+			p->base = (uintptr_t)dev->mem_resource[bar].addr;
+			ret = 0;
+		} else
+			ret = -1;
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	if (!ret)
+		p->dev = dev;
+
+	return ret;
+}
+
+static void
+pci_uio_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+#if defined(RTE_ARCH_X86)
+	uint8_t *d;
+	int size;
+	unsigned short reg = p->base + offset;
+
+	for (d = data; len > 0; d += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+			*(uint32_t *)d = inl(reg);
+		} else if (len >= 2) {
+			size = 2;
+			*(uint16_t *)d = inw(reg);
+		} else {
+			size = 1;
+			*d = inb(reg);
+		}
+	}
+#else
+	RTE_SET_USED(p);
+	RTE_SET_USED(data);
+	RTE_SET_USED(len);
+	RTE_SET_USED(offset);
+#endif
+}
+
+void
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+pci_uio_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+#if defined(RTE_ARCH_X86)
+	const uint8_t *s;
+	int size;
+	unsigned short reg = p->base + offset;
+
+	for (s = data; len > 0; s += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+			outl(reg, *(const uint32_t *)s);
+		} else if (len >= 2) {
+			size = 2;
+			outw(reg, *(const uint16_t *)s);
+		} else {
+			size = 1;
+			outb(reg, *s);
+		}
+	}
+#else
+	RTE_SET_USED(p);
+	RTE_SET_USED(data);
+	RTE_SET_USED(len);
+	RTE_SET_USED(offset);
+#endif
+}
+
+void
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	default:
+		break;
+	}
+}
+
+int
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
+{
+	int ret;
+
+	switch (p->dev->kdrv) {
+#if defined(RTE_ARCH_X86)
+	case RTE_KDRV_NIC_UIO:
+		ret = 0;
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/bus/pci/include/rte_bus_pci.h b/drivers/bus/pci/include/rte_bus_pci.h
new file mode 100644
index 0000000..b05dbf9
--- /dev/null
+++ b/drivers/bus/pci/include/rte_bus_pci.h
@@ -0,0 +1,387 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_BUS_PCI_H_
+#define _RTE_BUS_PCI_H_
+
+/**
+ * @file
+ *
+ * RTE PCI Bus Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+
+/** Pathname of PCI devices directory. */
+const char *pci_get_sysfs_path(void);
+
+/* Forward declarations */
+struct rte_pci_device;
+struct rte_pci_driver;
+
+/** List of PCI devices */
+TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
+/** List of PCI drivers */
+TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
+
+/* PCI Bus iterators */
+#define FOREACH_DEVICE_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
+
+#define FOREACH_DRIVER_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
+
+struct rte_devargs;
+
+/**
+ * A structure describing a PCI device.
+ */
+struct rte_pci_device {
+	TAILQ_ENTRY(rte_pci_device) next;   /**< Next probed PCI device. */
+	struct rte_device device;           /**< Inherit core device */
+	struct rte_pci_addr addr;           /**< PCI location. */
+	struct rte_pci_id id;               /**< PCI ID. */
+	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
+					    /**< PCI Memory Resource */
+	struct rte_intr_handle intr_handle; /**< Interrupt handle */
+	struct rte_pci_driver *driver;      /**< Associated driver */
+	uint16_t max_vfs;                   /**< sriov enable if not zero */
+	enum rte_kernel_driver kdrv;        /**< Kernel driver passthrough */
+	char name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_pci_device.
+ */
+#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
+
+#define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
+
+/** Any PCI device identifier (vendor, device, ...) */
+#define PCI_ANY_ID (0xffff)
+#define RTE_CLASS_ANY_ID (0xffffff)
+
+#ifdef __cplusplus
+/** C++ macro used to help building up tables of device IDs */
+#define RTE_PCI_DEVICE(vend, dev) \
+	RTE_CLASS_ANY_ID,         \
+	(vend),                   \
+	(dev),                    \
+	PCI_ANY_ID,               \
+	PCI_ANY_ID
+#else
+/** Macro used to help building up tables of device IDs */
+#define RTE_PCI_DEVICE(vend, dev)          \
+	.class_id = RTE_CLASS_ANY_ID,      \
+	.vendor_id = (vend),               \
+	.device_id = (dev),                \
+	.subsystem_vendor_id = PCI_ANY_ID, \
+	.subsystem_device_id = PCI_ANY_ID
+#endif
+
+/**
+ * Initialisation function for the driver called during PCI probing.
+ */
+typedef int (pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
+
+/**
+ * Uninitialisation function for the driver called during hotplugging.
+ */
+typedef int (pci_remove_t)(struct rte_pci_device *);
+
+/**
+ * A structure describing a PCI driver.
+ */
+struct rte_pci_driver {
+	TAILQ_ENTRY(rte_pci_driver) next;  /**< Next in list. */
+	struct rte_driver driver;          /**< Inherit core driver. */
+	struct rte_pci_bus *bus;           /**< PCI bus reference. */
+	pci_probe_t *probe;                /**< Device Probe function. */
+	pci_remove_t *remove;              /**< Device Remove function. */
+	const struct rte_pci_id *id_table; /**< ID table, NULL terminated. */
+	uint32_t drv_flags;                /**< Flags contolling handling of device. */
+};
+
+/**
+ * Structure describing the PCI bus
+ */
+struct rte_pci_bus {
+	struct rte_bus bus;               /**< Inherit the generic class */
+	struct rte_pci_device_list device_list;  /**< List of PCI devices */
+	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
+};
+
+/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
+#define RTE_PCI_DRV_NEED_MAPPING 0x0001
+/** Device driver supports link state interrupt */
+#define RTE_PCI_DRV_INTR_LSC	0x0008
+/** Device driver supports device removal interrupt */
+#define RTE_PCI_DRV_INTR_RMV 0x0010
+/** Device driver needs to keep mapped resources if unsupported dev detected */
+#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
+
+/**
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ *
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_pci_scan(void);
+
+/**
+ * Probe the PCI bus
+ *
+ * @return
+ *   - 0 on success.
+ *   - !0 on error.
+ */
+int
+rte_pci_probe(void);
+
+/**
+ * Map the PCI device resources in user space virtual memory address
+ *
+ * Note that driver should not call this function when flag
+ * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for
+ * you when it's on.
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ *
+ * @return
+ *   0 on success, negative on error and positive if no driver
+ *   is found for the device.
+ */
+int rte_pci_map_device(struct rte_pci_device *dev);
+
+/**
+ * Unmap this device
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ */
+void rte_pci_unmap_device(struct rte_pci_device *dev);
+
+/**
+ * Probe the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the probe() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to probe.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_probe_one(const struct rte_pci_addr *addr);
+
+/**
+ * Close the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the remove() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_detach(const struct rte_pci_addr *addr);
+
+/**
+ * Dump the content of the PCI bus.
+ *
+ * @param f
+ *   A pointer to a file for output
+ */
+void rte_pci_dump(FILE *f);
+
+/**
+ * Register a PCI driver.
+ *
+ * @param driver
+ *   A pointer to a rte_pci_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_pci_register(struct rte_pci_driver *driver);
+
+/** Helper for PCI device registration from driver (eth, crypto) instance */
+#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
+RTE_INIT(pciinitfn_ ##nm); \
+static void pciinitfn_ ##nm(void) \
+{\
+	(pci_drv).driver.name = RTE_STR(nm);\
+	rte_pci_register(&pci_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a PCI driver.
+ *
+ * @param driver
+ *   A pointer to a rte_pci_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_pci_unregister(struct rte_pci_driver *driver);
+
+/**
+ * Read PCI config space.
+ *
+ * @param device
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ * @param buf
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into PCI config space
+ */
+int rte_pci_read_config(const struct rte_pci_device *device,
+		void *buf, size_t len, off_t offset);
+
+/**
+ * Write PCI config space.
+ *
+ * @param device
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ * @param buf
+ *   A data buffer containing the bytes should be written
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into PCI config space
+ */
+int rte_pci_write_config(const struct rte_pci_device *device,
+		const void *buf, size_t len, off_t offset);
+
+/**
+ * A structure used to access io resources for a pci device.
+ * rte_pci_ioport is arch, os, driver specific, and should not be used outside
+ * of pci ioport api.
+ */
+struct rte_pci_ioport {
+	struct rte_pci_device *dev;
+	uint64_t base;
+	uint64_t len; /* only filled for memory mapped ports */
+};
+
+/**
+ * Initialize a rte_pci_ioport object for a pci device io resource.
+ *
+ * This object is then used to gain access to those io resources (see below).
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use.
+ * @param bar
+ *   Index of the io pci resource we want to access.
+ * @param p
+ *   The rte_pci_ioport object to be initialized.
+ * @return
+ *  0 on success, negative on error.
+ */
+int rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p);
+
+/**
+ * Release any resources used in a rte_pci_ioport object.
+ *
+ * @param p
+ *   The rte_pci_ioport object to be uninitialized.
+ * @return
+ *  0 on success, negative on error.
+ */
+int rte_pci_ioport_unmap(struct rte_pci_ioport *p);
+
+/**
+ * Read from a io pci resource.
+ *
+ * @param p
+ *   The rte_pci_ioport object from which we want to read.
+ * @param data
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into the pci io resource.
+ */
+void rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset);
+
+/**
+ * Write to a io pci resource.
+ *
+ * @param p
+ *   The rte_pci_ioport object to which we want to write.
+ * @param data
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into the pci io resource.
+ */
+void rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_BUS_PCI_H_ */
diff --git a/drivers/bus/pci/linux/Makefile b/drivers/bus/pci/linux/Makefile
new file mode 100644
index 0000000..d2ea84c
--- /dev/null
+++ b/drivers/bus/pci/linux/Makefile
@@ -0,0 +1,37 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += rte_pci.c
+SRCS += rte_pci_uio.c
+SRCS += rte_pci_vfio.c
+SRCS += rte_vfio_mp_sync.c
+
+CFLAGS += -D_GNU_SOURCE
diff --git a/drivers/bus/pci/linux/rte_pci.c b/drivers/bus/pci/linux/rte_pci.c
new file mode 100644
index 0000000..96f9778
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_pci.c
@@ -0,0 +1,723 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <dirent.h>
+
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+#include <rte_devargs.h>
+#include <rte_memcpy.h>
+
+#include "eal_filesystem.h"
+#include "private.h"
+#include "rte_pci_init.h"
+#include "rte_memory_linux.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in sysfs.
+ * When a registered device matches a driver, it is then initialized with
+ * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
+ */
+
+extern struct rte_pci_bus rte_pci_bus;
+
+static int
+pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
+{
+	int count;
+	char path[PATH_MAX];
+	char *name;
+
+	if (!filename || !dri_name)
+		return -1;
+
+	count = readlink(filename, path, PATH_MAX);
+	if (count >= PATH_MAX)
+		return -1;
+
+	/* For device does not have a driver */
+	if (count < 0)
+		return 1;
+
+	path[count] = '\0';
+
+	name = strrchr(path, '/');
+	if (name) {
+		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
+		return 0;
+	}
+
+	return -1;
+}
+
+/* Map pci device */
+int
+rte_pci_map_device(struct rte_pci_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_map_resource(dev);
+#endif
+		break;
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+		if (rte_eal_using_phys_addrs()) {
+			/* map resources for devices that use uio */
+			ret = pci_uio_map_resource(dev);
+		}
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+/* Unmap pci device */
+void
+rte_pci_unmap_device(struct rte_pci_device *dev)
+{
+	/* try unmapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+		if (pci_vfio_is_enabled())
+			pci_vfio_unmap_resource(dev);
+#endif
+		break;
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+		/* unmap resources for devices that use uio */
+		pci_uio_unmap_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+void *
+pci_find_max_end_va(void)
+{
+	const struct rte_memseg *seg = rte_eal_get_physmem_layout();
+	const struct rte_memseg *last = seg;
+	unsigned i = 0;
+
+	for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
+		if (seg->addr == NULL)
+			break;
+
+		if (seg->addr > last->addr)
+			last = seg;
+
+	}
+	return RTE_PTR_ADD(last->addr, last->len);
+}
+
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int
+pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+	uint64_t *end_addr, uint64_t *flags)
+{
+	union pci_resource_info {
+		struct {
+			char *phys_addr;
+			char *end_addr;
+			char *flags;
+		};
+		char *ptrs[PCI_RESOURCE_FMT_NVAL];
+	} res_info;
+
+	if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
+		RTE_LOG(ERR, EAL,
+			"%s(): bad resource format\n", __func__);
+		return -1;
+	}
+	errno = 0;
+	*phys_addr = strtoull(res_info.phys_addr, NULL, 16);
+	*end_addr = strtoull(res_info.end_addr, NULL, 16);
+	*flags = strtoull(res_info.flags, NULL, 16);
+	if (errno != 0) {
+		RTE_LOG(ERR, EAL,
+			"%s(): bad resource format\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
+
+/* parse the "resource" sysfs file */
+static int
+pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
+{
+	FILE *f;
+	char buf[BUFSIZ];
+	int i;
+	uint64_t phys_addr, end_addr, flags;
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
+		return -1;
+	}
+
+	for (i = 0; i<PCI_MAX_RESOURCE; i++) {
+
+		if (fgets(buf, sizeof(buf), f) == NULL) {
+			RTE_LOG(ERR, EAL,
+				"%s(): cannot read resource\n", __func__);
+			goto error;
+		}
+		if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+				&end_addr, &flags) < 0)
+			goto error;
+
+		if (flags & IORESOURCE_MEM) {
+			dev->mem_resource[i].phys_addr = phys_addr;
+			dev->mem_resource[i].len = end_addr - phys_addr + 1;
+			/* not mapped for now */
+			dev->mem_resource[i].addr = NULL;
+		}
+	}
+	fclose(f);
+	return 0;
+
+error:
+	fclose(f);
+	return -1;
+}
+
+/* Scan one pci sysfs entry, and fill the devices list from it. */
+static int
+pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
+{
+	char filename[PATH_MAX];
+	unsigned long tmp;
+	struct rte_pci_device *dev;
+	char driver[PATH_MAX];
+	int ret;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL)
+		return -1;
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr = *addr;
+
+	/* get vendor id */
+	snprintf(filename, sizeof(filename), "%s/vendor", dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.vendor_id = (uint16_t)tmp;
+
+	/* get device id */
+	snprintf(filename, sizeof(filename), "%s/device", dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.device_id = (uint16_t)tmp;
+
+	/* get subsystem_vendor id */
+	snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.subsystem_vendor_id = (uint16_t)tmp;
+
+	/* get subsystem_device id */
+	snprintf(filename, sizeof(filename), "%s/subsystem_device",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.subsystem_device_id = (uint16_t)tmp;
+
+	/* get class_id */
+	snprintf(filename, sizeof(filename), "%s/class",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	/* the least 24 bits are valid: class, subclass, program interface */
+	dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
+
+	/* get max_vfs */
+	dev->max_vfs = 0;
+	snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
+	if (!access(filename, F_OK) &&
+	    eal_parse_sysfs_value(filename, &tmp) == 0)
+		dev->max_vfs = (uint16_t)tmp;
+	else {
+		/* for non igb_uio driver, need kernel version >= 3.8 */
+		snprintf(filename, sizeof(filename),
+			 "%s/sriov_numvfs", dirname);
+		if (!access(filename, F_OK) &&
+		    eal_parse_sysfs_value(filename, &tmp) == 0)
+			dev->max_vfs = (uint16_t)tmp;
+	}
+
+	/* get numa node, default to 0 if not present */
+	snprintf(filename, sizeof(filename), "%s/numa_node",
+		 dirname);
+
+	if (access(filename, F_OK) != -1) {
+		if (eal_parse_sysfs_value(filename, &tmp) == 0)
+			dev->device.numa_node = tmp;
+		else
+			dev->device.numa_node = -1;
+	} else {
+		dev->device.numa_node = 0;
+	}
+
+	pci_name_set(dev);
+
+	/* parse resources */
+	snprintf(filename, sizeof(filename), "%s/resource", dirname);
+	if (pci_parse_sysfs_resource(filename, dev) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
+		free(dev);
+		return -1;
+	}
+
+	/* parse driver */
+	snprintf(filename, sizeof(filename), "%s/driver", dirname);
+	ret = pci_get_kernel_driver_by_path(filename, driver);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
+		free(dev);
+		return -1;
+	}
+
+	if (!ret) {
+		if (!strcmp(driver, "vfio-pci"))
+			dev->kdrv = RTE_KDRV_VFIO;
+		else if (!strcmp(driver, "igb_uio"))
+			dev->kdrv = RTE_KDRV_IGB_UIO;
+		else if (!strcmp(driver, "uio_pci_generic"))
+			dev->kdrv = RTE_KDRV_UIO_GENERIC;
+		else
+			dev->kdrv = RTE_KDRV_UNKNOWN;
+	} else
+		dev->kdrv = RTE_KDRV_NONE;
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
+		rte_pci_add_device(dev);
+	} else {
+		struct rte_pci_device *dev2;
+		int ret;
+
+		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
+			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+
+			if (ret < 0) {
+				rte_pci_insert_device(dev2, dev);
+			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->max_vfs = dev->max_vfs;
+				pci_name_set(dev2);
+				memmove(dev2->mem_resource, dev->mem_resource,
+					sizeof(dev->mem_resource));
+				free(dev);
+			}
+			return 0;
+		}
+
+		rte_pci_add_device(dev);
+	}
+
+	return 0;
+}
+
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+	char filename[PATH_MAX];
+
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
+		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
+		 addr->function);
+
+	return pci_scan_one(filename, addr);
+}
+
+/*
+ * split up a pci address into its constituent parts.
+ */
+static int
+parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
+{
+	/* first split on ':' */
+	union splitaddr {
+		struct {
+			char *domain;
+			char *bus;
+			char *devid;
+			char *function;
+		};
+		char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
+	} splitaddr;
+
+	char *buf_copy = strndup(buf, bufsize);
+	if (buf_copy == NULL)
+		return -1;
+
+	if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
+			!= PCI_FMT_NVAL - 1)
+		goto error;
+	/* final split is on '.' between devid and function */
+	splitaddr.function = strchr(splitaddr.devid,'.');
+	if (splitaddr.function == NULL)
+		goto error;
+	*splitaddr.function++ = '\0';
+
+	/* now convert to int values */
+	errno = 0;
+	addr->domain = strtoul(splitaddr.domain, NULL, 16);
+	addr->bus = strtoul(splitaddr.bus, NULL, 16);
+	addr->devid = strtoul(splitaddr.devid, NULL, 16);
+	addr->function = strtoul(splitaddr.function, NULL, 10);
+	if (errno != 0)
+		goto error;
+
+	free(buf_copy); /* free the copy made with strdup */
+	return 0;
+error:
+	free(buf_copy);
+	return -1;
+}
+
+/*
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ */
+int
+rte_pci_scan(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+	struct rte_pci_addr addr;
+
+	/* for debug purposes, PCI can be disabled */
+	if (internal_config.no_pci)
+		return 0;
+
+	dir = opendir(pci_get_sysfs_path());
+	if (dir == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
+			continue;
+
+		snprintf(dirname, sizeof(dirname), "%s/%s",
+				pci_get_sysfs_path(), e->d_name);
+
+		if (pci_scan_one(dirname, &addr) < 0)
+			goto error;
+	}
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
+
+/* Read PCI config space. */
+int rte_pci_read_config(const struct rte_pci_device *device,
+		void *buf, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &device->intr_handle;
+
+	switch (intr_handle->type) {
+	case RTE_INTR_HANDLE_UIO:
+	case RTE_INTR_HANDLE_UIO_INTX:
+		return pci_uio_read_config(intr_handle, buf, len, offset);
+
+#ifdef VFIO_PRESENT
+	case RTE_INTR_HANDLE_VFIO_MSIX:
+	case RTE_INTR_HANDLE_VFIO_MSI:
+	case RTE_INTR_HANDLE_VFIO_LEGACY:
+		return pci_vfio_read_config(intr_handle, buf, len, offset);
+#endif
+	default:
+		RTE_LOG(ERR, EAL,
+			"Unknown handle type of fd %d\n",
+					intr_handle->fd);
+		return -1;
+	}
+}
+
+/* Write PCI config space. */
+int rte_pci_write_config(const struct rte_pci_device *device,
+		const void *buf, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &device->intr_handle;
+
+	switch (intr_handle->type) {
+	case RTE_INTR_HANDLE_UIO:
+	case RTE_INTR_HANDLE_UIO_INTX:
+		return pci_uio_write_config(intr_handle, buf, len, offset);
+
+#ifdef VFIO_PRESENT
+	case RTE_INTR_HANDLE_VFIO_MSIX:
+	case RTE_INTR_HANDLE_VFIO_MSI:
+	case RTE_INTR_HANDLE_VFIO_LEGACY:
+		return pci_vfio_write_config(intr_handle, buf, len, offset);
+#endif
+	default:
+		RTE_LOG(ERR, EAL,
+			"Unknown handle type of fd %d\n",
+					intr_handle->fd);
+		return -1;
+	}
+}
+
+#if defined(RTE_ARCH_X86)
+static int
+pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
+		struct rte_pci_ioport *p)
+{
+	uint16_t start, end;
+	FILE *fp;
+	char *line = NULL;
+	char pci_id[16];
+	int found = 0;
+	size_t linesz;
+
+	snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
+		 dev->addr.domain, dev->addr.bus,
+		 dev->addr.devid, dev->addr.function);
+
+	fp = fopen("/proc/ioports", "r");
+	if (fp == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);
+		return -1;
+	}
+
+	while (getdelim(&line, &linesz, '\n', fp) > 0) {
+		char *ptr = line;
+		char *left;
+		int n;
+
+		n = strcspn(ptr, ":");
+		ptr[n] = 0;
+		left = &ptr[n + 1];
+
+		while (*left && isspace(*left))
+			left++;
+
+		if (!strncmp(left, pci_id, strlen(pci_id))) {
+			found = 1;
+
+			while (*ptr && isspace(*ptr))
+				ptr++;
+
+			sscanf(ptr, "%04hx-%04hx", &start, &end);
+
+			break;
+		}
+	}
+
+	free(line);
+	fclose(fp);
+
+	if (!found)
+		return -1;
+
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	p->base = start;
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
+
+	return 0;
+}
+#endif
+
+int
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p)
+{
+	int ret = -1;
+
+	switch (dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_ioport_map(dev, bar, p);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		ret = pci_uio_ioport_map(dev, bar, p);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+		ret = pci_ioport_map(dev, bar, p);
+#else
+		ret = pci_uio_ioport_map(dev, bar, p);
+#endif
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		ret = pci_ioport_map(dev, bar, p);
+#endif
+		break;
+	default:
+		break;
+	}
+
+	if (!ret)
+		p->dev = dev;
+
+	return ret;
+}
+
+void
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		pci_vfio_ioport_read(p, data, len, offset);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		pci_uio_ioport_read(p, data, len, offset);
+#endif
+		break;
+	default:
+		break;
+	}
+}
+
+void
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		pci_vfio_ioport_write(p, data, len, offset);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		pci_uio_ioport_write(p, data, len, offset);
+#endif
+		break;
+	default:
+		break;
+	}
+}
+
+int
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
+{
+	int ret = -1;
+
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_ioport_unmap(p);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		ret = pci_uio_ioport_unmap(p);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+		ret = 0;
+#else
+		ret = pci_uio_ioport_unmap(p);
+#endif
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		ret = 0;
+#endif
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/bus/pci/linux/rte_pci_init.h b/drivers/bus/pci/linux/rte_pci_init.h
new file mode 100644
index 0000000..ae2980d
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_pci_init.h
@@ -0,0 +1,97 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EAL_PCI_INIT_H_
+#define EAL_PCI_INIT_H_
+
+#include "eal_vfio.h"
+
+/** IO resource type: */
+#define IORESOURCE_IO         0x00000100
+#define IORESOURCE_MEM        0x00000200
+
+/*
+ * Helper function to map PCI resources right after hugepages in virtual memory
+ */
+extern void *pci_map_addr;
+void *pci_find_max_end_va(void);
+
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+	uint64_t *end_addr, uint64_t *flags);
+
+int pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res);
+void pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res);
+int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx);
+
+int pci_uio_read_config(const struct rte_intr_handle *intr_handle,
+			void *buf, size_t len, off_t offs);
+int pci_uio_write_config(const struct rte_intr_handle *intr_handle,
+			 const void *buf, size_t len, off_t offs);
+
+int pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		       struct rte_pci_ioport *p);
+void pci_uio_ioport_read(struct rte_pci_ioport *p,
+			 void *data, size_t len, off_t offset);
+void pci_uio_ioport_write(struct rte_pci_ioport *p,
+			  const void *data, size_t len, off_t offset);
+int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
+
+#ifdef VFIO_PRESENT
+
+/* access config space */
+int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
+			 void *buf, size_t len, off_t offs);
+int pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
+			  const void *buf, size_t len, off_t offs);
+
+int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
+		        struct rte_pci_ioport *p);
+void pci_vfio_ioport_read(struct rte_pci_ioport *p,
+			  void *data, size_t len, off_t offset);
+void pci_vfio_ioport_write(struct rte_pci_ioport *p,
+			   const void *data, size_t len, off_t offset);
+int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
+
+/* map/unmap VFIO resource prototype */
+int pci_vfio_map_resource(struct rte_pci_device *dev);
+int pci_vfio_unmap_resource(struct rte_pci_device *dev);
+
+#endif
+
+#endif /* EAL_PCI_INIT_H_ */
diff --git a/drivers/bus/pci/linux/rte_pci_uio.c b/drivers/bus/pci/linux/rte_pci_uio.c
new file mode 100644
index 0000000..eed6d0f
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_pci_uio.c
@@ -0,0 +1,567 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/sysmacros.h>
+#include <linux/pci_regs.h>
+
+#if defined(RTE_ARCH_X86)
+#include <sys/io.h>
+#endif
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_common.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "rte_pci_init.h"
+
+void *pci_map_addr = NULL;
+
+#define OFF_MAX              ((uint64_t)(off_t)-1)
+
+int
+pci_uio_read_config(const struct rte_intr_handle *intr_handle,
+		    void *buf, size_t len, off_t offset)
+{
+	return pread(intr_handle->uio_cfg_fd, buf, len, offset);
+}
+
+int
+pci_uio_write_config(const struct rte_intr_handle *intr_handle,
+		     const void *buf, size_t len, off_t offset)
+{
+	return pwrite(intr_handle->uio_cfg_fd, buf, len, offset);
+}
+
+static int
+pci_uio_set_bus_master(int dev_fd)
+{
+	uint16_t reg;
+	int ret;
+
+	ret = pread(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL,
+			"Cannot read command from PCI config space!\n");
+		return -1;
+	}
+
+	/* return if bus mastering is already on */
+	if (reg & PCI_COMMAND_MASTER)
+		return 0;
+
+	reg |= PCI_COMMAND_MASTER;
+
+	ret = pwrite(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL,
+			"Cannot write command to PCI config space!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
+{
+	FILE *f;
+	char filename[PATH_MAX];
+	int ret;
+	unsigned major, minor;
+	dev_t dev;
+
+	/* get the name of the sysfs file that contains the major and minor
+	 * of the uio device and read its content */
+	snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path);
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n",
+			__func__);
+		return -1;
+	}
+
+	ret = fscanf(f, "%u:%u", &major, &minor);
+	if (ret != 2) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n",
+			__func__);
+		fclose(f);
+		return -1;
+	}
+	fclose(f);
+
+	/* create the char device "mknod /dev/uioX c major minor" */
+	snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
+	dev = makedev(major, minor);
+	ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
+	if (ret != 0) {
+		RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	return ret;
+}
+
+/*
+ * Return the uioX char device used for a pci device. On success, return
+ * the UIO number and fill dstbuf string with the path of the device in
+ * sysfs. On error, return a negative value. In this case dstbuf is
+ * invalid.
+ */
+static int
+pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
+			   unsigned int buflen, int create)
+{
+	struct rte_pci_addr *loc = &dev->addr;
+	unsigned int uio_num;
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+
+	/* depending on kernel version, uio can be located in uio/uioX
+	 * or uio:uioX */
+
+	snprintf(dirname, sizeof(dirname),
+			"%s/" PCI_PRI_FMT "/uio", pci_get_sysfs_path(),
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	dir = opendir(dirname);
+	if (dir == NULL) {
+		/* retry with the parent directory */
+		snprintf(dirname, sizeof(dirname),
+				"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
+				loc->domain, loc->bus, loc->devid, loc->function);
+		dir = opendir(dirname);
+
+		if (dir == NULL) {
+			RTE_LOG(ERR, EAL, "Cannot opendir %s\n", dirname);
+			return -1;
+		}
+	}
+
+	/* take the first file starting with "uio" */
+	while ((e = readdir(dir)) != NULL) {
+		/* format could be uio%d ...*/
+		int shortprefix_len = sizeof("uio") - 1;
+		/* ... or uio:uio%d */
+		int longprefix_len = sizeof("uio:uio") - 1;
+		char *endptr;
+
+		if (strncmp(e->d_name, "uio", 3) != 0)
+			continue;
+
+		/* first try uio%d */
+		errno = 0;
+		uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
+		if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
+			snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
+			break;
+		}
+
+		/* then try uio:uio%d */
+		errno = 0;
+		uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
+		if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
+			snprintf(dstbuf, buflen, "%s/uio:uio%u", dirname, uio_num);
+			break;
+		}
+	}
+	closedir(dir);
+
+	/* No uio resource found */
+	if (e == NULL)
+		return -1;
+
+	/* create uio device if we've been asked to */
+	if (internal_config.create_uio_dev && create &&
+			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
+		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
+
+	return uio_num;
+}
+
+void
+pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res)
+{
+	rte_free(uio_res);
+
+	if (dev->intr_handle.uio_cfg_fd >= 0) {
+		close(dev->intr_handle.uio_cfg_fd);
+		dev->intr_handle.uio_cfg_fd = -1;
+	}
+	if (dev->intr_handle.fd >= 0) {
+		close(dev->intr_handle.fd);
+		dev->intr_handle.fd = -1;
+		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	}
+}
+
+int
+pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res)
+{
+	char dirname[PATH_MAX];
+	char cfgname[PATH_MAX];
+	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	int uio_num;
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+
+	/* find uio resource */
+	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 1);
+	if (uio_num < 0) {
+		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+		return 1;
+	}
+	snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
+
+	/* save fd if in primary process */
+	dev->intr_handle.fd = open(devname, O_RDWR);
+	if (dev->intr_handle.fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			devname, strerror(errno));
+		goto error;
+	}
+
+	snprintf(cfgname, sizeof(cfgname),
+			"/sys/class/uio/uio%u/device/config", uio_num);
+	dev->intr_handle.uio_cfg_fd = open(cfgname, O_RDWR);
+	if (dev->intr_handle.uio_cfg_fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			cfgname, strerror(errno));
+		goto error;
+	}
+
+	if (dev->kdrv == RTE_KDRV_IGB_UIO)
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+	else {
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
+
+		/* set bus master that is not done by uio_pci_generic */
+		if (pci_uio_set_bus_master(dev->intr_handle.uio_cfg_fd)) {
+			RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
+			goto error;
+		}
+	}
+
+	/* allocate the mapping details for secondary processes*/
+	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
+	if (*uio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto error;
+	}
+
+	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
+	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
+
+	return 0;
+
+error:
+	pci_uio_free_resource(dev, *uio_res);
+	return -1;
+}
+
+int
+pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx)
+{
+	int fd;
+	char devname[PATH_MAX];
+	void *mapaddr;
+	struct rte_pci_addr *loc;
+	struct pci_map *maps;
+
+	loc = &dev->addr;
+	maps = uio_res->maps;
+
+	/* update devname for mmap  */
+	snprintf(devname, sizeof(devname),
+			"%s/" PCI_PRI_FMT "/resource%d",
+			pci_get_sysfs_path(),
+			loc->domain, loc->bus, loc->devid,
+			loc->function, res_idx);
+
+	/* allocate memory to keep path */
+	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+	if (maps[map_idx].path == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+				strerror(errno));
+		return -1;
+	}
+
+	/*
+	 * open resource file, to mmap it
+	 */
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				devname, strerror(errno));
+		goto error;
+	}
+
+	/* try mapping somewhere close to the end of hugepages */
+	if (pci_map_addr == NULL)
+		pci_map_addr = pci_find_max_end_va();
+
+	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
+			(size_t)dev->mem_resource[res_idx].len, 0);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		goto error;
+
+	pci_map_addr = RTE_PTR_ADD(mapaddr,
+			(size_t)dev->mem_resource[res_idx].len);
+
+	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+	maps[map_idx].size = dev->mem_resource[res_idx].len;
+	maps[map_idx].addr = mapaddr;
+	maps[map_idx].offset = 0;
+	strcpy(maps[map_idx].path, devname);
+	dev->mem_resource[res_idx].addr = mapaddr;
+
+	return 0;
+
+error:
+	rte_free(maps[map_idx].path);
+	return -1;
+}
+
+#if defined(RTE_ARCH_X86)
+int
+pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		   struct rte_pci_ioport *p)
+{
+	char dirname[PATH_MAX];
+	char filename[PATH_MAX];
+	int uio_num;
+	unsigned long start;
+
+	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 0);
+	if (uio_num < 0)
+		return -1;
+
+	/* get portio start */
+	snprintf(filename, sizeof(filename),
+		 "%s/portio/port%d/start", dirname, bar);
+	if (eal_parse_sysfs_value(filename, &start) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
+			__func__);
+		return -1;
+	}
+	/* ensure we don't get anything funny here, read/write will cast to
+	 * uin16_t */
+	if (start > UINT16_MAX)
+		return -1;
+
+	/* FIXME only for primary process ? */
+	if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {
+
+		snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
+		dev->intr_handle.fd = open(filename, O_RDWR);
+		if (dev->intr_handle.fd < 0) {
+			RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				filename, strerror(errno));
+			return -1;
+		}
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+	}
+
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);
+
+	p->base = start;
+	p->len = 0;
+	return 0;
+}
+#else
+int
+pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		   struct rte_pci_ioport *p)
+{
+	FILE *f;
+	char buf[BUFSIZ];
+	char filename[PATH_MAX];
+	uint64_t phys_addr, end_addr, flags;
+	int fd, i;
+	void *addr;
+
+	/* open and read addresses of the corresponding resource in sysfs */
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
+		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function);
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",
+			strerror(errno));
+		return -1;
+	}
+	for (i = 0; i < bar + 1; i++) {
+		if (fgets(buf, sizeof(buf), f) == NULL) {
+			RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");
+			goto error;
+		}
+	}
+	if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+			&end_addr, &flags) < 0)
+		goto error;
+	if ((flags & IORESOURCE_IO) == 0) {
+		RTE_LOG(ERR, EAL, "BAR %d is not an IO resource\n", bar);
+		goto error;
+	}
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
+		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function, bar);
+
+	/* mmap the pci resource */
+	fd = open(filename, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
+			strerror(errno));
+		goto error;
+	}
+	addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
+		MAP_SHARED, fd, 0);
+	close(fd);
+	if (addr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s\n",
+			strerror(errno));
+		goto error;
+	}
+
+	/* strangely, the base address is mmap addr + phys_addr */
+	p->base = (uintptr_t)addr + phys_addr;
+	p->len = end_addr + 1;
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"\n", p->base);
+	fclose(f);
+
+	return 0;
+
+error:
+	fclose(f);
+	return -1;
+}
+#endif
+
+void
+pci_uio_ioport_read(struct rte_pci_ioport *p,
+		    void *data, size_t len, off_t offset)
+{
+	uint8_t *d;
+	int size;
+	uintptr_t reg = p->base + offset;
+
+	for (d = data; len > 0; d += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+#if defined(RTE_ARCH_X86)
+			*(uint32_t *)d = inl(reg);
+#else
+			*(uint32_t *)d = *(volatile uint32_t *)reg;
+#endif
+		} else if (len >= 2) {
+			size = 2;
+#if defined(RTE_ARCH_X86)
+			*(uint16_t *)d = inw(reg);
+#else
+			*(uint16_t *)d = *(volatile uint16_t *)reg;
+#endif
+		} else {
+			size = 1;
+#if defined(RTE_ARCH_X86)
+			*d = inb(reg);
+#else
+			*d = *(volatile uint8_t *)reg;
+#endif
+		}
+	}
+}
+
+void
+pci_uio_ioport_write(struct rte_pci_ioport *p,
+		     const void *data, size_t len, off_t offset)
+{
+	const uint8_t *s;
+	int size;
+	uintptr_t reg = p->base + offset;
+
+	for (s = data; len > 0; s += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+#if defined(RTE_ARCH_X86)
+			outl_p(*(const uint32_t *)s, reg);
+#else
+			*(volatile uint32_t *)reg = *(const uint32_t *)s;
+#endif
+		} else if (len >= 2) {
+			size = 2;
+#if defined(RTE_ARCH_X86)
+			outw_p(*(const uint16_t *)s, reg);
+#else
+			*(volatile uint16_t *)reg = *(const uint16_t *)s;
+#endif
+		} else {
+			size = 1;
+#if defined(RTE_ARCH_X86)
+			outb_p(*s, reg);
+#else
+			*(volatile uint8_t *)reg = *s;
+#endif
+		}
+	}
+}
+
+int
+pci_uio_ioport_unmap(struct rte_pci_ioport *p)
+{
+#if defined(RTE_ARCH_X86)
+	RTE_SET_USED(p);
+	/* FIXME close intr fd ? */
+	return 0;
+#else
+	return munmap((void *)(uintptr_t)p->base, p->len);
+#endif
+}
diff --git a/drivers/bus/pci/linux/rte_pci_vfio.c b/drivers/bus/pci/linux/rte_pci_vfio.c
new file mode 100644
index 0000000..81b67c9
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_pci_vfio.c
@@ -0,0 +1,674 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <fcntl.h>
+#include <linux/pci_regs.h>
+#include <sys/eventfd.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "rte_pci_init.h"
+#include "eal_vfio.h"
+#include "private.h"
+
+/**
+ * @file
+ * PCI probing under linux (VFIO version)
+ *
+ * This code tries to determine if the PCI device is bound to VFIO driver,
+ * and initialize it (map BARs, set up interrupts) if that's the case.
+ *
+ * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
+ */
+
+#ifdef VFIO_PRESENT
+
+#define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
+#define PAGE_MASK   (~(PAGE_SIZE - 1))
+
+static struct rte_tailq_elem rte_vfio_tailq = {
+	.name = "VFIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_vfio_tailq)
+
+int
+pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
+		    void *buf, size_t len, off_t offs)
+{
+	return pread64(intr_handle->vfio_dev_fd, buf, len,
+	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
+}
+
+int
+pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
+		    const void *buf, size_t len, off_t offs)
+{
+	return pwrite64(intr_handle->vfio_dev_fd, buf, len,
+	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
+}
+
+/* get PCI BAR number where MSI-X interrupts are */
+static int
+pci_vfio_get_msix_bar(int fd, int *msix_bar, uint32_t *msix_table_offset,
+		      uint32_t *msix_table_size)
+{
+	int ret;
+	uint32_t reg;
+	uint16_t flags;
+	uint8_t cap_id, cap_offset;
+
+	/* read PCI capability pointer from config space */
+	ret = pread64(fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_CAPABILITY_LIST);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
+				"config space!\n");
+		return -1;
+	}
+
+	/* we need first byte */
+	cap_offset = reg & 0xFF;
+
+	while (cap_offset) {
+
+		/* read PCI capability ID */
+		ret = pread64(fd, &reg, sizeof(reg),
+				VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+				cap_offset);
+		if (ret != sizeof(reg)) {
+			RTE_LOG(ERR, EAL, "Cannot read capability ID from PCI "
+					"config space!\n");
+			return -1;
+		}
+
+		/* we need first byte */
+		cap_id = reg & 0xFF;
+
+		/* if we haven't reached MSI-X, check next capability */
+		if (cap_id != PCI_CAP_ID_MSIX) {
+			ret = pread64(fd, &reg, sizeof(reg),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset);
+			if (ret != sizeof(reg)) {
+				RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
+						"config space!\n");
+				return -1;
+			}
+
+			/* we need second byte */
+			cap_offset = (reg & 0xFF00) >> 8;
+
+			continue;
+		}
+		/* else, read table offset */
+		else {
+			/* table offset resides in the next 4 bytes */
+			ret = pread64(fd, &reg, sizeof(reg),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset + 4);
+			if (ret != sizeof(reg)) {
+				RTE_LOG(ERR, EAL, "Cannot read table offset from PCI config "
+						"space!\n");
+				return -1;
+			}
+
+			ret = pread64(fd, &flags, sizeof(flags),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset + 2);
+			if (ret != sizeof(flags)) {
+				RTE_LOG(ERR, EAL, "Cannot read table flags from PCI config "
+						"space!\n");
+				return -1;
+			}
+
+			*msix_bar = reg & RTE_PCI_MSIX_TABLE_BIR;
+			*msix_table_offset = reg & RTE_PCI_MSIX_TABLE_OFFSET;
+			*msix_table_size = 16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE));
+
+			return 0;
+		}
+	}
+	return 0;
+}
+
+/* set PCI bus mastering */
+static int
+pci_vfio_set_bus_master(int dev_fd, bool op)
+{
+	uint16_t reg;
+	int ret;
+
+	ret = pread64(dev_fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n");
+		return -1;
+	}
+
+	if (op)
+		/* set the master bit */
+		reg |= PCI_COMMAND_MASTER;
+	else
+		reg &= ~(PCI_COMMAND_MASTER);
+
+	ret = pwrite64(dev_fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_COMMAND);
+
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* set up interrupt support (but not enable interrupts) */
+static int
+pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
+{
+	int i, ret, intr_idx;
+
+	/* default to invalid index */
+	intr_idx = VFIO_PCI_NUM_IRQS;
+
+	/* get interrupt type from internal config (MSI-X by default, can be
+	 * overridden from the command line
+	 */
+	switch (internal_config.vfio_intr_mode) {
+	case RTE_INTR_MODE_MSIX:
+		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
+		break;
+	case RTE_INTR_MODE_MSI:
+		intr_idx = VFIO_PCI_MSI_IRQ_INDEX;
+		break;
+	case RTE_INTR_MODE_LEGACY:
+		intr_idx = VFIO_PCI_INTX_IRQ_INDEX;
+		break;
+	/* don't do anything if we want to automatically determine interrupt type */
+	case RTE_INTR_MODE_NONE:
+		break;
+	default:
+		RTE_LOG(ERR, EAL, "  unknown default interrupt type!\n");
+		return -1;
+	}
+
+	/* start from MSI-X interrupt type */
+	for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) {
+		struct vfio_irq_info irq = { .argsz = sizeof(irq) };
+		int fd = -1;
+
+		/* skip interrupt modes we don't want */
+		if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE &&
+				i != intr_idx)
+			continue;
+
+		irq.index = i;
+
+		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  cannot get IRQ info, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+
+		/* if this vector cannot be used with eventfd, fail if we explicitly
+		 * specified interrupt type, otherwise continue */
+		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
+			if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE) {
+				RTE_LOG(ERR, EAL,
+						"  interrupt vector does not support eventfd!\n");
+				return -1;
+			} else
+				continue;
+		}
+
+		/* set up an eventfd for interrupts */
+		fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
+		if (fd < 0) {
+			RTE_LOG(ERR, EAL, "  cannot set up eventfd, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+
+		dev->intr_handle.fd = fd;
+		dev->intr_handle.vfio_dev_fd = vfio_dev_fd;
+
+		switch (i) {
+		case VFIO_PCI_MSIX_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSIX;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
+			break;
+		case VFIO_PCI_MSI_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSI;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
+			break;
+		case VFIO_PCI_INTX_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_LEGACY;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
+			break;
+		default:
+			RTE_LOG(ERR, EAL, "  unknown interrupt type!\n");
+			return -1;
+		}
+
+		return 0;
+	}
+
+	/* if we're here, we haven't found a suitable interrupt vector */
+	return -1;
+}
+
+/*
+ * map the PCI resources of a PCI device in virtual memory (VFIO version).
+ * primary and secondary processes follow almost exactly the same path
+ */
+int
+pci_vfio_map_resource(struct rte_pci_device *dev)
+{
+	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+	char pci_addr[PATH_MAX] = {0};
+	int vfio_dev_fd;
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret, msix_bar;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+
+	struct pci_map *maps;
+	uint32_t msix_table_offset = 0;
+	uint32_t msix_table_size = 0;
+	uint32_t ioport_bar;
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	if ((ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
+					&vfio_dev_fd, &device_info)))
+		return ret;
+
+	/* get MSI-X BAR, if any (we have to know where it is because we can't
+	 * easily mmap it when using VFIO) */
+	msix_bar = -1;
+	ret = pci_vfio_get_msix_bar(vfio_dev_fd, &msix_bar,
+				    &msix_table_offset, &msix_table_size);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "  %s cannot get MSI-X BAR number!\n", pci_addr);
+		close(vfio_dev_fd);
+		return -1;
+	}
+
+	/* if we're in a primary process, allocate vfio_res and get region info */
+	if (internal_config.process_type == RTE_PROC_PRIMARY) {
+		vfio_res = rte_zmalloc("VFIO_RES", sizeof(*vfio_res), 0);
+		if (vfio_res == NULL) {
+			RTE_LOG(ERR, EAL,
+				"%s(): cannot store uio mmap details\n", __func__);
+			close(vfio_dev_fd);
+			return -1;
+		}
+		memcpy(&vfio_res->pci_addr, &dev->addr, sizeof(vfio_res->pci_addr));
+
+		/* get number of registers (up to BAR5) */
+		vfio_res->nb_maps = RTE_MIN((int) device_info.num_regions,
+				VFIO_PCI_BAR5_REGION_INDEX + 1);
+	} else {
+		/* if we're in a secondary process, just find our tailq entry */
+		TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
+			if (rte_eal_compare_pci_addr(&vfio_res->pci_addr,
+						     &dev->addr))
+				continue;
+			break;
+		}
+		/* if we haven't found our tailq entry, something's wrong */
+		if (vfio_res == NULL) {
+			RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
+					pci_addr);
+			close(vfio_dev_fd);
+			return -1;
+		}
+	}
+
+	/* map BARs */
+	maps = vfio_res->maps;
+
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+		struct vfio_region_info reg = { .argsz = sizeof(reg) };
+		void *bar_addr;
+		struct memreg {
+			unsigned long offset, size;
+		} memreg[2] = {};
+
+		reg.index = i;
+
+		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg);
+
+		if (ret) {
+			RTE_LOG(ERR, EAL, "  %s cannot get device region info "
+					"error %i (%s)\n", pci_addr, errno, strerror(errno));
+			close(vfio_dev_fd);
+			if (internal_config.process_type == RTE_PROC_PRIMARY)
+				rte_free(vfio_res);
+			return -1;
+		}
+
+		/* chk for io port region */
+		ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar),
+			      VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX)
+			      + PCI_BASE_ADDRESS_0 + i*4);
+
+		if (ret != sizeof(ioport_bar)) {
+			RTE_LOG(ERR, EAL,
+				"Cannot read command (%x) from config space!\n",
+				PCI_BASE_ADDRESS_0 + i*4);
+			return -1;
+		}
+
+		if (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) {
+			RTE_LOG(INFO, EAL,
+				"Ignore mapping IO port bar(%d) addr: %x\n",
+				 i, ioport_bar);
+			continue;
+		}
+
+		/* skip non-mmapable BARs */
+		if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0)
+			continue;
+
+		if (i == msix_bar) {
+			/*
+			 * VFIO will not let us map the MSI-X table,
+			 * but we can map around it.
+			 */
+			uint32_t table_start = msix_table_offset;
+			uint32_t table_end = table_start + msix_table_size;
+			table_end = (table_end + ~PAGE_MASK) & PAGE_MASK;
+			table_start &= PAGE_MASK;
+
+			if (table_start == 0 && table_end >= reg.size) {
+				/* Cannot map this BAR */
+				RTE_LOG(DEBUG, EAL, "Skipping BAR %d\n", i);
+				continue;
+			} else {
+				memreg[0].offset = reg.offset;
+				memreg[0].size = table_start;
+				memreg[1].offset = reg.offset + table_end;
+				memreg[1].size = reg.size - table_end;
+
+				RTE_LOG(DEBUG, EAL,
+					"Trying to map BAR %d that contains the MSI-X "
+					"table. Trying offsets: "
+					"0x%04lx:0x%04lx, 0x%04lx:0x%04lx\n", i,
+					memreg[0].offset, memreg[0].size,
+					memreg[1].offset, memreg[1].size);
+			}
+		} else {
+			memreg[0].offset = reg.offset;
+			memreg[0].size = reg.size;
+		}
+
+		/* try to figure out an address */
+		if (internal_config.process_type == RTE_PROC_PRIMARY) {
+			/* try mapping somewhere close to the end of hugepages */
+			if (pci_map_addr == NULL)
+				pci_map_addr = pci_find_max_end_va();
+
+			bar_addr = pci_map_addr;
+			pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
+		} else {
+			bar_addr = maps[i].addr;
+		}
+
+		/* reserve the address using an inaccessible mapping */
+		bar_addr = mmap(bar_addr, reg.size, 0, MAP_PRIVATE |
+				MAP_ANONYMOUS, -1, 0);
+		if (bar_addr != MAP_FAILED) {
+			void *map_addr = NULL;
+			if (memreg[0].size) {
+				/* actual map of first part */
+				map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
+							    memreg[0].offset,
+							    memreg[0].size,
+							    MAP_FIXED);
+			}
+
+			/* if there's a second part, try to map it */
+			if (map_addr != MAP_FAILED
+			    && memreg[1].offset && memreg[1].size) {
+				void *second_addr = RTE_PTR_ADD(bar_addr,
+								memreg[1].offset -
+								(uintptr_t)reg.offset);
+				map_addr = pci_map_resource(second_addr,
+							    vfio_dev_fd, memreg[1].offset,
+							    memreg[1].size,
+							    MAP_FIXED);
+			}
+
+			if (map_addr == MAP_FAILED || !map_addr) {
+				munmap(bar_addr, reg.size);
+				bar_addr = MAP_FAILED;
+			}
+		}
+
+		if (bar_addr == MAP_FAILED ||
+				(internal_config.process_type == RTE_PROC_SECONDARY &&
+						bar_addr != maps[i].addr)) {
+			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n", pci_addr, i,
+					strerror(errno));
+			close(vfio_dev_fd);
+			if (internal_config.process_type == RTE_PROC_PRIMARY)
+				rte_free(vfio_res);
+			return -1;
+		}
+
+		maps[i].addr = bar_addr;
+		maps[i].offset = reg.offset;
+		maps[i].size = reg.size;
+		maps[i].path = NULL; /* vfio doesn't have per-resource paths */
+		dev->mem_resource[i].addr = bar_addr;
+	}
+
+	/* if secondary process, do not set up interrupts */
+	if (internal_config.process_type == RTE_PROC_PRIMARY) {
+		if (pci_vfio_setup_interrupts(dev, vfio_dev_fd) != 0) {
+			RTE_LOG(ERR, EAL, "  %s error setting up interrupts!\n", pci_addr);
+			close(vfio_dev_fd);
+			rte_free(vfio_res);
+			return -1;
+		}
+
+		/* set bus mastering for the device */
+		if (pci_vfio_set_bus_master(vfio_dev_fd, true)) {
+			RTE_LOG(ERR, EAL, "  %s cannot set up bus mastering!\n", pci_addr);
+			close(vfio_dev_fd);
+			rte_free(vfio_res);
+			return -1;
+		}
+
+		/* Reset the device */
+		ioctl(vfio_dev_fd, VFIO_DEVICE_RESET);
+	}
+
+	if (internal_config.process_type == RTE_PROC_PRIMARY)
+		TAILQ_INSERT_TAIL(vfio_res_list, vfio_res, next);
+
+	return 0;
+}
+
+int
+pci_vfio_unmap_resource(struct rte_pci_device *dev)
+{
+	char pci_addr[PATH_MAX] = {0};
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list;
+
+	struct pci_map *maps;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+
+	if (close(dev->intr_handle.fd) < 0) {
+		RTE_LOG(INFO, EAL, "Error when closing eventfd file descriptor for %s\n",
+			pci_addr);
+		return -1;
+	}
+
+	if (pci_vfio_set_bus_master(dev->intr_handle.vfio_dev_fd, false)) {
+		RTE_LOG(ERR, EAL, "  %s cannot unset bus mastering for PCI device!\n",
+				pci_addr);
+		return -1;
+	}
+
+	ret = vfio_release_device(pci_get_sysfs_path(), pci_addr,
+				  dev->intr_handle.vfio_dev_fd);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot release device\n", __func__);
+		return ret;
+	}
+
+	vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+	/* Get vfio_res */
+	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
+		if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
+			continue;
+		break;
+	}
+	/* if we haven't found our tailq entry, something's wrong */
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
+				pci_addr);
+		return -1;
+	}
+
+	/* unmap BARs */
+	maps = vfio_res->maps;
+
+	RTE_LOG(INFO, EAL, "Releasing pci mapped resource for %s\n",
+		pci_addr);
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+
+		/*
+		 * We do not need to be aware of MSI-X table BAR mappings as
+		 * when mapping. Just using current maps array is enough
+		 */
+		if (maps[i].addr) {
+			RTE_LOG(INFO, EAL, "Calling pci_unmap_resource for %s at %p\n",
+				pci_addr, maps[i].addr);
+			pci_unmap_resource(maps[i].addr, maps[i].size);
+		}
+	}
+
+	TAILQ_REMOVE(vfio_res_list, vfio_res, next);
+
+	return 0;
+}
+
+int
+pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
+		    struct rte_pci_ioport *p)
+{
+	if (bar < VFIO_PCI_BAR0_REGION_INDEX ||
+	    bar > VFIO_PCI_BAR5_REGION_INDEX) {
+		RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar);
+		return -1;
+	}
+
+	p->dev = dev;
+	p->base = VFIO_GET_REGION_ADDR(bar);
+	return 0;
+}
+
+void
+pci_vfio_ioport_read(struct rte_pci_ioport *p,
+		     void *data, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
+
+	if (pread64(intr_handle->vfio_dev_fd, data,
+		    len, p->base + offset) <= 0)
+		RTE_LOG(ERR, EAL,
+			"Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n",
+			VFIO_GET_REGION_IDX(p->base), (int)offset);
+}
+
+void
+pci_vfio_ioport_write(struct rte_pci_ioport *p,
+		      const void *data, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
+
+	if (pwrite64(intr_handle->vfio_dev_fd, data,
+		     len, p->base + offset) <= 0)
+		RTE_LOG(ERR, EAL,
+			"Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n",
+			VFIO_GET_REGION_IDX(p->base), (int)offset);
+}
+
+int
+pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
+{
+	RTE_SET_USED(p);
+	return -1;
+}
+
+int
+pci_vfio_enable(void)
+{
+	return vfio_enable("vfio_pci");
+}
+
+int
+pci_vfio_is_enabled(void)
+{
+	return vfio_is_enabled("vfio_pci");
+}
+#endif
diff --git a/drivers/bus/pci/linux/rte_vfio_mp_sync.c b/drivers/bus/pci/linux/rte_vfio_mp_sync.c
new file mode 100644
index 0000000..2c1654d
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_vfio_mp_sync.c
@@ -0,0 +1,424 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <pthread.h>
+
+/* sys/un.h with __USE_MISC uses strlen, which is unsafe */
+#ifdef __USE_MISC
+#define REMOVED_USE_MISC
+#undef __USE_MISC
+#endif
+#include <sys/un.h>
+/* make sure we redefine __USE_MISC only if it was previously undefined */
+#ifdef REMOVED_USE_MISC
+#define __USE_MISC
+#undef REMOVED_USE_MISC
+#endif
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "eal_thread.h"
+#include "rte_pci_init.h"
+
+/**
+ * @file
+ * VFIO socket for communication between primary and secondary processes.
+ *
+ * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
+ */
+
+#ifdef VFIO_PRESENT
+
+#define SOCKET_PATH_FMT "%s/.%s_mp_socket"
+#define CMSGLEN (CMSG_LEN(sizeof(int)))
+#define FD_TO_CMSGHDR(fd, chdr) \
+		do {\
+			(chdr).cmsg_len = CMSGLEN;\
+			(chdr).cmsg_level = SOL_SOCKET;\
+			(chdr).cmsg_type = SCM_RIGHTS;\
+			memcpy((chdr).__cmsg_data, &(fd), sizeof(fd));\
+		} while (0)
+#define CMSGHDR_TO_FD(chdr, fd) \
+			memcpy(&(fd), (chdr).__cmsg_data, sizeof(fd))
+
+static pthread_t socket_thread;
+static int mp_socket_fd;
+
+
+/* get socket path (/var/run if root, $HOME otherwise) */
+static void
+get_socket_path(char *buffer, int bufsz)
+{
+	const char *dir = "/var/run";
+	const char *home_dir = getenv("HOME");
+
+	if (getuid() != 0 && home_dir != NULL)
+		dir = home_dir;
+
+	/* use current prefix as file path */
+	snprintf(buffer, bufsz, SOCKET_PATH_FMT, dir,
+			internal_config.hugefile_prefix);
+}
+
+
+
+/*
+ * data flow for socket comm protocol:
+ * 1. client sends SOCKET_REQ_CONTAINER or SOCKET_REQ_GROUP
+ * 1a. in case of SOCKET_REQ_GROUP, client also then sends group number
+ * 2. server receives message
+ * 2a. in case of invalid group, SOCKET_ERR is sent back to client
+ * 2b. in case of unbound group, SOCKET_NO_FD is sent back to client
+ * 2c. in case of valid group, SOCKET_OK is sent and immediately followed by fd
+ *
+ * in case of any error, socket is closed.
+ */
+
+/* send a request, return -1 on error */
+int
+vfio_mp_sync_send_request(int socket, int req)
+{
+	struct msghdr hdr;
+	struct iovec iov;
+	int buf;
+	int ret;
+
+	memset(&hdr, 0, sizeof(hdr));
+
+	buf = req;
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+
+	ret = sendmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+	return 0;
+}
+
+/* receive a request and return it */
+int
+vfio_mp_sync_receive_request(int socket)
+{
+	int buf;
+	struct msghdr hdr;
+	struct iovec iov;
+	int ret, req;
+
+	memset(&hdr, 0, sizeof(hdr));
+
+	buf = SOCKET_ERR;
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+
+	ret = recvmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+
+	req = buf;
+
+	return req;
+}
+
+/* send OK in message, fd in control message */
+int
+vfio_mp_sync_send_fd(int socket, int fd)
+{
+	int buf;
+	struct msghdr hdr;
+	struct cmsghdr *chdr;
+	char chdr_buf[CMSGLEN];
+	struct iovec iov;
+	int ret;
+
+	chdr = (struct cmsghdr *) chdr_buf;
+	memset(chdr, 0, sizeof(chdr_buf));
+	memset(&hdr, 0, sizeof(hdr));
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+	hdr.msg_control = chdr;
+	hdr.msg_controllen = CMSGLEN;
+
+	buf = SOCKET_OK;
+	FD_TO_CMSGHDR(fd, *chdr);
+
+	ret = sendmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+	return 0;
+}
+
+/* receive OK in message, fd in control message */
+int
+vfio_mp_sync_receive_fd(int socket)
+{
+	int buf;
+	struct msghdr hdr;
+	struct cmsghdr *chdr;
+	char chdr_buf[CMSGLEN];
+	struct iovec iov;
+	int ret, req, fd;
+
+	buf = SOCKET_ERR;
+
+	chdr = (struct cmsghdr *) chdr_buf;
+	memset(chdr, 0, sizeof(chdr_buf));
+	memset(&hdr, 0, sizeof(hdr));
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+	hdr.msg_control = chdr;
+	hdr.msg_controllen = CMSGLEN;
+
+	ret = recvmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+
+	req = buf;
+
+	if (req != SOCKET_OK)
+		return -1;
+
+	CMSGHDR_TO_FD(*chdr, fd);
+
+	return fd;
+}
+
+/* connect socket_fd in secondary process to the primary process's socket */
+int
+vfio_mp_sync_connect_to_primary(void)
+{
+	struct sockaddr_un addr;
+	socklen_t sockaddr_len;
+	int socket_fd;
+
+	/* set up a socket */
+	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+	if (socket_fd < 0) {
+		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
+		return -1;
+	}
+
+	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
+	addr.sun_family = AF_UNIX;
+
+	sockaddr_len = sizeof(struct sockaddr_un);
+
+	if (connect(socket_fd, (struct sockaddr *) &addr, sockaddr_len) == 0)
+		return socket_fd;
+
+	/* if connect failed */
+	close(socket_fd);
+	return -1;
+}
+
+
+
+/*
+ * socket listening thread for primary process
+ */
+static __attribute__((noreturn)) void *
+vfio_mp_sync_thread(void __rte_unused * arg)
+{
+	int ret, fd, vfio_data;
+
+	/* wait for requests on the socket */
+	for (;;) {
+		int conn_sock;
+		struct sockaddr_un addr;
+		socklen_t sockaddr_len = sizeof(addr);
+
+		/* this is a blocking call */
+		conn_sock = accept(mp_socket_fd, (struct sockaddr *) &addr,
+				&sockaddr_len);
+
+		/* just restart on error */
+		if (conn_sock == -1)
+			continue;
+
+		/* set socket to linger after close */
+		struct linger l;
+		l.l_onoff = 1;
+		l.l_linger = 60;
+
+		if (setsockopt(conn_sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0)
+			RTE_LOG(WARNING, EAL, "Cannot set SO_LINGER option "
+					"on listen socket (%s)\n", strerror(errno));
+
+		ret = vfio_mp_sync_receive_request(conn_sock);
+
+		switch (ret) {
+		case SOCKET_REQ_CONTAINER:
+			fd = vfio_get_container_fd();
+			if (fd < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			else
+				vfio_mp_sync_send_fd(conn_sock, fd);
+			close(fd);
+			break;
+		case SOCKET_REQ_GROUP:
+			/* wait for group number */
+			vfio_data = vfio_mp_sync_receive_request(conn_sock);
+			if (vfio_data < 0) {
+				close(conn_sock);
+				continue;
+			}
+
+			fd = vfio_get_group_fd(vfio_data);
+
+			if (fd < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			/* if VFIO group exists but isn't bound to VFIO driver */
+			else if (fd == 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
+			/* if group exists and is bound to VFIO driver */
+			else {
+				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
+				vfio_mp_sync_send_fd(conn_sock, fd);
+			}
+			break;
+		case SOCKET_CLR_GROUP:
+			/* wait for group fd */
+			vfio_data = vfio_mp_sync_receive_request(conn_sock);
+			if (vfio_data < 0) {
+				close(conn_sock);
+				continue;
+			}
+
+			ret = clear_group(vfio_data);
+
+			if (ret < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
+			else
+				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
+			break;
+		default:
+			vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			break;
+		}
+		close(conn_sock);
+	}
+}
+
+static int
+vfio_mp_sync_socket_setup(void)
+{
+	int ret, socket_fd;
+	struct sockaddr_un addr;
+	socklen_t sockaddr_len;
+
+	/* set up a socket */
+	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+	if (socket_fd < 0) {
+		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
+		return -1;
+	}
+
+	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
+	addr.sun_family = AF_UNIX;
+
+	sockaddr_len = sizeof(struct sockaddr_un);
+
+	unlink(addr.sun_path);
+
+	ret = bind(socket_fd, (struct sockaddr *) &addr, sockaddr_len);
+	if (ret) {
+		RTE_LOG(ERR, EAL, "Failed to bind socket: %s!\n", strerror(errno));
+		close(socket_fd);
+		return -1;
+	}
+
+	ret = listen(socket_fd, 50);
+	if (ret) {
+		RTE_LOG(ERR, EAL, "Failed to listen: %s!\n", strerror(errno));
+		close(socket_fd);
+		return -1;
+	}
+
+	/* save the socket in local configuration */
+	mp_socket_fd = socket_fd;
+
+	return 0;
+}
+
+/*
+ * set up a local socket and tell it to listen for incoming connections
+ */
+int
+vfio_mp_sync_setup(void)
+{
+	int ret;
+	char thread_name[RTE_MAX_THREAD_NAME_LEN];
+
+	if (vfio_mp_sync_socket_setup() < 0) {
+		RTE_LOG(ERR, EAL, "Failed to set up local socket!\n");
+		return -1;
+	}
+
+	ret = pthread_create(&socket_thread, NULL,
+			vfio_mp_sync_thread, NULL);
+	if (ret) {
+		RTE_LOG(ERR, EAL,
+			"Failed to create thread for communication with secondary processes!\n");
+		close(mp_socket_fd);
+		return -1;
+	}
+
+	/* Set thread_name for aid in debugging. */
+	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "vfio-sync");
+	ret = rte_thread_setname(socket_thread, thread_name);
+	if (ret)
+		RTE_LOG(DEBUG, EAL,
+			"Failed to set thread name for secondary processes!\n");
+
+	return 0;
+}
+
+#endif
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
new file mode 100644
index 0000000..7ff1fc4
--- /dev/null
+++ b/drivers/bus/pci/private.h
@@ -0,0 +1,173 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PCI_PRIVATE_H_
+#define _PCI_PRIVATE_H_
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <rte_pci.h>
+
+struct rte_pci_driver;
+struct rte_pci_device;
+
+/**
+ * Find the name of a PCI device.
+ */
+void
+pci_name_set(struct rte_pci_device *dev);
+
+/**
+ * Add a PCI device to the PCI Bus (append to PCI Device list). This function
+ * also updates the bus references of the PCI Device (and the generic device
+ * object embedded within.
+ *
+ * @param pci_dev
+ *	PCI device to add
+ * @return void
+ */
+void rte_pci_add_device(struct rte_pci_device *pci_dev);
+
+/**
+ * Insert a PCI device in the PCI Bus at a particular location in the device
+ * list. It also updates the PCI Bus reference of the new devices to be
+ * inserted.
+ *
+ * @param exist_pci_dev
+ *	Existing PCI device in PCI Bus
+ * @param new_pci_dev
+ *	PCI device to be added before exist_pci_dev
+ * @return void
+ */
+void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+		struct rte_pci_device *new_pci_dev);
+
+/**
+ * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
+ * in the PCI device object as well as the generic device object.
+ *
+ * @param pci_device
+ *	PCI device to be removed from PCI Bus
+ * @return void
+ */
+void rte_pci_remove_device(struct rte_pci_device *pci_device);
+
+/**
+ * Update a pci device object by asking the kernel for the latest information.
+ *
+ * This function is private to EAL.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to look for
+ * @return
+ *   - 0 on success.
+ *   - negative on error.
+ */
+int pci_update_device(const struct rte_pci_addr *addr);
+
+/**
+ * Unbind kernel driver for this device
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_unbind_kernel_driver(struct rte_pci_device *dev);
+
+/**
+ * Map the PCI resource of a PCI device in virtual memory
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_map_resource(struct rte_pci_device *dev);
+
+/**
+ * Unmap the PCI resource of a PCI device
+ *
+ * This function is private to EAL.
+ */
+void pci_uio_unmap_resource(struct rte_pci_device *dev);
+
+/**
+ * Allocate uio resource for PCI device
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device to allocate uio resource
+ * @param uio_res
+ *   Pointer to uio resource.
+ *   If the function returns 0, the pointer will be filled.
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res);
+
+/**
+ * Free uio resource for PCI device
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device to free uio resource
+ * @param uio_res
+ *   Pointer to uio resource.
+ */
+void pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res);
+
+/**
+ * Map device memory to uio resource
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device that has memory information.
+ * @param res_idx
+ *   Memory resource index of the PCI device.
+ * @param uio_res
+ *  uio resource that will keep mapping information.
+ * @param map_idx
+ *   Mapping information index of the uio resource.
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx);
+
+#endif /* _PCI_PRIVATE_H_ */
diff --git a/drivers/bus/pci/rte_bus_pci_version.map b/drivers/bus/pci/rte_bus_pci_version.map
new file mode 100644
index 0000000..eca49e9
--- /dev/null
+++ b/drivers/bus/pci/rte_bus_pci_version.map
@@ -0,0 +1,21 @@
+DPDK_17.08 {
+	global:
+
+	rte_pci_detach;
+	rte_pci_dump;
+	rte_pci_ioport_map;
+	rte_pci_ioport_read;
+	rte_pci_ioport_unmap;
+	rte_pci_ioport_write;
+	rte_pci_map_device;
+	rte_pci_probe;
+	rte_pci_probe_one;
+	rte_pci_read_config;
+	rte_pci_register;
+	rte_pci_scan;
+	rte_pci_unmap_device;
+	rte_pci_unregister;
+	rte_pci_write_config;
+
+	local: *;
+};
diff --git a/drivers/bus/pci/rte_pci_common.c b/drivers/bus/pci/rte_pci_common.c
new file mode 100644
index 0000000..c37b85b
--- /dev/null
+++ b/drivers/bus/pci/rte_pci_common.c
@@ -0,0 +1,542 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+
+#include "private.h"
+
+extern struct rte_pci_bus rte_pci_bus;
+
+#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
+
+const char *pci_get_sysfs_path(void)
+{
+	const char *path = NULL;
+
+	path = getenv("SYSFS_PCI_DEVICES");
+	if (path == NULL)
+		return SYSFS_PCI_DEVICES;
+
+	return path;
+}
+
+static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
+{
+	struct rte_devargs *devargs;
+	struct rte_pci_addr addr;
+	struct rte_bus *pbus;
+
+	pbus = rte_bus_find_by_name("pci");
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->bus != pbus)
+			continue;
+		devargs->bus->parse(devargs->name, &addr);
+		if (!rte_eal_compare_pci_addr(&dev->addr, &addr))
+			return devargs;
+	}
+	return NULL;
+}
+
+void
+pci_name_set(struct rte_pci_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	/* Each device has its internal, canonical name set. */
+	rte_pci_device_name(&dev->addr,
+			dev->name, sizeof(dev->name));
+	devargs = pci_devargs_lookup(dev);
+	dev->device.devargs = devargs;
+	/* In blacklist mode, if the device is not blacklisted, no
+	 * rte_devargs exists for it.
+	 */
+	if (devargs != NULL)
+		/* If an rte_devargs exists, the generic rte_device uses the
+		 * given name as its namea
+		 */
+		dev->device.name = dev->device.devargs->name;
+	else
+		/* Otherwise, it uses the internal, canonical form. */
+		dev->device.name = dev->name;
+}
+
+/*
+ * Match the PCI Driver and Device using the ID Table
+ *
+ * @param pci_drv
+ *	PCI driver from which ID table would be extracted
+ * @param pci_dev
+ *	PCI device to match against the driver
+ * @return
+ *	1 for successful match
+ *	0 for unsuccessful match
+ */
+static int
+rte_pci_match(const struct rte_pci_driver *pci_drv,
+	      const struct rte_pci_device *pci_dev)
+{
+	const struct rte_pci_id *id_table;
+
+	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
+	     id_table++) {
+		/* check if device's identifiers match the driver's ones */
+		if (id_table->vendor_id != pci_dev->id.vendor_id &&
+				id_table->vendor_id != PCI_ANY_ID)
+			continue;
+		if (id_table->device_id != pci_dev->id.device_id &&
+				id_table->device_id != PCI_ANY_ID)
+			continue;
+		if (id_table->subsystem_vendor_id !=
+		    pci_dev->id.subsystem_vendor_id &&
+		    id_table->subsystem_vendor_id != PCI_ANY_ID)
+			continue;
+		if (id_table->subsystem_device_id !=
+		    pci_dev->id.subsystem_device_id &&
+		    id_table->subsystem_device_id != PCI_ANY_ID)
+			continue;
+		if (id_table->class_id != pci_dev->id.class_id &&
+				id_table->class_id != RTE_CLASS_ANY_ID)
+			continue;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * If vendor/device ID match, call the probe() function of the
+ * driver.
+ */
+static int
+rte_pci_probe_one_driver(struct rte_pci_driver *dr,
+			 struct rte_pci_device *dev)
+{
+	int ret;
+	struct rte_pci_addr *loc;
+
+	if ((dr == NULL) || (dev == NULL))
+		return -EINVAL;
+
+	loc = &dev->addr;
+
+	/* The device is not blacklisted; Check if driver supports it */
+	if (!rte_pci_match(dr, dev))
+		/* Match of device and driver failed */
+		return 1;
+
+	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			loc->domain, loc->bus, loc->devid, loc->function,
+			dev->device.numa_node);
+
+	/* no initialization when blacklisted, return without error */
+	if (dev->device.devargs != NULL &&
+		dev->device.devargs->policy ==
+			RTE_DEV_BLACKLISTED) {
+		RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
+			" initializing\n");
+		return 1;
+	}
+
+	if (dev->device.numa_node < 0) {
+		RTE_LOG(WARNING, EAL, "  Invalid NUMA socket, default to 0\n");
+		dev->device.numa_node = 0;
+	}
+
+	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
+		dev->id.device_id, dr->driver.name);
+
+	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+		/* map resources for devices that use igb_uio */
+		ret = rte_pci_map_device(dev);
+		if (ret != 0)
+			return ret;
+	}
+
+	/* reference driver structure */
+	dev->driver = dr;
+	dev->device.driver = &dr->driver;
+
+	/* call the driver probe() function */
+	ret = dr->probe(dr, dev);
+	if (ret) {
+		dev->driver = NULL;
+		dev->device.driver = NULL;
+		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
+			/* Don't unmap if device is unsupported and
+			 * driver needs mapped resources.
+			 */
+			!(ret > 0 &&
+				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
+			rte_pci_unmap_device(dev);
+	}
+
+	return ret;
+}
+
+/*
+ * If vendor/device ID match, call the remove() function of the
+ * driver.
+ */
+static int
+rte_pci_detach_dev(struct rte_pci_device *dev)
+{
+	struct rte_pci_addr *loc;
+	struct rte_pci_driver *dr;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	dr = dev->driver;
+	loc = &dev->addr;
+
+	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			loc->domain, loc->bus, loc->devid,
+			loc->function, dev->device.numa_node);
+
+	RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
+			dev->id.device_id, dr->driver.name);
+
+	if (dr->remove && (dr->remove(dev) < 0))
+		return -1;	/* negative value is an error */
+
+	/* clear driver structure */
+	dev->driver = NULL;
+
+	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
+		/* unmap resources for devices that use igb_uio */
+		rte_pci_unmap_device(dev);
+
+	return 0;
+}
+
+/*
+ * If vendor/device ID match, call the probe() function of all
+ * registered driver for the given device. Return -1 if initialization
+ * failed, return 1 if no driver is found for this device.
+ */
+static int
+pci_probe_all_drivers(struct rte_pci_device *dev)
+{
+	struct rte_pci_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	/* Check if a driver is already loaded */
+	if (dev->driver != NULL)
+		return 0;
+
+	FOREACH_DRIVER_ON_PCIBUS(dr) {
+		rc = rte_pci_probe_one_driver(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * Find the pci device specified by pci address, then invoke probe function of
+ * the driver of the device.
+ */
+int
+rte_pci_probe_one(const struct rte_pci_addr *addr)
+{
+	struct rte_pci_device *dev = NULL;
+
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	/* update current pci device in global list, kernel bindings might have
+	 * changed since last time we looked at it.
+	 */
+	if (pci_update_device(addr) < 0)
+		goto err_return;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (rte_eal_compare_pci_addr(&dev->addr, addr))
+			continue;
+
+		ret = pci_probe_all_drivers(dev);
+		if (ret)
+			goto err_return;
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL,
+		"Requested device " PCI_PRI_FMT " cannot be used\n",
+		addr->domain, addr->bus, addr->devid, addr->function);
+	return -1;
+}
+
+/*
+ * Detach device specified by its pci address.
+ */
+int
+rte_pci_detach(const struct rte_pci_addr *addr)
+{
+	struct rte_pci_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (rte_eal_compare_pci_addr(&dev->addr, addr))
+			continue;
+
+		ret = rte_pci_detach_dev(dev);
+		if (ret < 0)
+			/* negative value is an error */
+			goto err_return;
+		if (ret > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+
+		rte_pci_remove_device(dev);
+		free(dev);
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
+			" cannot be used\n", dev->addr.domain, dev->addr.bus,
+			dev->addr.devid, dev->addr.function);
+	return -1;
+}
+
+/*
+ * Scan the content of the PCI bus, and call the probe() function for
+ * all registered drivers that have a matching entry in its id_table
+ * for discovered devices.
+ */
+int
+rte_pci_probe(void)
+{
+	struct rte_pci_device *dev = NULL;
+	size_t probed = 0, failed = 0;
+	struct rte_devargs *devargs;
+	int probe_all = 0;
+	int ret = 0;
+
+	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
+		probe_all = 1;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		probed++;
+
+		devargs = dev->device.devargs;
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = pci_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->policy == RTE_DEV_WHITELISTED)
+			ret = pci_probe_all_drivers(dev);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
+				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
+				 dev->addr.devid, dev->addr.function);
+			rte_errno = errno;
+			failed++;
+			ret = 0;
+		}
+	}
+
+	return (probed && probed == failed) ? -1 : 0;
+}
+
+/* dump one device */
+static int
+pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
+{
+	int i;
+
+	fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
+	       dev->addr.devid, dev->addr.function);
+	fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
+	       dev->id.device_id);
+
+	for (i = 0; i != sizeof(dev->mem_resource) /
+		sizeof(dev->mem_resource[0]); i++) {
+		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
+			dev->mem_resource[i].phys_addr,
+			dev->mem_resource[i].len);
+	}
+	return 0;
+}
+
+/* dump devices on the bus */
+void
+rte_pci_dump(FILE *f)
+{
+	struct rte_pci_device *dev = NULL;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		pci_dump_one_device(f, dev);
+	}
+}
+
+static int
+pci_parse(const char *name, void *addr)
+{
+	struct rte_pci_addr *out = addr;
+	struct rte_pci_addr pci_addr;
+	bool parse;
+
+	parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
+		 eal_parse_pci_DomBDF(name, &pci_addr) == 0);
+	if (parse && addr != NULL)
+		*out = pci_addr;
+	return parse == false;
+}
+
+/* register a driver */
+void
+rte_pci_register(struct rte_pci_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
+	driver->bus = &rte_pci_bus;
+}
+
+/* unregister a driver */
+void
+rte_pci_unregister(struct rte_pci_driver *driver)
+{
+	TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
+	driver->bus = NULL;
+}
+
+/* Add a device to PCI bus */
+void
+rte_pci_add_device(struct rte_pci_device *pci_dev)
+{
+	TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
+}
+
+/* Insert a device into a predefined position in PCI bus */
+void
+rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+		      struct rte_pci_device *new_pci_dev)
+{
+	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
+}
+
+/* Remove a device from PCI bus */
+void
+rte_pci_remove_device(struct rte_pci_device *pci_dev)
+{
+	TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
+}
+
+static struct rte_device *
+pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		const void *data)
+{
+	struct rte_pci_device *dev;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (start && &dev->device == start) {
+			start = NULL; /* starting point found */
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+
+	return NULL;
+}
+
+static int
+pci_plug(struct rte_device *dev)
+{
+	return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
+}
+
+static int
+pci_unplug(struct rte_device *dev)
+{
+	struct rte_pci_device *pdev;
+	int ret;
+
+	pdev = RTE_DEV_TO_PCI(dev);
+	ret = rte_pci_detach_dev(pdev);
+	rte_pci_remove_device(pdev);
+	free(pdev);
+	return ret;
+}
+
+struct rte_pci_bus rte_pci_bus = {
+	.bus = {
+		.scan = rte_pci_scan,
+		.probe = rte_pci_probe,
+		.find_device = pci_find_device,
+		.plug = pci_plug,
+		.unplug = pci_unplug,
+		.parse = pci_parse,
+	},
+	.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
+	.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(pci, rte_pci_bus.bus);
diff --git a/drivers/bus/pci/rte_pci_common_uio.c b/drivers/bus/pci/rte_pci_common_uio.c
new file mode 100644
index 0000000..4365660
--- /dev/null
+++ b/drivers/bus/pci/rte_pci_common_uio.c
@@ -0,0 +1,234 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_tailq.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+
+#include "private.h"
+
+static struct rte_tailq_elem rte_uio_tailq = {
+	.name = "UIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_uio_tailq)
+
+static int
+pci_uio_map_secondary(struct rte_pci_device *dev)
+{
+	int fd, i, j;
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	TAILQ_FOREACH(uio_res, uio_res_list, next) {
+
+		/* skip this element if it doesn't match our PCI address */
+		if (rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+			continue;
+
+		for (i = 0; i != uio_res->nb_maps; i++) {
+			/*
+			 * open devname, to mmap it
+			 */
+			fd = open(uio_res->maps[i].path, O_RDWR);
+			if (fd < 0) {
+				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+					uio_res->maps[i].path, strerror(errno));
+				return -1;
+			}
+
+			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
+					fd, (off_t)uio_res->maps[i].offset,
+					(size_t)uio_res->maps[i].size, 0);
+			/* fd is not needed in slave process, close it */
+			close(fd);
+			if (mapaddr != uio_res->maps[i].addr) {
+				RTE_LOG(ERR, EAL,
+					"Cannot mmap device resource file %s to address: %p\n",
+					uio_res->maps[i].path,
+					uio_res->maps[i].addr);
+				if (mapaddr != MAP_FAILED) {
+					/* unmap addrs correctly mapped */
+					for (j = 0; j < i; j++)
+						pci_unmap_resource(
+							uio_res->maps[j].addr,
+							(size_t)uio_res->maps[j].size);
+					/* unmap addr wrongly mapped */
+					pci_unmap_resource(mapaddr,
+						(size_t)uio_res->maps[i].size);
+				}
+				return -1;
+			}
+		}
+		return 0;
+	}
+
+	RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
+	return 1;
+}
+
+/* map the PCI resource of a PCI device in virtual memory */
+int
+pci_uio_map_resource(struct rte_pci_device *dev)
+{
+	int i, map_idx = 0, ret;
+	uint64_t phaddr;
+	struct mapped_pci_resource *uio_res = NULL;
+	struct mapped_pci_res_list *uio_res_list =
+		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.uio_cfg_fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* secondary processes - use already recorded details */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return pci_uio_map_secondary(dev);
+
+	/* allocate uio resource */
+	ret = pci_uio_alloc_resource(dev, &uio_res);
+	if (ret)
+		return ret;
+
+	/* Map all BARs */
+	for (i = 0; i != PCI_MAX_RESOURCE; i++) {
+		/* skip empty BAR */
+		phaddr = dev->mem_resource[i].phys_addr;
+		if (phaddr == 0)
+			continue;
+
+		ret = pci_uio_map_resource_by_index(dev, i,
+				uio_res, map_idx);
+		if (ret)
+			goto error;
+
+		map_idx++;
+	}
+
+	uio_res->nb_maps = map_idx;
+
+	TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
+
+	return 0;
+error:
+	for (i = 0; i < map_idx; i++) {
+		pci_unmap_resource(uio_res->maps[i].addr,
+				(size_t)uio_res->maps[i].size);
+		rte_free(uio_res->maps[i].path);
+	}
+	pci_uio_free_resource(dev, uio_res);
+	return -1;
+}
+
+static void
+pci_uio_unmap(struct mapped_pci_resource *uio_res)
+{
+	int i;
+
+	if (uio_res == NULL)
+		return;
+
+	for (i = 0; i != uio_res->nb_maps; i++) {
+		pci_unmap_resource(uio_res->maps[i].addr,
+				(size_t)uio_res->maps[i].size);
+		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+			rte_free(uio_res->maps[i].path);
+	}
+}
+
+static struct mapped_pci_resource *
+pci_uio_find_resource(struct rte_pci_device *dev)
+{
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	if (dev == NULL)
+		return NULL;
+
+	TAILQ_FOREACH(uio_res, uio_res_list, next) {
+
+		/* skip this element if it doesn't match our PCI address */
+		if (!rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+			return uio_res;
+	}
+	return NULL;
+}
+
+/* unmap the PCI resource of a PCI device in virtual memory */
+void
+pci_uio_unmap_resource(struct rte_pci_device *dev)
+{
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	if (dev == NULL)
+		return;
+
+	/* find an entry for the device */
+	uio_res = pci_uio_find_resource(dev);
+	if (uio_res == NULL)
+		return;
+
+	/* secondary processes - just free maps */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return pci_uio_unmap(uio_res);
+
+	TAILQ_REMOVE(uio_res_list, uio_res, next);
+
+	/* unmap all resources */
+	pci_uio_unmap(uio_res);
+
+	/* free uio resource */
+	rte_free(uio_res);
+
+	/* close fd if in primary process */
+	close(dev->intr_handle.fd);
+	if (dev->intr_handle.uio_cfg_fd >= 0) {
+		close(dev->intr_handle.uio_cfg_fd);
+		dev->intr_handle.uio_cfg_fd = -1;
+	}
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+}
diff --git a/lib/Makefile b/lib/Makefile
index 86caba1..147be60 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-y += librte_compat
 DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
+DIRS-$(CONFIG_RTE_LIBRTE_PCI) += librte_pci
+DEPDIRS-librte_pci := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
 DEPDIRS-librte_ring := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 005019e..e5273f7 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -55,7 +55,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
@@ -69,8 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_errno.c
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
deleted file mode 100644
index 04eacdc..0000000
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ /dev/null
@@ -1,670 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-#include <limits.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/pciio.h>
-#include <dev/pci/pcireg.h>
-
-#if defined(RTE_ARCH_X86)
-#include <machine/cpufunc.h>
-#endif
-
-#include <rte_interrupts.h>
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_common.h>
-#include <rte_launch.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_eal.h>
-#include <rte_eal_memconfig.h>
-#include <rte_per_lcore.h>
-#include <rte_lcore.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-#include <rte_debug.h>
-#include <rte_devargs.h>
-
-#include "eal_filesystem.h"
-#include "eal_private.h"
-
-/**
- * @file
- * PCI probing under linux
- *
- * This code is used to simulate a PCI probe by parsing information in
- * sysfs. Moreover, when a registered driver matches a device, the
- * kernel driver currently using it is unloaded and replaced by
- * igb_uio module, which is a very minimal userland driver for Intel
- * network card, only providing access to PCI BAR to applications, and
- * enabling bus master.
- */
-
-extern struct rte_pci_bus rte_pci_bus;
-
-/* Map pci device */
-int
-rte_pci_map_device(struct rte_pci_device *dev)
-{
-	int ret = -1;
-
-	/* try mapping the NIC resources */
-	switch (dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		/* map resources for devices that use uio */
-		ret = pci_uio_map_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		ret = 1;
-		break;
-	}
-
-	return ret;
-}
-
-/* Unmap pci device */
-void
-rte_pci_unmap_device(struct rte_pci_device *dev)
-{
-	/* try unmapping the NIC resources */
-	switch (dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		/* unmap resources for devices that use uio */
-		pci_uio_unmap_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		break;
-	}
-}
-
-void
-pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res)
-{
-	rte_free(uio_res);
-
-	if (dev->intr_handle.fd) {
-		close(dev->intr_handle.fd);
-		dev->intr_handle.fd = -1;
-		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	}
-}
-
-int
-pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res)
-{
-	char devname[PATH_MAX]; /* contains the /dev/uioX */
-	struct rte_pci_addr *loc;
-
-	loc = &dev->addr;
-
-	snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
-			dev->addr.bus, dev->addr.devid, dev->addr.function);
-
-	if (access(devname, O_RDWR) < 0) {
-		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
-				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
-		return 1;
-	}
-
-	/* save fd if in primary process */
-	dev->intr_handle.fd = open(devname, O_RDWR);
-	if (dev->intr_handle.fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			devname, strerror(errno));
-		goto error;
-	}
-	dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-
-	/* allocate the mapping details for secondary processes*/
-	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
-	if (*uio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto error;
-	}
-
-	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
-	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
-
-	return 0;
-
-error:
-	pci_uio_free_resource(dev, *uio_res);
-	return -1;
-}
-
-int
-pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx)
-{
-	int fd;
-	char *devname;
-	void *mapaddr;
-	uint64_t offset;
-	uint64_t pagesz;
-	struct pci_map *maps;
-
-	maps = uio_res->maps;
-	devname = uio_res->path;
-	pagesz = sysconf(_SC_PAGESIZE);
-
-	/* allocate memory to keep path */
-	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
-	if (maps[map_idx].path == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
-				strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * open resource file, to mmap it
-	 */
-	fd = open(devname, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				devname, strerror(errno));
-		goto error;
-	}
-
-	/* if matching map is found, then use it */
-	offset = res_idx * pagesz;
-	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
-			(size_t)dev->mem_resource[res_idx].len, 0);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		goto error;
-
-	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
-	maps[map_idx].size = dev->mem_resource[res_idx].len;
-	maps[map_idx].addr = mapaddr;
-	maps[map_idx].offset = offset;
-	strcpy(maps[map_idx].path, devname);
-	dev->mem_resource[res_idx].addr = mapaddr;
-
-	return 0;
-
-error:
-	rte_free(maps[map_idx].path);
-	return -1;
-}
-
-static int
-pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
-{
-	struct rte_pci_device *dev;
-	struct pci_bar_io bar;
-	unsigned i, max;
-
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL) {
-		return -1;
-	}
-
-	memset(dev, 0, sizeof(*dev));
-	dev->addr.domain = conf->pc_sel.pc_domain;
-	dev->addr.bus = conf->pc_sel.pc_bus;
-	dev->addr.devid = conf->pc_sel.pc_dev;
-	dev->addr.function = conf->pc_sel.pc_func;
-
-	/* get vendor id */
-	dev->id.vendor_id = conf->pc_vendor;
-
-	/* get device id */
-	dev->id.device_id = conf->pc_device;
-
-	/* get subsystem_vendor id */
-	dev->id.subsystem_vendor_id = conf->pc_subvendor;
-
-	/* get subsystem_device id */
-	dev->id.subsystem_device_id = conf->pc_subdevice;
-
-	/* get class id */
-	dev->id.class_id = (conf->pc_class << 16) |
-			   (conf->pc_subclass << 8) |
-			   (conf->pc_progif);
-
-	/* TODO: get max_vfs */
-	dev->max_vfs = 0;
-
-	/* FreeBSD has no NUMA support (yet) */
-	dev->device.numa_node = 0;
-
-	pci_name_set(dev);
-
-	/* FreeBSD has only one pass through driver */
-	dev->kdrv = RTE_KDRV_NIC_UIO;
-
-	/* parse resources */
-	switch (conf->pc_hdr & PCIM_HDRTYPE) {
-	case PCIM_HDRTYPE_NORMAL:
-		max = PCIR_MAX_BAR_0;
-		break;
-	case PCIM_HDRTYPE_BRIDGE:
-		max = PCIR_MAX_BAR_1;
-		break;
-	case PCIM_HDRTYPE_CARDBUS:
-		max = PCIR_MAX_BAR_2;
-		break;
-	default:
-		goto skipdev;
-	}
-
-	for (i = 0; i <= max; i++) {
-		bar.pbi_sel = conf->pc_sel;
-		bar.pbi_reg = PCIR_BAR(i);
-		if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
-			continue;
-
-		dev->mem_resource[i].len = bar.pbi_length;
-		if (PCI_BAR_IO(bar.pbi_base)) {
-			dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
-			continue;
-		}
-		dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
-	}
-
-	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-		rte_pci_add_device(dev);
-	}
-	else {
-		struct rte_pci_device *dev2 = NULL;
-		int ret;
-
-		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
-			if (ret > 0)
-				continue;
-			else if (ret < 0) {
-				rte_pci_insert_device(dev2, dev);
-			} else { /* already registered */
-				dev2->kdrv = dev->kdrv;
-				dev2->max_vfs = dev->max_vfs;
-				pci_name_set(dev2);
-				memmove(dev2->mem_resource,
-					dev->mem_resource,
-					sizeof(dev->mem_resource));
-				free(dev);
-			}
-			return 0;
-		}
-		rte_pci_add_device(dev);
-	}
-
-	return 0;
-
-skipdev:
-	free(dev);
-	return 0;
-}
-
-/*
- * Scan the content of the PCI bus, and add the devices in the devices
- * list. Call pci_scan_one() for each pci entry found.
- */
-int
-rte_pci_scan(void)
-{
-	int fd;
-	unsigned dev_count = 0;
-	struct pci_conf matches[16];
-	struct pci_conf_io conf_io = {
-			.pat_buf_len = 0,
-			.num_patterns = 0,
-			.patterns = NULL,
-			.match_buf_len = sizeof(matches),
-			.matches = &matches[0],
-	};
-
-	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
-		return 0;
-
-	fd = open("/dev/pci", O_RDONLY);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	do {
-		unsigned i;
-		if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
-			RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
-					__func__, strerror(errno));
-			goto error;
-		}
-
-		for (i = 0; i < conf_io.num_matches; i++)
-			if (pci_scan_one(fd, &matches[i]) < 0)
-				goto error;
-
-		dev_count += conf_io.num_matches;
-	} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
-
-	close(fd);
-
-	RTE_LOG(DEBUG, EAL, "PCI scan found %u devices\n", dev_count);
-	return 0;
-
-error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-int
-pci_update_device(const struct rte_pci_addr *addr)
-{
-	int fd;
-	struct pci_conf matches[2];
-	struct pci_match_conf match = {
-		.pc_sel = {
-			.pc_domain = addr->domain,
-			.pc_bus = addr->bus,
-			.pc_dev = addr->devid,
-			.pc_func = addr->function,
-		},
-	};
-	struct pci_conf_io conf_io = {
-		.pat_buf_len = 0,
-		.num_patterns = 1,
-		.patterns = &match,
-		.match_buf_len = sizeof(matches),
-		.matches = &matches[0],
-	};
-
-	fd = open("/dev/pci", O_RDONLY);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
-				__func__, strerror(errno));
-		goto error;
-	}
-
-	if (conf_io.num_matches != 1)
-		goto error;
-
-	if (pci_scan_one(fd, &matches[0]) < 0)
-		goto error;
-
-	close(fd);
-
-	return 0;
-
-error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/* Read PCI config space. */
-int rte_pci_read_config(const struct rte_pci_device *dev,
-		void *buf, size_t len, off_t offset)
-{
-	int fd = -1;
-	int size;
-	struct pci_io pi = {
-		.pi_sel = {
-			.pc_domain = dev->addr.domain,
-			.pc_bus = dev->addr.bus,
-			.pc_dev = dev->addr.devid,
-			.pc_func = dev->addr.function,
-		},
-		.pi_reg = offset,
-	};
-
-	fd = open("/dev/pci", O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	while (len > 0) {
-		size = (len >= 4) ? 4 : ((len >= 2) ? 2 : 1);
-		pi.pi_width = size;
-
-		if (ioctl(fd, PCIOCREAD, &pi) < 0)
-			goto error;
-		memcpy(buf, &pi.pi_data, size);
-
-		buf = (char *)buf + size;
-		pi.pi_reg += size;
-		len -= size;
-	}
-	close(fd);
-
-	return 0;
-
- error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/* Write PCI config space. */
-int rte_pci_write_config(const struct rte_pci_device *dev,
-		const void *buf, size_t len, off_t offset)
-{
-	int fd = -1;
-
-	struct pci_io pi = {
-		.pi_sel = {
-			.pc_domain = dev->addr.domain,
-			.pc_bus = dev->addr.bus,
-			.pc_dev = dev->addr.devid,
-			.pc_func = dev->addr.function,
-		},
-		.pi_reg = offset,
-		.pi_data = *(const uint32_t *)buf,
-		.pi_width = len,
-	};
-
-	if (len == 3 || len > sizeof(pi.pi_data)) {
-		RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__);
-		goto error;
-	}
-
-	memcpy(&pi.pi_data, buf, len);
-
-	fd = open("/dev/pci", O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	if (ioctl(fd, PCIOCWRITE, &pi) < 0)
-		goto error;
-
-	close(fd);
-	return 0;
-
- error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-int
-rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p)
-{
-	int ret;
-
-	switch (dev->kdrv) {
-#if defined(RTE_ARCH_X86)
-	case RTE_KDRV_NIC_UIO:
-		if ((uintptr_t) dev->mem_resource[bar].addr <= UINT16_MAX) {
-			p->base = (uintptr_t)dev->mem_resource[bar].addr;
-			ret = 0;
-		} else
-			ret = -1;
-		break;
-#endif
-	default:
-		ret = -1;
-		break;
-	}
-
-	if (!ret)
-		p->dev = dev;
-
-	return ret;
-}
-
-static void
-pci_uio_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-#if defined(RTE_ARCH_X86)
-	uint8_t *d;
-	int size;
-	unsigned short reg = p->base + offset;
-
-	for (d = data; len > 0; d += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-			*(uint32_t *)d = inl(reg);
-		} else if (len >= 2) {
-			size = 2;
-			*(uint16_t *)d = inw(reg);
-		} else {
-			size = 1;
-			*d = inb(reg);
-		}
-	}
-#else
-	RTE_SET_USED(p);
-	RTE_SET_USED(data);
-	RTE_SET_USED(len);
-	RTE_SET_USED(offset);
-#endif
-}
-
-void
-rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	default:
-		break;
-	}
-}
-
-static void
-pci_uio_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-#if defined(RTE_ARCH_X86)
-	const uint8_t *s;
-	int size;
-	unsigned short reg = p->base + offset;
-
-	for (s = data; len > 0; s += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-			outl(reg, *(const uint32_t *)s);
-		} else if (len >= 2) {
-			size = 2;
-			outw(reg, *(const uint16_t *)s);
-		} else {
-			size = 1;
-			outb(reg, *s);
-		}
-	}
-#else
-	RTE_SET_USED(p);
-	RTE_SET_USED(data);
-	RTE_SET_USED(len);
-	RTE_SET_USED(offset);
-#endif
-}
-
-void
-rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	default:
-		break;
-	}
-}
-
-int
-rte_pci_ioport_unmap(struct rte_pci_ioport *p)
-{
-	int ret;
-
-	switch (p->dev->kdrv) {
-#if defined(RTE_ARCH_X86)
-	case RTE_KDRV_NIC_UIO:
-		ret = 0;
-		break;
-#endif
-	default:
-		ret = -1;
-		break;
-	}
-
-	return ret;
-}
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index e8fd67a..ac8d3bb 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h
 INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
deleted file mode 100644
index 52fd38c..0000000
--- a/lib/librte_eal/common/eal_common_pci.c
+++ /dev/null
@@ -1,580 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   Copyright 2013-2014 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-
-#include <rte_errno.h>
-#include <rte_interrupts.h>
-#include <rte_log.h>
-#include <rte_bus.h>
-#include <rte_pci.h>
-#include <rte_per_lcore.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_eal.h>
-#include <rte_string_fns.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-
-#include "eal_private.h"
-
-extern struct rte_pci_bus rte_pci_bus;
-
-#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
-
-const char *pci_get_sysfs_path(void)
-{
-	const char *path = NULL;
-
-	path = getenv("SYSFS_PCI_DEVICES");
-	if (path == NULL)
-		return SYSFS_PCI_DEVICES;
-
-	return path;
-}
-
-static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_pci_addr addr;
-	struct rte_bus *pbus;
-
-	pbus = rte_bus_find_by_name("pci");
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-		if (devargs->bus != pbus)
-			continue;
-		devargs->bus->parse(devargs->name, &addr);
-		if (!rte_eal_compare_pci_addr(&dev->addr, &addr))
-			return devargs;
-	}
-	return NULL;
-}
-
-void
-pci_name_set(struct rte_pci_device *dev)
-{
-	struct rte_devargs *devargs;
-
-	/* Each device has its internal, canonical name set. */
-	rte_pci_device_name(&dev->addr,
-			dev->name, sizeof(dev->name));
-	devargs = pci_devargs_lookup(dev);
-	dev->device.devargs = devargs;
-	/* In blacklist mode, if the device is not blacklisted, no
-	 * rte_devargs exists for it.
-	 */
-	if (devargs != NULL)
-		/* If an rte_devargs exists, the generic rte_device uses the
-		 * given name as its namea
-		 */
-		dev->device.name = dev->device.devargs->name;
-	else
-		/* Otherwise, it uses the internal, canonical form. */
-		dev->device.name = dev->name;
-}
-
-/* map a particular resource from a file */
-void *
-pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
-		 int additional_flags)
-{
-	void *mapaddr;
-
-	/* Map the PCI memory resource of device */
-	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
-			MAP_SHARED | additional_flags, fd, offset);
-	if (mapaddr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
-			__func__, fd, requested_addr,
-			(unsigned long)size, (unsigned long)offset,
-			strerror(errno), mapaddr);
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
-
-	return mapaddr;
-}
-
-/* unmap a particular resource */
-void
-pci_unmap_resource(void *requested_addr, size_t size)
-{
-	if (requested_addr == NULL)
-		return;
-
-	/* Unmap the PCI memory resource of device */
-	if (munmap(requested_addr, size)) {
-		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
-			__func__, requested_addr, (unsigned long)size,
-			strerror(errno));
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
-				requested_addr);
-}
-
-/*
- * Match the PCI Driver and Device using the ID Table
- *
- * @param pci_drv
- *	PCI driver from which ID table would be extracted
- * @param pci_dev
- *	PCI device to match against the driver
- * @return
- *	1 for successful match
- *	0 for unsuccessful match
- */
-static int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev)
-{
-	const struct rte_pci_id *id_table;
-
-	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
-	     id_table++) {
-		/* check if device's identifiers match the driver's ones */
-		if (id_table->vendor_id != pci_dev->id.vendor_id &&
-				id_table->vendor_id != PCI_ANY_ID)
-			continue;
-		if (id_table->device_id != pci_dev->id.device_id &&
-				id_table->device_id != PCI_ANY_ID)
-			continue;
-		if (id_table->subsystem_vendor_id !=
-		    pci_dev->id.subsystem_vendor_id &&
-		    id_table->subsystem_vendor_id != PCI_ANY_ID)
-			continue;
-		if (id_table->subsystem_device_id !=
-		    pci_dev->id.subsystem_device_id &&
-		    id_table->subsystem_device_id != PCI_ANY_ID)
-			continue;
-		if (id_table->class_id != pci_dev->id.class_id &&
-				id_table->class_id != RTE_CLASS_ANY_ID)
-			continue;
-
-		return 1;
-	}
-
-	return 0;
-}
-
-/*
- * If vendor/device ID match, call the probe() function of the
- * driver.
- */
-static int
-rte_pci_probe_one_driver(struct rte_pci_driver *dr,
-			 struct rte_pci_device *dev)
-{
-	int ret;
-	struct rte_pci_addr *loc;
-
-	if ((dr == NULL) || (dev == NULL))
-		return -EINVAL;
-
-	loc = &dev->addr;
-
-	/* The device is not blacklisted; Check if driver supports it */
-	if (!rte_pci_match(dr, dev))
-		/* Match of device and driver failed */
-		return 1;
-
-	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-			loc->domain, loc->bus, loc->devid, loc->function,
-			dev->device.numa_node);
-
-	/* no initialization when blacklisted, return without error */
-	if (dev->device.devargs != NULL &&
-		dev->device.devargs->policy ==
-			RTE_DEV_BLACKLISTED) {
-		RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
-			" initializing\n");
-		return 1;
-	}
-
-	if (dev->device.numa_node < 0) {
-		RTE_LOG(WARNING, EAL, "  Invalid NUMA socket, default to 0\n");
-		dev->device.numa_node = 0;
-	}
-
-	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
-		dev->id.device_id, dr->driver.name);
-
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
-		/* map resources for devices that use igb_uio */
-		ret = rte_pci_map_device(dev);
-		if (ret != 0)
-			return ret;
-	}
-
-	/* reference driver structure */
-	dev->driver = dr;
-	dev->device.driver = &dr->driver;
-
-	/* call the driver probe() function */
-	ret = dr->probe(dr, dev);
-	if (ret) {
-		dev->driver = NULL;
-		dev->device.driver = NULL;
-		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
-			/* Don't unmap if device is unsupported and
-			 * driver needs mapped resources.
-			 */
-			!(ret > 0 &&
-				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
-			rte_pci_unmap_device(dev);
-	}
-
-	return ret;
-}
-
-/*
- * If vendor/device ID match, call the remove() function of the
- * driver.
- */
-static int
-rte_pci_detach_dev(struct rte_pci_device *dev)
-{
-	struct rte_pci_addr *loc;
-	struct rte_pci_driver *dr;
-
-	if (dev == NULL)
-		return -EINVAL;
-
-	dr = dev->driver;
-	loc = &dev->addr;
-
-	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-			loc->domain, loc->bus, loc->devid,
-			loc->function, dev->device.numa_node);
-
-	RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
-			dev->id.device_id, dr->driver.name);
-
-	if (dr->remove && (dr->remove(dev) < 0))
-		return -1;	/* negative value is an error */
-
-	/* clear driver structure */
-	dev->driver = NULL;
-
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
-		/* unmap resources for devices that use igb_uio */
-		rte_pci_unmap_device(dev);
-
-	return 0;
-}
-
-/*
- * If vendor/device ID match, call the probe() function of all
- * registered driver for the given device. Return -1 if initialization
- * failed, return 1 if no driver is found for this device.
- */
-static int
-pci_probe_all_drivers(struct rte_pci_device *dev)
-{
-	struct rte_pci_driver *dr = NULL;
-	int rc = 0;
-
-	if (dev == NULL)
-		return -1;
-
-	/* Check if a driver is already loaded */
-	if (dev->driver != NULL)
-		return 0;
-
-	FOREACH_DRIVER_ON_PCIBUS(dr) {
-		rc = rte_pci_probe_one_driver(dr, dev);
-		if (rc < 0)
-			/* negative value is an error */
-			return -1;
-		if (rc > 0)
-			/* positive value means driver doesn't support it */
-			continue;
-		return 0;
-	}
-	return 1;
-}
-
-/*
- * Find the pci device specified by pci address, then invoke probe function of
- * the driver of the device.
- */
-int
-rte_pci_probe_one(const struct rte_pci_addr *addr)
-{
-	struct rte_pci_device *dev = NULL;
-
-	int ret = 0;
-
-	if (addr == NULL)
-		return -1;
-
-	/* update current pci device in global list, kernel bindings might have
-	 * changed since last time we looked at it.
-	 */
-	if (pci_update_device(addr) < 0)
-		goto err_return;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_eal_compare_pci_addr(&dev->addr, addr))
-			continue;
-
-		ret = pci_probe_all_drivers(dev);
-		if (ret)
-			goto err_return;
-		return 0;
-	}
-	return -1;
-
-err_return:
-	RTE_LOG(WARNING, EAL,
-		"Requested device " PCI_PRI_FMT " cannot be used\n",
-		addr->domain, addr->bus, addr->devid, addr->function);
-	return -1;
-}
-
-/*
- * Detach device specified by its pci address.
- */
-int
-rte_pci_detach(const struct rte_pci_addr *addr)
-{
-	struct rte_pci_device *dev = NULL;
-	int ret = 0;
-
-	if (addr == NULL)
-		return -1;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_eal_compare_pci_addr(&dev->addr, addr))
-			continue;
-
-		ret = rte_pci_detach_dev(dev);
-		if (ret < 0)
-			/* negative value is an error */
-			goto err_return;
-		if (ret > 0)
-			/* positive value means driver doesn't support it */
-			continue;
-
-		rte_pci_remove_device(dev);
-		free(dev);
-		return 0;
-	}
-	return -1;
-
-err_return:
-	RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
-			" cannot be used\n", dev->addr.domain, dev->addr.bus,
-			dev->addr.devid, dev->addr.function);
-	return -1;
-}
-
-/*
- * Scan the content of the PCI bus, and call the probe() function for
- * all registered drivers that have a matching entry in its id_table
- * for discovered devices.
- */
-int
-rte_pci_probe(void)
-{
-	struct rte_pci_device *dev = NULL;
-	size_t probed = 0, failed = 0;
-	struct rte_devargs *devargs;
-	int probe_all = 0;
-	int ret = 0;
-
-	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
-		probe_all = 1;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		probed++;
-
-		devargs = dev->device.devargs;
-		/* probe all or only whitelisted devices */
-		if (probe_all)
-			ret = pci_probe_all_drivers(dev);
-		else if (devargs != NULL &&
-			devargs->policy == RTE_DEV_WHITELISTED)
-			ret = pci_probe_all_drivers(dev);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
-				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
-				 dev->addr.devid, dev->addr.function);
-			rte_errno = errno;
-			failed++;
-			ret = 0;
-		}
-	}
-
-	return (probed && probed == failed) ? -1 : 0;
-}
-
-/* dump one device */
-static int
-pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
-{
-	int i;
-
-	fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
-	       dev->addr.devid, dev->addr.function);
-	fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
-	       dev->id.device_id);
-
-	for (i = 0; i != sizeof(dev->mem_resource) /
-		sizeof(dev->mem_resource[0]); i++) {
-		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
-			dev->mem_resource[i].phys_addr,
-			dev->mem_resource[i].len);
-	}
-	return 0;
-}
-
-/* dump devices on the bus */
-void
-rte_pci_dump(FILE *f)
-{
-	struct rte_pci_device *dev = NULL;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		pci_dump_one_device(f, dev);
-	}
-}
-
-static int
-pci_parse(const char *name, void *addr)
-{
-	struct rte_pci_addr *out = addr;
-	struct rte_pci_addr pci_addr;
-	bool parse;
-
-	parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
-		 eal_parse_pci_DomBDF(name, &pci_addr) == 0);
-	if (parse && addr != NULL)
-		*out = pci_addr;
-	return parse == false;
-}
-
-/* register a driver */
-void
-rte_pci_register(struct rte_pci_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
-	driver->bus = &rte_pci_bus;
-}
-
-/* unregister a driver */
-void
-rte_pci_unregister(struct rte_pci_driver *driver)
-{
-	TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
-	driver->bus = NULL;
-}
-
-/* Add a device to PCI bus */
-void
-rte_pci_add_device(struct rte_pci_device *pci_dev)
-{
-	TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
-}
-
-/* Insert a device into a predefined position in PCI bus */
-void
-rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
-		      struct rte_pci_device *new_pci_dev)
-{
-	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
-}
-
-/* Remove a device from PCI bus */
-void
-rte_pci_remove_device(struct rte_pci_device *pci_dev)
-{
-	TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
-}
-
-static struct rte_device *
-pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		const void *data)
-{
-	struct rte_pci_device *dev;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (start && &dev->device == start) {
-			start = NULL; /* starting point found */
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-
-	return NULL;
-}
-
-static int
-pci_plug(struct rte_device *dev)
-{
-	return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
-}
-
-static int
-pci_unplug(struct rte_device *dev)
-{
-	struct rte_pci_device *pdev;
-	int ret;
-
-	pdev = RTE_DEV_TO_PCI(dev);
-	ret = rte_pci_detach_dev(pdev);
-	rte_pci_remove_device(pdev);
-	free(pdev);
-	return ret;
-}
-
-struct rte_pci_bus rte_pci_bus = {
-	.bus = {
-		.scan = rte_pci_scan,
-		.probe = rte_pci_probe,
-		.find_device = pci_find_device,
-		.plug = pci_plug,
-		.unplug = pci_unplug,
-		.parse = pci_parse,
-	},
-	.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
-	.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
-};
-
-RTE_REGISTER_BUS(pci, rte_pci_bus.bus);
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
deleted file mode 100644
index 367a681..0000000
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include <rte_eal.h>
-#include <rte_tailq.h>
-#include <rte_log.h>
-#include <rte_malloc.h>
-
-#include "eal_private.h"
-
-static struct rte_tailq_elem rte_uio_tailq = {
-	.name = "UIO_RESOURCE_LIST",
-};
-EAL_REGISTER_TAILQ(rte_uio_tailq)
-
-static int
-pci_uio_map_secondary(struct rte_pci_device *dev)
-{
-	int fd, i, j;
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	TAILQ_FOREACH(uio_res, uio_res_list, next) {
-
-		/* skip this element if it doesn't match our PCI address */
-		if (rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
-			continue;
-
-		for (i = 0; i != uio_res->nb_maps; i++) {
-			/*
-			 * open devname, to mmap it
-			 */
-			fd = open(uio_res->maps[i].path, O_RDWR);
-			if (fd < 0) {
-				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-					uio_res->maps[i].path, strerror(errno));
-				return -1;
-			}
-
-			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
-					fd, (off_t)uio_res->maps[i].offset,
-					(size_t)uio_res->maps[i].size, 0);
-			/* fd is not needed in slave process, close it */
-			close(fd);
-			if (mapaddr != uio_res->maps[i].addr) {
-				RTE_LOG(ERR, EAL,
-					"Cannot mmap device resource file %s to address: %p\n",
-					uio_res->maps[i].path,
-					uio_res->maps[i].addr);
-				if (mapaddr != MAP_FAILED) {
-					/* unmap addrs correctly mapped */
-					for (j = 0; j < i; j++)
-						pci_unmap_resource(
-							uio_res->maps[j].addr,
-							(size_t)uio_res->maps[j].size);
-					/* unmap addr wrongly mapped */
-					pci_unmap_resource(mapaddr,
-						(size_t)uio_res->maps[i].size);
-				}
-				return -1;
-			}
-		}
-		return 0;
-	}
-
-	RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
-	return 1;
-}
-
-/* map the PCI resource of a PCI device in virtual memory */
-int
-pci_uio_map_resource(struct rte_pci_device *dev)
-{
-	int i, map_idx = 0, ret;
-	uint64_t phaddr;
-	struct mapped_pci_resource *uio_res = NULL;
-	struct mapped_pci_res_list *uio_res_list =
-		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.uio_cfg_fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* secondary processes - use already recorded details */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return pci_uio_map_secondary(dev);
-
-	/* allocate uio resource */
-	ret = pci_uio_alloc_resource(dev, &uio_res);
-	if (ret)
-		return ret;
-
-	/* Map all BARs */
-	for (i = 0; i != PCI_MAX_RESOURCE; i++) {
-		/* skip empty BAR */
-		phaddr = dev->mem_resource[i].phys_addr;
-		if (phaddr == 0)
-			continue;
-
-		ret = pci_uio_map_resource_by_index(dev, i,
-				uio_res, map_idx);
-		if (ret)
-			goto error;
-
-		map_idx++;
-	}
-
-	uio_res->nb_maps = map_idx;
-
-	TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
-
-	return 0;
-error:
-	for (i = 0; i < map_idx; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
-				(size_t)uio_res->maps[i].size);
-		rte_free(uio_res->maps[i].path);
-	}
-	pci_uio_free_resource(dev, uio_res);
-	return -1;
-}
-
-static void
-pci_uio_unmap(struct mapped_pci_resource *uio_res)
-{
-	int i;
-
-	if (uio_res == NULL)
-		return;
-
-	for (i = 0; i != uio_res->nb_maps; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
-				(size_t)uio_res->maps[i].size);
-		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-			rte_free(uio_res->maps[i].path);
-	}
-}
-
-static struct mapped_pci_resource *
-pci_uio_find_resource(struct rte_pci_device *dev)
-{
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	if (dev == NULL)
-		return NULL;
-
-	TAILQ_FOREACH(uio_res, uio_res_list, next) {
-
-		/* skip this element if it doesn't match our PCI address */
-		if (!rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
-			return uio_res;
-	}
-	return NULL;
-}
-
-/* unmap the PCI resource of a PCI device in virtual memory */
-void
-pci_uio_unmap_resource(struct rte_pci_device *dev)
-{
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	if (dev == NULL)
-		return;
-
-	/* find an entry for the device */
-	uio_res = pci_uio_find_resource(dev);
-	if (uio_res == NULL)
-		return;
-
-	/* secondary processes - just free maps */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return pci_uio_unmap(uio_res);
-
-	TAILQ_REMOVE(uio_res_list, uio_res, next);
-
-	/* unmap all resources */
-	pci_uio_unmap(uio_res);
-
-	/* free uio resource */
-	rte_free(uio_res);
-
-	/* close fd if in primary process */
-	close(dev->intr_handle.fd);
-	if (dev->intr_handle.uio_cfg_fd >= 0) {
-		close(dev->intr_handle.uio_cfg_fd);
-		dev->intr_handle.uio_cfg_fd = -1;
-	}
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-}
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
deleted file mode 100644
index 8b12339..0000000
--- a/lib/librte_eal/common/include/rte_pci.h
+++ /dev/null
@@ -1,598 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   Copyright 2013-2014 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_PCI_H_
-#define _RTE_PCI_H_
-
-/**
- * @file
- *
- * RTE PCI Interface
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <errno.h>
-#include <sys/queue.h>
-#include <stdint.h>
-#include <inttypes.h>
-
-#include <rte_debug.h>
-#include <rte_interrupts.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-
-/** Pathname of PCI devices directory. */
-const char *pci_get_sysfs_path(void);
-
-/** Formatting string for PCI device identifier: Ex: 0000:00:01.0 */
-#define PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
-#define PCI_PRI_STR_SIZE sizeof("XXXXXXXX:XX:XX.X")
-
-/** Short formatting string, without domain, for PCI device: Ex: 00:01.0 */
-#define PCI_SHORT_PRI_FMT "%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
-
-/** Nb. of values in PCI device identifier format string. */
-#define PCI_FMT_NVAL 4
-
-/** Nb. of values in PCI resource format. */
-#define PCI_RESOURCE_FMT_NVAL 3
-
-/** Maximum number of PCI resources. */
-#define PCI_MAX_RESOURCE 6
-
-/* Forward declarations */
-struct rte_pci_device;
-struct rte_pci_driver;
-
-/** List of PCI devices */
-TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
-/** List of PCI drivers */
-TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
-
-/* PCI Bus iterators */
-#define FOREACH_DEVICE_ON_PCIBUS(p)	\
-		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
-
-#define FOREACH_DRIVER_ON_PCIBUS(p)	\
-		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
-
-/**
- * A structure describing an ID for a PCI driver. Each driver provides a
- * table of these IDs for each device that it supports.
- */
-struct rte_pci_id {
-	uint32_t class_id;            /**< Class ID (class, subclass, pi) or RTE_CLASS_ANY_ID. */
-	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
-	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
-	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
-	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
-};
-
-/**
- * A structure describing the location of a PCI device.
- */
-struct rte_pci_addr {
-	uint32_t domain;                /**< Device domain */
-	uint8_t bus;                    /**< Device bus */
-	uint8_t devid;                  /**< Device ID */
-	uint8_t function;               /**< Device function. */
-};
-
-struct rte_devargs;
-
-/**
- * A structure describing a PCI device.
- */
-struct rte_pci_device {
-	TAILQ_ENTRY(rte_pci_device) next;       /**< Next probed PCI device. */
-	struct rte_device device;               /**< Inherit core device */
-	struct rte_pci_addr addr;               /**< PCI location. */
-	struct rte_pci_id id;                   /**< PCI ID. */
-	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
-						/**< PCI Memory Resource */
-	struct rte_intr_handle intr_handle;     /**< Interrupt handle */
-	struct rte_pci_driver *driver;          /**< Associated driver */
-	uint16_t max_vfs;                       /**< sriov enable if not zero */
-	enum rte_kernel_driver kdrv;            /**< Kernel driver passthrough */
-	char name[PCI_PRI_STR_SIZE+1];          /**< PCI location (ASCII) */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_pci_device.
- */
-#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
-
-/** Any PCI device identifier (vendor, device, ...) */
-#define PCI_ANY_ID (0xffff)
-#define RTE_CLASS_ANY_ID (0xffffff)
-
-#ifdef __cplusplus
-/** C++ macro used to help building up tables of device IDs */
-#define RTE_PCI_DEVICE(vend, dev) \
-	RTE_CLASS_ANY_ID,         \
-	(vend),                   \
-	(dev),                    \
-	PCI_ANY_ID,               \
-	PCI_ANY_ID
-#else
-/** Macro used to help building up tables of device IDs */
-#define RTE_PCI_DEVICE(vend, dev)          \
-	.class_id = RTE_CLASS_ANY_ID,      \
-	.vendor_id = (vend),               \
-	.device_id = (dev),                \
-	.subsystem_vendor_id = PCI_ANY_ID, \
-	.subsystem_device_id = PCI_ANY_ID
-#endif
-
-/**
- * Initialisation function for the driver called during PCI probing.
- */
-typedef int (pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
-
-/**
- * Uninitialisation function for the driver called during hotplugging.
- */
-typedef int (pci_remove_t)(struct rte_pci_device *);
-
-/**
- * A structure describing a PCI driver.
- */
-struct rte_pci_driver {
-	TAILQ_ENTRY(rte_pci_driver) next;       /**< Next in list. */
-	struct rte_driver driver;               /**< Inherit core driver. */
-	struct rte_pci_bus *bus;                /**< PCI bus reference. */
-	pci_probe_t *probe;                     /**< Device Probe function. */
-	pci_remove_t *remove;                   /**< Device Remove function. */
-	const struct rte_pci_id *id_table;	/**< ID table, NULL terminated. */
-	uint32_t drv_flags;                     /**< Flags contolling handling of device. */
-};
-
-/**
- * Structure describing the PCI bus
- */
-struct rte_pci_bus {
-	struct rte_bus bus;               /**< Inherit the generic class */
-	struct rte_pci_device_list device_list;  /**< List of PCI devices */
-	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
-};
-
-/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
-#define RTE_PCI_DRV_NEED_MAPPING 0x0001
-/** Device driver supports link state interrupt */
-#define RTE_PCI_DRV_INTR_LSC	0x0008
-/** Device driver supports device removal interrupt */
-#define RTE_PCI_DRV_INTR_RMV 0x0010
-/** Device driver needs to keep mapped resources if unsupported dev detected */
-#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
-
-/**
- * A structure describing a PCI mapping.
- */
-struct pci_map {
-	void *addr;
-	char *path;
-	uint64_t offset;
-	uint64_t size;
-	uint64_t phaddr;
-};
-
-/**
- * A structure describing a mapped PCI resource.
- * For multi-process we need to reproduce all PCI mappings in secondary
- * processes, so save them in a tailq.
- */
-struct mapped_pci_resource {
-	TAILQ_ENTRY(mapped_pci_resource) next;
-
-	struct rte_pci_addr pci_addr;
-	char path[PATH_MAX];
-	int nb_maps;
-	struct pci_map maps[PCI_MAX_RESOURCE];
-};
-
-/** mapped pci device list */
-TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
-
-/**< Internal use only - Macro used by pci addr parsing functions **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
-do {                                                               \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
-
-/**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided without
- * a domain prefix (i.e. domain returned is always 0)
- *
- * @param input
- *	The input string to be parsed. Should have the format XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned. Domain will always be
- *	returned as 0
- * @return
- *  0 on success, negative on error.
- */
-static inline int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-
-/**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided including
- * a domain prefix.
- *
- * @param input
- *	The input string to be parsed. Should have the format XXXX:XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned
- * @return
- *  0 on success, negative on error.
- */
-static inline int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-#undef GET_PCIADDR_FIELD
-
-/**
- * Utility function to write a pci device name, this device name can later be
- * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
- * BDF helpers.
- *
- * @param addr
- *	The PCI Bus-Device-Function address
- * @param output
- *	The output buffer string
- * @param size
- *	The output buffer size
- */
-static inline void
-rte_pci_device_name(const struct rte_pci_addr *addr,
-		char *output, size_t size)
-{
-	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
-	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
-			    addr->domain, addr->bus,
-			    addr->devid, addr->function) >= 0);
-}
-
-/* Compare two PCI device addresses. */
-/**
- * Utility function to compare two PCI device addresses.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to compare
- * @param addr2
- *	The PCI Bus-Device-Function address to compare
- * @return
- *	0 on equal PCI address.
- *	Positive on addr is greater than addr2.
- *	Negative on addr is less than addr2, or error.
- */
-static inline int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			 const struct rte_pci_addr *addr2)
-{
-	uint64_t dev_addr, dev_addr2;
-
-	if ((addr == NULL) || (addr2 == NULL))
-		return -1;
-
-	dev_addr = ((uint64_t)addr->domain << 24) |
-		(addr->bus << 16) | (addr->devid << 8) | addr->function;
-	dev_addr2 = ((uint64_t)addr2->domain << 24) |
-		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
-
-	if (dev_addr > dev_addr2)
-		return 1;
-	else if (dev_addr < dev_addr2)
-		return -1;
-	else
-		return 0;
-}
-
-/**
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- *
- * @return
- *  0 on success, negative on error
- */
-int rte_pci_scan(void);
-
-/**
- * Probe the PCI bus
- *
- * @return
- *   - 0 on success.
- *   - !0 on error.
- */
-int
-rte_pci_probe(void);
-
-/**
- * Map the PCI device resources in user space virtual memory address
- *
- * Note that driver should not call this function when flag
- * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for
- * you when it's on.
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- *
- * @return
- *   0 on success, negative on error and positive if no driver
- *   is found for the device.
- */
-int rte_pci_map_device(struct rte_pci_device *dev);
-
-/**
- * Unmap this device
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- */
-void rte_pci_unmap_device(struct rte_pci_device *dev);
-
-/**
- * @internal
- * Map a particular resource from a file.
- *
- * @param requested_addr
- *      The starting address for the new mapping range.
- * @param fd
- *      The file descriptor.
- * @param offset
- *      The offset for the mapping range.
- * @param size
- *      The size for the mapping range.
- * @param additional_flags
- *      The additional flags for the mapping range.
- * @return
- *   - On success, the function returns a pointer to the mapped area.
- *   - On error, the value MAP_FAILED is returned.
- */
-void *pci_map_resource(void *requested_addr, int fd, off_t offset,
-		size_t size, int additional_flags);
-
-/**
- * @internal
- * Unmap a particular resource.
- *
- * @param requested_addr
- *      The address for the unmapping range.
- * @param size
- *      The size for the unmapping range.
- */
-void pci_unmap_resource(void *requested_addr, size_t size);
-
-/**
- * Probe the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the probe() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to probe.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_probe_one(const struct rte_pci_addr *addr);
-
-/**
- * Close the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the remove() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to close.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_detach(const struct rte_pci_addr *addr);
-
-/**
- * Dump the content of the PCI bus.
- *
- * @param f
- *   A pointer to a file for output
- */
-void rte_pci_dump(FILE *f);
-
-/**
- * Register a PCI driver.
- *
- * @param driver
- *   A pointer to a rte_pci_driver structure describing the driver
- *   to be registered.
- */
-void rte_pci_register(struct rte_pci_driver *driver);
-
-/** Helper for PCI device registration from driver (eth, crypto) instance */
-#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
-RTE_INIT(pciinitfn_ ##nm); \
-static void pciinitfn_ ##nm(void) \
-{\
-	(pci_drv).driver.name = RTE_STR(nm);\
-	rte_pci_register(&pci_drv); \
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-/**
- * Unregister a PCI driver.
- *
- * @param driver
- *   A pointer to a rte_pci_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_pci_unregister(struct rte_pci_driver *driver);
-
-/**
- * Read PCI config space.
- *
- * @param device
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- * @param buf
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into PCI config space
- */
-int rte_pci_read_config(const struct rte_pci_device *device,
-		void *buf, size_t len, off_t offset);
-
-/**
- * Write PCI config space.
- *
- * @param device
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- * @param buf
- *   A data buffer containing the bytes should be written
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into PCI config space
- */
-int rte_pci_write_config(const struct rte_pci_device *device,
-		const void *buf, size_t len, off_t offset);
-
-/**
- * A structure used to access io resources for a pci device.
- * rte_pci_ioport is arch, os, driver specific, and should not be used outside
- * of pci ioport api.
- */
-struct rte_pci_ioport {
-	struct rte_pci_device *dev;
-	uint64_t base;
-	uint64_t len; /* only filled for memory mapped ports */
-};
-
-/**
- * Initialize a rte_pci_ioport object for a pci device io resource.
- *
- * This object is then used to gain access to those io resources (see below).
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use.
- * @param bar
- *   Index of the io pci resource we want to access.
- * @param p
- *   The rte_pci_ioport object to be initialized.
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p);
-
-/**
- * Release any resources used in a rte_pci_ioport object.
- *
- * @param p
- *   The rte_pci_ioport object to be uninitialized.
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_ioport_unmap(struct rte_pci_ioport *p);
-
-/**
- * Read from a io pci resource.
- *
- * @param p
- *   The rte_pci_ioport object from which we want to read.
- * @param data
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into the pci io resource.
- */
-void rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset);
-
-/**
- * Write to a io pci resource.
- *
- * @param p
- *   The rte_pci_ioport object to which we want to write.
- * @param data
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into the pci io resource.
- */
-void rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RTE_PCI_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index ad7e34a..e24c103 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -64,10 +64,6 @@ endif
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
@@ -81,8 +77,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_errno.c
@@ -109,16 +103,12 @@ CFLAGS_eal_common_cpuflags.o := $(CPUFLAGS_LIST)
 
 CFLAGS_eal.o := -D_GNU_SOURCE
 CFLAGS_eal_interrupts.o := -D_GNU_SOURCE
-CFLAGS_eal_vfio_mp_sync.o := -D_GNU_SOURCE
 CFLAGS_eal_timer.o := -D_GNU_SOURCE
 CFLAGS_eal_lcore.o := -D_GNU_SOURCE
 CFLAGS_eal_thread.o := -D_GNU_SOURCE
 CFLAGS_eal_log.o := -D_GNU_SOURCE
 CFLAGS_eal_common_log.o := -D_GNU_SOURCE
 CFLAGS_eal_hugepage_info.o := -D_GNU_SOURCE
-CFLAGS_eal_pci.o := -D_GNU_SOURCE
-CFLAGS_eal_pci_uio.o := -D_GNU_SOURCE
-CFLAGS_eal_pci_vfio.o := -D_GNU_SOURCE
 CFLAGS_eal_common_whitelist.o := -D_GNU_SOURCE
 CFLAGS_eal_common_options.o := -D_GNU_SOURCE
 CFLAGS_eal_common_thread.o := -D_GNU_SOURCE
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
deleted file mode 100644
index 8f658d6..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ /dev/null
@@ -1,723 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <dirent.h>
-
-#include <rte_log.h>
-#include <rte_bus.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-#include <rte_devargs.h>
-#include <rte_memcpy.h>
-
-#include "eal_filesystem.h"
-#include "eal_private.h"
-#include "eal_pci_init.h"
-#include "rte_memory_linux.h"
-
-/**
- * @file
- * PCI probing under linux
- *
- * This code is used to simulate a PCI probe by parsing information in sysfs.
- * When a registered device matches a driver, it is then initialized with
- * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
- */
-
-extern struct rte_pci_bus rte_pci_bus;
-
-static int
-pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
-{
-	int count;
-	char path[PATH_MAX];
-	char *name;
-
-	if (!filename || !dri_name)
-		return -1;
-
-	count = readlink(filename, path, PATH_MAX);
-	if (count >= PATH_MAX)
-		return -1;
-
-	/* For device does not have a driver */
-	if (count < 0)
-		return 1;
-
-	path[count] = '\0';
-
-	name = strrchr(path, '/');
-	if (name) {
-		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
-		return 0;
-	}
-
-	return -1;
-}
-
-/* Map pci device */
-int
-rte_pci_map_device(struct rte_pci_device *dev)
-{
-	int ret = -1;
-
-	/* try mapping the NIC resources using VFIO if it exists */
-	switch (dev->kdrv) {
-	case RTE_KDRV_VFIO:
-#ifdef VFIO_PRESENT
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_map_resource(dev);
-#endif
-		break;
-	case RTE_KDRV_IGB_UIO:
-	case RTE_KDRV_UIO_GENERIC:
-		if (rte_eal_using_phys_addrs()) {
-			/* map resources for devices that use uio */
-			ret = pci_uio_map_resource(dev);
-		}
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		ret = 1;
-		break;
-	}
-
-	return ret;
-}
-
-/* Unmap pci device */
-void
-rte_pci_unmap_device(struct rte_pci_device *dev)
-{
-	/* try unmapping the NIC resources using VFIO if it exists */
-	switch (dev->kdrv) {
-	case RTE_KDRV_VFIO:
-#ifdef VFIO_PRESENT
-		if (pci_vfio_is_enabled())
-			pci_vfio_unmap_resource(dev);
-#endif
-		break;
-	case RTE_KDRV_IGB_UIO:
-	case RTE_KDRV_UIO_GENERIC:
-		/* unmap resources for devices that use uio */
-		pci_uio_unmap_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		break;
-	}
-}
-
-void *
-pci_find_max_end_va(void)
-{
-	const struct rte_memseg *seg = rte_eal_get_physmem_layout();
-	const struct rte_memseg *last = seg;
-	unsigned i = 0;
-
-	for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
-		if (seg->addr == NULL)
-			break;
-
-		if (seg->addr > last->addr)
-			last = seg;
-
-	}
-	return RTE_PTR_ADD(last->addr, last->len);
-}
-
-/* parse one line of the "resource" sysfs file (note that the 'line'
- * string is modified)
- */
-int
-pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
-	uint64_t *end_addr, uint64_t *flags)
-{
-	union pci_resource_info {
-		struct {
-			char *phys_addr;
-			char *end_addr;
-			char *flags;
-		};
-		char *ptrs[PCI_RESOURCE_FMT_NVAL];
-	} res_info;
-
-	if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
-		RTE_LOG(ERR, EAL,
-			"%s(): bad resource format\n", __func__);
-		return -1;
-	}
-	errno = 0;
-	*phys_addr = strtoull(res_info.phys_addr, NULL, 16);
-	*end_addr = strtoull(res_info.end_addr, NULL, 16);
-	*flags = strtoull(res_info.flags, NULL, 16);
-	if (errno != 0) {
-		RTE_LOG(ERR, EAL,
-			"%s(): bad resource format\n", __func__);
-		return -1;
-	}
-
-	return 0;
-}
-
-/* parse the "resource" sysfs file */
-static int
-pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
-{
-	FILE *f;
-	char buf[BUFSIZ];
-	int i;
-	uint64_t phys_addr, end_addr, flags;
-
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
-		return -1;
-	}
-
-	for (i = 0; i<PCI_MAX_RESOURCE; i++) {
-
-		if (fgets(buf, sizeof(buf), f) == NULL) {
-			RTE_LOG(ERR, EAL,
-				"%s(): cannot read resource\n", __func__);
-			goto error;
-		}
-		if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
-				&end_addr, &flags) < 0)
-			goto error;
-
-		if (flags & IORESOURCE_MEM) {
-			dev->mem_resource[i].phys_addr = phys_addr;
-			dev->mem_resource[i].len = end_addr - phys_addr + 1;
-			/* not mapped for now */
-			dev->mem_resource[i].addr = NULL;
-		}
-	}
-	fclose(f);
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
-}
-
-/* Scan one pci sysfs entry, and fill the devices list from it. */
-static int
-pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
-{
-	char filename[PATH_MAX];
-	unsigned long tmp;
-	struct rte_pci_device *dev;
-	char driver[PATH_MAX];
-	int ret;
-
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL)
-		return -1;
-
-	memset(dev, 0, sizeof(*dev));
-	dev->addr = *addr;
-
-	/* get vendor id */
-	snprintf(filename, sizeof(filename), "%s/vendor", dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.vendor_id = (uint16_t)tmp;
-
-	/* get device id */
-	snprintf(filename, sizeof(filename), "%s/device", dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.device_id = (uint16_t)tmp;
-
-	/* get subsystem_vendor id */
-	snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.subsystem_vendor_id = (uint16_t)tmp;
-
-	/* get subsystem_device id */
-	snprintf(filename, sizeof(filename), "%s/subsystem_device",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.subsystem_device_id = (uint16_t)tmp;
-
-	/* get class_id */
-	snprintf(filename, sizeof(filename), "%s/class",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	/* the least 24 bits are valid: class, subclass, program interface */
-	dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
-
-	/* get max_vfs */
-	dev->max_vfs = 0;
-	snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
-	if (!access(filename, F_OK) &&
-	    eal_parse_sysfs_value(filename, &tmp) == 0)
-		dev->max_vfs = (uint16_t)tmp;
-	else {
-		/* for non igb_uio driver, need kernel version >= 3.8 */
-		snprintf(filename, sizeof(filename),
-			 "%s/sriov_numvfs", dirname);
-		if (!access(filename, F_OK) &&
-		    eal_parse_sysfs_value(filename, &tmp) == 0)
-			dev->max_vfs = (uint16_t)tmp;
-	}
-
-	/* get numa node, default to 0 if not present */
-	snprintf(filename, sizeof(filename), "%s/numa_node",
-		 dirname);
-
-	if (access(filename, F_OK) != -1) {
-		if (eal_parse_sysfs_value(filename, &tmp) == 0)
-			dev->device.numa_node = tmp;
-		else
-			dev->device.numa_node = -1;
-	} else {
-		dev->device.numa_node = 0;
-	}
-
-	pci_name_set(dev);
-
-	/* parse resources */
-	snprintf(filename, sizeof(filename), "%s/resource", dirname);
-	if (pci_parse_sysfs_resource(filename, dev) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
-		free(dev);
-		return -1;
-	}
-
-	/* parse driver */
-	snprintf(filename, sizeof(filename), "%s/driver", dirname);
-	ret = pci_get_kernel_driver_by_path(filename, driver);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
-		free(dev);
-		return -1;
-	}
-
-	if (!ret) {
-		if (!strcmp(driver, "vfio-pci"))
-			dev->kdrv = RTE_KDRV_VFIO;
-		else if (!strcmp(driver, "igb_uio"))
-			dev->kdrv = RTE_KDRV_IGB_UIO;
-		else if (!strcmp(driver, "uio_pci_generic"))
-			dev->kdrv = RTE_KDRV_UIO_GENERIC;
-		else
-			dev->kdrv = RTE_KDRV_UNKNOWN;
-	} else
-		dev->kdrv = RTE_KDRV_NONE;
-
-	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-		rte_pci_add_device(dev);
-	} else {
-		struct rte_pci_device *dev2;
-		int ret;
-
-		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
-			if (ret > 0)
-				continue;
-
-			if (ret < 0) {
-				rte_pci_insert_device(dev2, dev);
-			} else { /* already registered */
-				dev2->kdrv = dev->kdrv;
-				dev2->max_vfs = dev->max_vfs;
-				pci_name_set(dev2);
-				memmove(dev2->mem_resource, dev->mem_resource,
-					sizeof(dev->mem_resource));
-				free(dev);
-			}
-			return 0;
-		}
-
-		rte_pci_add_device(dev);
-	}
-
-	return 0;
-}
-
-int
-pci_update_device(const struct rte_pci_addr *addr)
-{
-	char filename[PATH_MAX];
-
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
-		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
-		 addr->function);
-
-	return pci_scan_one(filename, addr);
-}
-
-/*
- * split up a pci address into its constituent parts.
- */
-static int
-parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
-{
-	/* first split on ':' */
-	union splitaddr {
-		struct {
-			char *domain;
-			char *bus;
-			char *devid;
-			char *function;
-		};
-		char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
-	} splitaddr;
-
-	char *buf_copy = strndup(buf, bufsize);
-	if (buf_copy == NULL)
-		return -1;
-
-	if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
-			!= PCI_FMT_NVAL - 1)
-		goto error;
-	/* final split is on '.' between devid and function */
-	splitaddr.function = strchr(splitaddr.devid,'.');
-	if (splitaddr.function == NULL)
-		goto error;
-	*splitaddr.function++ = '\0';
-
-	/* now convert to int values */
-	errno = 0;
-	addr->domain = strtoul(splitaddr.domain, NULL, 16);
-	addr->bus = strtoul(splitaddr.bus, NULL, 16);
-	addr->devid = strtoul(splitaddr.devid, NULL, 16);
-	addr->function = strtoul(splitaddr.function, NULL, 10);
-	if (errno != 0)
-		goto error;
-
-	free(buf_copy); /* free the copy made with strdup */
-	return 0;
-error:
-	free(buf_copy);
-	return -1;
-}
-
-/*
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- */
-int
-rte_pci_scan(void)
-{
-	struct dirent *e;
-	DIR *dir;
-	char dirname[PATH_MAX];
-	struct rte_pci_addr addr;
-
-	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
-		return 0;
-
-	dir = opendir(pci_get_sysfs_path());
-	if (dir == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
-			__func__, strerror(errno));
-		return -1;
-	}
-
-	while ((e = readdir(dir)) != NULL) {
-		if (e->d_name[0] == '.')
-			continue;
-
-		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
-			continue;
-
-		snprintf(dirname, sizeof(dirname), "%s/%s",
-				pci_get_sysfs_path(), e->d_name);
-
-		if (pci_scan_one(dirname, &addr) < 0)
-			goto error;
-	}
-	closedir(dir);
-	return 0;
-
-error:
-	closedir(dir);
-	return -1;
-}
-
-/* Read PCI config space. */
-int rte_pci_read_config(const struct rte_pci_device *device,
-		void *buf, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &device->intr_handle;
-
-	switch (intr_handle->type) {
-	case RTE_INTR_HANDLE_UIO:
-	case RTE_INTR_HANDLE_UIO_INTX:
-		return pci_uio_read_config(intr_handle, buf, len, offset);
-
-#ifdef VFIO_PRESENT
-	case RTE_INTR_HANDLE_VFIO_MSIX:
-	case RTE_INTR_HANDLE_VFIO_MSI:
-	case RTE_INTR_HANDLE_VFIO_LEGACY:
-		return pci_vfio_read_config(intr_handle, buf, len, offset);
-#endif
-	default:
-		RTE_LOG(ERR, EAL,
-			"Unknown handle type of fd %d\n",
-					intr_handle->fd);
-		return -1;
-	}
-}
-
-/* Write PCI config space. */
-int rte_pci_write_config(const struct rte_pci_device *device,
-		const void *buf, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &device->intr_handle;
-
-	switch (intr_handle->type) {
-	case RTE_INTR_HANDLE_UIO:
-	case RTE_INTR_HANDLE_UIO_INTX:
-		return pci_uio_write_config(intr_handle, buf, len, offset);
-
-#ifdef VFIO_PRESENT
-	case RTE_INTR_HANDLE_VFIO_MSIX:
-	case RTE_INTR_HANDLE_VFIO_MSI:
-	case RTE_INTR_HANDLE_VFIO_LEGACY:
-		return pci_vfio_write_config(intr_handle, buf, len, offset);
-#endif
-	default:
-		RTE_LOG(ERR, EAL,
-			"Unknown handle type of fd %d\n",
-					intr_handle->fd);
-		return -1;
-	}
-}
-
-#if defined(RTE_ARCH_X86)
-static int
-pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
-		struct rte_pci_ioport *p)
-{
-	uint16_t start, end;
-	FILE *fp;
-	char *line = NULL;
-	char pci_id[16];
-	int found = 0;
-	size_t linesz;
-
-	snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
-		 dev->addr.domain, dev->addr.bus,
-		 dev->addr.devid, dev->addr.function);
-
-	fp = fopen("/proc/ioports", "r");
-	if (fp == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);
-		return -1;
-	}
-
-	while (getdelim(&line, &linesz, '\n', fp) > 0) {
-		char *ptr = line;
-		char *left;
-		int n;
-
-		n = strcspn(ptr, ":");
-		ptr[n] = 0;
-		left = &ptr[n + 1];
-
-		while (*left && isspace(*left))
-			left++;
-
-		if (!strncmp(left, pci_id, strlen(pci_id))) {
-			found = 1;
-
-			while (*ptr && isspace(*ptr))
-				ptr++;
-
-			sscanf(ptr, "%04hx-%04hx", &start, &end);
-
-			break;
-		}
-	}
-
-	free(line);
-	fclose(fp);
-
-	if (!found)
-		return -1;
-
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	p->base = start;
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
-
-	return 0;
-}
-#endif
-
-int
-rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p)
-{
-	int ret = -1;
-
-	switch (dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_ioport_map(dev, bar, p);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		ret = pci_uio_ioport_map(dev, bar, p);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-#if defined(RTE_ARCH_X86)
-		ret = pci_ioport_map(dev, bar, p);
-#else
-		ret = pci_uio_ioport_map(dev, bar, p);
-#endif
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		ret = pci_ioport_map(dev, bar, p);
-#endif
-		break;
-	default:
-		break;
-	}
-
-	if (!ret)
-		p->dev = dev;
-
-	return ret;
-}
-
-void
-rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		pci_vfio_ioport_read(p, data, len, offset);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		pci_uio_ioport_read(p, data, len, offset);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-void
-rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		pci_vfio_ioport_write(p, data, len, offset);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		pci_uio_ioport_write(p, data, len, offset);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-int
-rte_pci_ioport_unmap(struct rte_pci_ioport *p)
-{
-	int ret = -1;
-
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_ioport_unmap(p);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		ret = pci_uio_ioport_unmap(p);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-#if defined(RTE_ARCH_X86)
-		ret = 0;
-#else
-		ret = pci_uio_ioport_unmap(p);
-#endif
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		ret = 0;
-#endif
-		break;
-	default:
-		break;
-	}
-
-	return ret;
-}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
deleted file mode 100644
index ae2980d..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_init.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef EAL_PCI_INIT_H_
-#define EAL_PCI_INIT_H_
-
-#include "eal_vfio.h"
-
-/** IO resource type: */
-#define IORESOURCE_IO         0x00000100
-#define IORESOURCE_MEM        0x00000200
-
-/*
- * Helper function to map PCI resources right after hugepages in virtual memory
- */
-extern void *pci_map_addr;
-void *pci_find_max_end_va(void);
-
-/* parse one line of the "resource" sysfs file (note that the 'line'
- * string is modified)
- */
-int pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
-	uint64_t *end_addr, uint64_t *flags);
-
-int pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res);
-void pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res);
-int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx);
-
-int pci_uio_read_config(const struct rte_intr_handle *intr_handle,
-			void *buf, size_t len, off_t offs);
-int pci_uio_write_config(const struct rte_intr_handle *intr_handle,
-			 const void *buf, size_t len, off_t offs);
-
-int pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		       struct rte_pci_ioport *p);
-void pci_uio_ioport_read(struct rte_pci_ioport *p,
-			 void *data, size_t len, off_t offset);
-void pci_uio_ioport_write(struct rte_pci_ioport *p,
-			  const void *data, size_t len, off_t offset);
-int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
-
-#ifdef VFIO_PRESENT
-
-/* access config space */
-int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
-			 void *buf, size_t len, off_t offs);
-int pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
-			  const void *buf, size_t len, off_t offs);
-
-int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
-		        struct rte_pci_ioport *p);
-void pci_vfio_ioport_read(struct rte_pci_ioport *p,
-			  void *data, size_t len, off_t offset);
-void pci_vfio_ioport_write(struct rte_pci_ioport *p,
-			   const void *data, size_t len, off_t offset);
-int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
-
-/* map/unmap VFIO resource prototype */
-int pci_vfio_map_resource(struct rte_pci_device *dev);
-int pci_vfio_unmap_resource(struct rte_pci_device *dev);
-
-#endif
-
-#endif /* EAL_PCI_INIT_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
deleted file mode 100644
index fa10329..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/sysmacros.h>
-#include <linux/pci_regs.h>
-
-#if defined(RTE_ARCH_X86)
-#include <sys/io.h>
-#endif
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-
-void *pci_map_addr = NULL;
-
-#define OFF_MAX              ((uint64_t)(off_t)-1)
-
-int
-pci_uio_read_config(const struct rte_intr_handle *intr_handle,
-		    void *buf, size_t len, off_t offset)
-{
-	return pread(intr_handle->uio_cfg_fd, buf, len, offset);
-}
-
-int
-pci_uio_write_config(const struct rte_intr_handle *intr_handle,
-		     const void *buf, size_t len, off_t offset)
-{
-	return pwrite(intr_handle->uio_cfg_fd, buf, len, offset);
-}
-
-static int
-pci_uio_set_bus_master(int dev_fd)
-{
-	uint16_t reg;
-	int ret;
-
-	ret = pread(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL,
-			"Cannot read command from PCI config space!\n");
-		return -1;
-	}
-
-	/* return if bus mastering is already on */
-	if (reg & PCI_COMMAND_MASTER)
-		return 0;
-
-	reg |= PCI_COMMAND_MASTER;
-
-	ret = pwrite(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL,
-			"Cannot write command to PCI config space!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-static int
-pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
-{
-	FILE *f;
-	char filename[PATH_MAX];
-	int ret;
-	unsigned major, minor;
-	dev_t dev;
-
-	/* get the name of the sysfs file that contains the major and minor
-	 * of the uio device and read its content */
-	snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path);
-
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n",
-			__func__);
-		return -1;
-	}
-
-	ret = fscanf(f, "%u:%u", &major, &minor);
-	if (ret != 2) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n",
-			__func__);
-		fclose(f);
-		return -1;
-	}
-	fclose(f);
-
-	/* create the char device "mknod /dev/uioX c major minor" */
-	snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
-	dev = makedev(major, minor);
-	ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
-	if (ret != 0) {
-		RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
-			__func__, strerror(errno));
-		return -1;
-	}
-
-	return ret;
-}
-
-/*
- * Return the uioX char device used for a pci device. On success, return
- * the UIO number and fill dstbuf string with the path of the device in
- * sysfs. On error, return a negative value. In this case dstbuf is
- * invalid.
- */
-static int
-pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
-			   unsigned int buflen, int create)
-{
-	struct rte_pci_addr *loc = &dev->addr;
-	unsigned int uio_num;
-	struct dirent *e;
-	DIR *dir;
-	char dirname[PATH_MAX];
-
-	/* depending on kernel version, uio can be located in uio/uioX
-	 * or uio:uioX */
-
-	snprintf(dirname, sizeof(dirname),
-			"%s/" PCI_PRI_FMT "/uio", pci_get_sysfs_path(),
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	dir = opendir(dirname);
-	if (dir == NULL) {
-		/* retry with the parent directory */
-		snprintf(dirname, sizeof(dirname),
-				"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
-				loc->domain, loc->bus, loc->devid, loc->function);
-		dir = opendir(dirname);
-
-		if (dir == NULL) {
-			RTE_LOG(ERR, EAL, "Cannot opendir %s\n", dirname);
-			return -1;
-		}
-	}
-
-	/* take the first file starting with "uio" */
-	while ((e = readdir(dir)) != NULL) {
-		/* format could be uio%d ...*/
-		int shortprefix_len = sizeof("uio") - 1;
-		/* ... or uio:uio%d */
-		int longprefix_len = sizeof("uio:uio") - 1;
-		char *endptr;
-
-		if (strncmp(e->d_name, "uio", 3) != 0)
-			continue;
-
-		/* first try uio%d */
-		errno = 0;
-		uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
-		if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
-			snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
-			break;
-		}
-
-		/* then try uio:uio%d */
-		errno = 0;
-		uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
-		if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
-			snprintf(dstbuf, buflen, "%s/uio:uio%u", dirname, uio_num);
-			break;
-		}
-	}
-	closedir(dir);
-
-	/* No uio resource found */
-	if (e == NULL)
-		return -1;
-
-	/* create uio device if we've been asked to */
-	if (internal_config.create_uio_dev && create &&
-			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
-		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
-
-	return uio_num;
-}
-
-void
-pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res)
-{
-	rte_free(uio_res);
-
-	if (dev->intr_handle.uio_cfg_fd >= 0) {
-		close(dev->intr_handle.uio_cfg_fd);
-		dev->intr_handle.uio_cfg_fd = -1;
-	}
-	if (dev->intr_handle.fd >= 0) {
-		close(dev->intr_handle.fd);
-		dev->intr_handle.fd = -1;
-		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	}
-}
-
-int
-pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res)
-{
-	char dirname[PATH_MAX];
-	char cfgname[PATH_MAX];
-	char devname[PATH_MAX]; /* contains the /dev/uioX */
-	int uio_num;
-	struct rte_pci_addr *loc;
-
-	loc = &dev->addr;
-
-	/* find uio resource */
-	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 1);
-	if (uio_num < 0) {
-		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
-				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
-		return 1;
-	}
-	snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
-
-	/* save fd if in primary process */
-	dev->intr_handle.fd = open(devname, O_RDWR);
-	if (dev->intr_handle.fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			devname, strerror(errno));
-		goto error;
-	}
-
-	snprintf(cfgname, sizeof(cfgname),
-			"/sys/class/uio/uio%u/device/config", uio_num);
-	dev->intr_handle.uio_cfg_fd = open(cfgname, O_RDWR);
-	if (dev->intr_handle.uio_cfg_fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			cfgname, strerror(errno));
-		goto error;
-	}
-
-	if (dev->kdrv == RTE_KDRV_IGB_UIO)
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-	else {
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
-
-		/* set bus master that is not done by uio_pci_generic */
-		if (pci_uio_set_bus_master(dev->intr_handle.uio_cfg_fd)) {
-			RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
-			goto error;
-		}
-	}
-
-	/* allocate the mapping details for secondary processes*/
-	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
-	if (*uio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto error;
-	}
-
-	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
-	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
-
-	return 0;
-
-error:
-	pci_uio_free_resource(dev, *uio_res);
-	return -1;
-}
-
-int
-pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx)
-{
-	int fd;
-	char devname[PATH_MAX];
-	void *mapaddr;
-	struct rte_pci_addr *loc;
-	struct pci_map *maps;
-
-	loc = &dev->addr;
-	maps = uio_res->maps;
-
-	/* update devname for mmap  */
-	snprintf(devname, sizeof(devname),
-			"%s/" PCI_PRI_FMT "/resource%d",
-			pci_get_sysfs_path(),
-			loc->domain, loc->bus, loc->devid,
-			loc->function, res_idx);
-
-	/* allocate memory to keep path */
-	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
-	if (maps[map_idx].path == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
-				strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * open resource file, to mmap it
-	 */
-	fd = open(devname, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				devname, strerror(errno));
-		goto error;
-	}
-
-	/* try mapping somewhere close to the end of hugepages */
-	if (pci_map_addr == NULL)
-		pci_map_addr = pci_find_max_end_va();
-
-	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
-			(size_t)dev->mem_resource[res_idx].len, 0);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		goto error;
-
-	pci_map_addr = RTE_PTR_ADD(mapaddr,
-			(size_t)dev->mem_resource[res_idx].len);
-
-	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
-	maps[map_idx].size = dev->mem_resource[res_idx].len;
-	maps[map_idx].addr = mapaddr;
-	maps[map_idx].offset = 0;
-	strcpy(maps[map_idx].path, devname);
-	dev->mem_resource[res_idx].addr = mapaddr;
-
-	return 0;
-
-error:
-	rte_free(maps[map_idx].path);
-	return -1;
-}
-
-#if defined(RTE_ARCH_X86)
-int
-pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		   struct rte_pci_ioport *p)
-{
-	char dirname[PATH_MAX];
-	char filename[PATH_MAX];
-	int uio_num;
-	unsigned long start;
-
-	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 0);
-	if (uio_num < 0)
-		return -1;
-
-	/* get portio start */
-	snprintf(filename, sizeof(filename),
-		 "%s/portio/port%d/start", dirname, bar);
-	if (eal_parse_sysfs_value(filename, &start) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
-			__func__);
-		return -1;
-	}
-	/* ensure we don't get anything funny here, read/write will cast to
-	 * uin16_t */
-	if (start > UINT16_MAX)
-		return -1;
-
-	/* FIXME only for primary process ? */
-	if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {
-
-		snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
-		dev->intr_handle.fd = open(filename, O_RDWR);
-		if (dev->intr_handle.fd < 0) {
-			RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				filename, strerror(errno));
-			return -1;
-		}
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-	}
-
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);
-
-	p->base = start;
-	p->len = 0;
-	return 0;
-}
-#else
-int
-pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		   struct rte_pci_ioport *p)
-{
-	FILE *f;
-	char buf[BUFSIZ];
-	char filename[PATH_MAX];
-	uint64_t phys_addr, end_addr, flags;
-	int fd, i;
-	void *addr;
-
-	/* open and read addresses of the corresponding resource in sysfs */
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
-		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
-		dev->addr.devid, dev->addr.function);
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",
-			strerror(errno));
-		return -1;
-	}
-	for (i = 0; i < bar + 1; i++) {
-		if (fgets(buf, sizeof(buf), f) == NULL) {
-			RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");
-			goto error;
-		}
-	}
-	if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
-			&end_addr, &flags) < 0)
-		goto error;
-	if ((flags & IORESOURCE_IO) == 0) {
-		RTE_LOG(ERR, EAL, "BAR %d is not an IO resource\n", bar);
-		goto error;
-	}
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
-		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
-		dev->addr.devid, dev->addr.function, bar);
-
-	/* mmap the pci resource */
-	fd = open(filename, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
-			strerror(errno));
-		goto error;
-	}
-	addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
-		MAP_SHARED, fd, 0);
-	close(fd);
-	if (addr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s\n",
-			strerror(errno));
-		goto error;
-	}
-
-	/* strangely, the base address is mmap addr + phys_addr */
-	p->base = (uintptr_t)addr + phys_addr;
-	p->len = end_addr + 1;
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"\n", p->base);
-	fclose(f);
-
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
-}
-#endif
-
-void
-pci_uio_ioport_read(struct rte_pci_ioport *p,
-		    void *data, size_t len, off_t offset)
-{
-	uint8_t *d;
-	int size;
-	uintptr_t reg = p->base + offset;
-
-	for (d = data; len > 0; d += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-#if defined(RTE_ARCH_X86)
-			*(uint32_t *)d = inl(reg);
-#else
-			*(uint32_t *)d = *(volatile uint32_t *)reg;
-#endif
-		} else if (len >= 2) {
-			size = 2;
-#if defined(RTE_ARCH_X86)
-			*(uint16_t *)d = inw(reg);
-#else
-			*(uint16_t *)d = *(volatile uint16_t *)reg;
-#endif
-		} else {
-			size = 1;
-#if defined(RTE_ARCH_X86)
-			*d = inb(reg);
-#else
-			*d = *(volatile uint8_t *)reg;
-#endif
-		}
-	}
-}
-
-void
-pci_uio_ioport_write(struct rte_pci_ioport *p,
-		     const void *data, size_t len, off_t offset)
-{
-	const uint8_t *s;
-	int size;
-	uintptr_t reg = p->base + offset;
-
-	for (s = data; len > 0; s += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-#if defined(RTE_ARCH_X86)
-			outl_p(*(const uint32_t *)s, reg);
-#else
-			*(volatile uint32_t *)reg = *(const uint32_t *)s;
-#endif
-		} else if (len >= 2) {
-			size = 2;
-#if defined(RTE_ARCH_X86)
-			outw_p(*(const uint16_t *)s, reg);
-#else
-			*(volatile uint16_t *)reg = *(const uint16_t *)s;
-#endif
-		} else {
-			size = 1;
-#if defined(RTE_ARCH_X86)
-			outb_p(*s, reg);
-#else
-			*(volatile uint8_t *)reg = *s;
-#endif
-		}
-	}
-}
-
-int
-pci_uio_ioport_unmap(struct rte_pci_ioport *p)
-{
-#if defined(RTE_ARCH_X86)
-	RTE_SET_USED(p);
-	/* FIXME close intr fd ? */
-	return 0;
-#else
-	return munmap((void *)(uintptr_t)p->base, p->len);
-#endif
-}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
deleted file mode 100644
index aa9d96e..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <fcntl.h>
-#include <linux/pci_regs.h>
-#include <sys/eventfd.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <stdbool.h>
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-#include "eal_vfio.h"
-#include "eal_private.h"
-
-/**
- * @file
- * PCI probing under linux (VFIO version)
- *
- * This code tries to determine if the PCI device is bound to VFIO driver,
- * and initialize it (map BARs, set up interrupts) if that's the case.
- *
- * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
- */
-
-#ifdef VFIO_PRESENT
-
-#define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
-#define PAGE_MASK   (~(PAGE_SIZE - 1))
-
-static struct rte_tailq_elem rte_vfio_tailq = {
-	.name = "VFIO_RESOURCE_LIST",
-};
-EAL_REGISTER_TAILQ(rte_vfio_tailq)
-
-int
-pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
-		    void *buf, size_t len, off_t offs)
-{
-	return pread64(intr_handle->vfio_dev_fd, buf, len,
-	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
-}
-
-int
-pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
-		    const void *buf, size_t len, off_t offs)
-{
-	return pwrite64(intr_handle->vfio_dev_fd, buf, len,
-	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
-}
-
-/* get PCI BAR number where MSI-X interrupts are */
-static int
-pci_vfio_get_msix_bar(int fd, int *msix_bar, uint32_t *msix_table_offset,
-		      uint32_t *msix_table_size)
-{
-	int ret;
-	uint32_t reg;
-	uint16_t flags;
-	uint8_t cap_id, cap_offset;
-
-	/* read PCI capability pointer from config space */
-	ret = pread64(fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_CAPABILITY_LIST);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
-				"config space!\n");
-		return -1;
-	}
-
-	/* we need first byte */
-	cap_offset = reg & 0xFF;
-
-	while (cap_offset) {
-
-		/* read PCI capability ID */
-		ret = pread64(fd, &reg, sizeof(reg),
-				VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-				cap_offset);
-		if (ret != sizeof(reg)) {
-			RTE_LOG(ERR, EAL, "Cannot read capability ID from PCI "
-					"config space!\n");
-			return -1;
-		}
-
-		/* we need first byte */
-		cap_id = reg & 0xFF;
-
-		/* if we haven't reached MSI-X, check next capability */
-		if (cap_id != PCI_CAP_ID_MSIX) {
-			ret = pread64(fd, &reg, sizeof(reg),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset);
-			if (ret != sizeof(reg)) {
-				RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
-						"config space!\n");
-				return -1;
-			}
-
-			/* we need second byte */
-			cap_offset = (reg & 0xFF00) >> 8;
-
-			continue;
-		}
-		/* else, read table offset */
-		else {
-			/* table offset resides in the next 4 bytes */
-			ret = pread64(fd, &reg, sizeof(reg),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset + 4);
-			if (ret != sizeof(reg)) {
-				RTE_LOG(ERR, EAL, "Cannot read table offset from PCI config "
-						"space!\n");
-				return -1;
-			}
-
-			ret = pread64(fd, &flags, sizeof(flags),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset + 2);
-			if (ret != sizeof(flags)) {
-				RTE_LOG(ERR, EAL, "Cannot read table flags from PCI config "
-						"space!\n");
-				return -1;
-			}
-
-			*msix_bar = reg & RTE_PCI_MSIX_TABLE_BIR;
-			*msix_table_offset = reg & RTE_PCI_MSIX_TABLE_OFFSET;
-			*msix_table_size = 16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE));
-
-			return 0;
-		}
-	}
-	return 0;
-}
-
-/* set PCI bus mastering */
-static int
-pci_vfio_set_bus_master(int dev_fd, bool op)
-{
-	uint16_t reg;
-	int ret;
-
-	ret = pread64(dev_fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n");
-		return -1;
-	}
-
-	if (op)
-		/* set the master bit */
-		reg |= PCI_COMMAND_MASTER;
-	else
-		reg &= ~(PCI_COMMAND_MASTER);
-
-	ret = pwrite64(dev_fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_COMMAND);
-
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-/* set up interrupt support (but not enable interrupts) */
-static int
-pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
-{
-	int i, ret, intr_idx;
-
-	/* default to invalid index */
-	intr_idx = VFIO_PCI_NUM_IRQS;
-
-	/* get interrupt type from internal config (MSI-X by default, can be
-	 * overridden from the command line
-	 */
-	switch (internal_config.vfio_intr_mode) {
-	case RTE_INTR_MODE_MSIX:
-		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
-		break;
-	case RTE_INTR_MODE_MSI:
-		intr_idx = VFIO_PCI_MSI_IRQ_INDEX;
-		break;
-	case RTE_INTR_MODE_LEGACY:
-		intr_idx = VFIO_PCI_INTX_IRQ_INDEX;
-		break;
-	/* don't do anything if we want to automatically determine interrupt type */
-	case RTE_INTR_MODE_NONE:
-		break;
-	default:
-		RTE_LOG(ERR, EAL, "  unknown default interrupt type!\n");
-		return -1;
-	}
-
-	/* start from MSI-X interrupt type */
-	for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) {
-		struct vfio_irq_info irq = { .argsz = sizeof(irq) };
-		int fd = -1;
-
-		/* skip interrupt modes we don't want */
-		if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE &&
-				i != intr_idx)
-			continue;
-
-		irq.index = i;
-
-		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  cannot get IRQ info, "
-					"error %i (%s)\n", errno, strerror(errno));
-			return -1;
-		}
-
-		/* if this vector cannot be used with eventfd, fail if we explicitly
-		 * specified interrupt type, otherwise continue */
-		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
-			if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE) {
-				RTE_LOG(ERR, EAL,
-						"  interrupt vector does not support eventfd!\n");
-				return -1;
-			} else
-				continue;
-		}
-
-		/* set up an eventfd for interrupts */
-		fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
-		if (fd < 0) {
-			RTE_LOG(ERR, EAL, "  cannot set up eventfd, "
-					"error %i (%s)\n", errno, strerror(errno));
-			return -1;
-		}
-
-		dev->intr_handle.fd = fd;
-		dev->intr_handle.vfio_dev_fd = vfio_dev_fd;
-
-		switch (i) {
-		case VFIO_PCI_MSIX_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSIX;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
-			break;
-		case VFIO_PCI_MSI_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSI;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
-			break;
-		case VFIO_PCI_INTX_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_LEGACY;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
-			break;
-		default:
-			RTE_LOG(ERR, EAL, "  unknown interrupt type!\n");
-			return -1;
-		}
-
-		return 0;
-	}
-
-	/* if we're here, we haven't found a suitable interrupt vector */
-	return -1;
-}
-
-/*
- * map the PCI resources of a PCI device in virtual memory (VFIO version).
- * primary and secondary processes follow almost exactly the same path
- */
-int
-pci_vfio_map_resource(struct rte_pci_device *dev)
-{
-	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
-	char pci_addr[PATH_MAX] = {0};
-	int vfio_dev_fd;
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret, msix_bar;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-
-	struct pci_map *maps;
-	uint32_t msix_table_offset = 0;
-	uint32_t msix_table_size = 0;
-	uint32_t ioport_bar;
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	if ((ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
-					&vfio_dev_fd, &device_info)))
-		return ret;
-
-	/* get MSI-X BAR, if any (we have to know where it is because we can't
-	 * easily mmap it when using VFIO) */
-	msix_bar = -1;
-	ret = pci_vfio_get_msix_bar(vfio_dev_fd, &msix_bar,
-				    &msix_table_offset, &msix_table_size);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "  %s cannot get MSI-X BAR number!\n", pci_addr);
-		close(vfio_dev_fd);
-		return -1;
-	}
-
-	/* if we're in a primary process, allocate vfio_res and get region info */
-	if (internal_config.process_type == RTE_PROC_PRIMARY) {
-		vfio_res = rte_zmalloc("VFIO_RES", sizeof(*vfio_res), 0);
-		if (vfio_res == NULL) {
-			RTE_LOG(ERR, EAL,
-				"%s(): cannot store uio mmap details\n", __func__);
-			close(vfio_dev_fd);
-			return -1;
-		}
-		memcpy(&vfio_res->pci_addr, &dev->addr, sizeof(vfio_res->pci_addr));
-
-		/* get number of registers (up to BAR5) */
-		vfio_res->nb_maps = RTE_MIN((int) device_info.num_regions,
-				VFIO_PCI_BAR5_REGION_INDEX + 1);
-	} else {
-		/* if we're in a secondary process, just find our tailq entry */
-		TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-			if (rte_eal_compare_pci_addr(&vfio_res->pci_addr,
-						     &dev->addr))
-				continue;
-			break;
-		}
-		/* if we haven't found our tailq entry, something's wrong */
-		if (vfio_res == NULL) {
-			RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
-					pci_addr);
-			close(vfio_dev_fd);
-			return -1;
-		}
-	}
-
-	/* map BARs */
-	maps = vfio_res->maps;
-
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-		struct vfio_region_info reg = { .argsz = sizeof(reg) };
-		void *bar_addr;
-		struct memreg {
-			unsigned long offset, size;
-		} memreg[2] = {};
-
-		reg.index = i;
-
-		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg);
-
-		if (ret) {
-			RTE_LOG(ERR, EAL, "  %s cannot get device region info "
-					"error %i (%s)\n", pci_addr, errno, strerror(errno));
-			close(vfio_dev_fd);
-			if (internal_config.process_type == RTE_PROC_PRIMARY)
-				rte_free(vfio_res);
-			return -1;
-		}
-
-		/* chk for io port region */
-		ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar),
-			      VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX)
-			      + PCI_BASE_ADDRESS_0 + i*4);
-
-		if (ret != sizeof(ioport_bar)) {
-			RTE_LOG(ERR, EAL,
-				"Cannot read command (%x) from config space!\n",
-				PCI_BASE_ADDRESS_0 + i*4);
-			return -1;
-		}
-
-		if (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) {
-			RTE_LOG(INFO, EAL,
-				"Ignore mapping IO port bar(%d) addr: %x\n",
-				 i, ioport_bar);
-			continue;
-		}
-
-		/* skip non-mmapable BARs */
-		if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0)
-			continue;
-
-		if (i == msix_bar) {
-			/*
-			 * VFIO will not let us map the MSI-X table,
-			 * but we can map around it.
-			 */
-			uint32_t table_start = msix_table_offset;
-			uint32_t table_end = table_start + msix_table_size;
-			table_end = (table_end + ~PAGE_MASK) & PAGE_MASK;
-			table_start &= PAGE_MASK;
-
-			if (table_start == 0 && table_end >= reg.size) {
-				/* Cannot map this BAR */
-				RTE_LOG(DEBUG, EAL, "Skipping BAR %d\n", i);
-				continue;
-			} else {
-				memreg[0].offset = reg.offset;
-				memreg[0].size = table_start;
-				memreg[1].offset = reg.offset + table_end;
-				memreg[1].size = reg.size - table_end;
-
-				RTE_LOG(DEBUG, EAL,
-					"Trying to map BAR %d that contains the MSI-X "
-					"table. Trying offsets: "
-					"0x%04lx:0x%04lx, 0x%04lx:0x%04lx\n", i,
-					memreg[0].offset, memreg[0].size,
-					memreg[1].offset, memreg[1].size);
-			}
-		} else {
-			memreg[0].offset = reg.offset;
-			memreg[0].size = reg.size;
-		}
-
-		/* try to figure out an address */
-		if (internal_config.process_type == RTE_PROC_PRIMARY) {
-			/* try mapping somewhere close to the end of hugepages */
-			if (pci_map_addr == NULL)
-				pci_map_addr = pci_find_max_end_va();
-
-			bar_addr = pci_map_addr;
-			pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
-		} else {
-			bar_addr = maps[i].addr;
-		}
-
-		/* reserve the address using an inaccessible mapping */
-		bar_addr = mmap(bar_addr, reg.size, 0, MAP_PRIVATE |
-				MAP_ANONYMOUS, -1, 0);
-		if (bar_addr != MAP_FAILED) {
-			void *map_addr = NULL;
-			if (memreg[0].size) {
-				/* actual map of first part */
-				map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
-							    memreg[0].offset,
-							    memreg[0].size,
-							    MAP_FIXED);
-			}
-
-			/* if there's a second part, try to map it */
-			if (map_addr != MAP_FAILED
-			    && memreg[1].offset && memreg[1].size) {
-				void *second_addr = RTE_PTR_ADD(bar_addr,
-								memreg[1].offset -
-								(uintptr_t)reg.offset);
-				map_addr = pci_map_resource(second_addr,
-							    vfio_dev_fd, memreg[1].offset,
-							    memreg[1].size,
-							    MAP_FIXED);
-			}
-
-			if (map_addr == MAP_FAILED || !map_addr) {
-				munmap(bar_addr, reg.size);
-				bar_addr = MAP_FAILED;
-			}
-		}
-
-		if (bar_addr == MAP_FAILED ||
-				(internal_config.process_type == RTE_PROC_SECONDARY &&
-						bar_addr != maps[i].addr)) {
-			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n", pci_addr, i,
-					strerror(errno));
-			close(vfio_dev_fd);
-			if (internal_config.process_type == RTE_PROC_PRIMARY)
-				rte_free(vfio_res);
-			return -1;
-		}
-
-		maps[i].addr = bar_addr;
-		maps[i].offset = reg.offset;
-		maps[i].size = reg.size;
-		maps[i].path = NULL; /* vfio doesn't have per-resource paths */
-		dev->mem_resource[i].addr = bar_addr;
-	}
-
-	/* if secondary process, do not set up interrupts */
-	if (internal_config.process_type == RTE_PROC_PRIMARY) {
-		if (pci_vfio_setup_interrupts(dev, vfio_dev_fd) != 0) {
-			RTE_LOG(ERR, EAL, "  %s error setting up interrupts!\n", pci_addr);
-			close(vfio_dev_fd);
-			rte_free(vfio_res);
-			return -1;
-		}
-
-		/* set bus mastering for the device */
-		if (pci_vfio_set_bus_master(vfio_dev_fd, true)) {
-			RTE_LOG(ERR, EAL, "  %s cannot set up bus mastering!\n", pci_addr);
-			close(vfio_dev_fd);
-			rte_free(vfio_res);
-			return -1;
-		}
-
-		/* Reset the device */
-		ioctl(vfio_dev_fd, VFIO_DEVICE_RESET);
-	}
-
-	if (internal_config.process_type == RTE_PROC_PRIMARY)
-		TAILQ_INSERT_TAIL(vfio_res_list, vfio_res, next);
-
-	return 0;
-}
-
-int
-pci_vfio_unmap_resource(struct rte_pci_device *dev)
-{
-	char pci_addr[PATH_MAX] = {0};
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list;
-
-	struct pci_map *maps;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-
-	if (close(dev->intr_handle.fd) < 0) {
-		RTE_LOG(INFO, EAL, "Error when closing eventfd file descriptor for %s\n",
-			pci_addr);
-		return -1;
-	}
-
-	if (pci_vfio_set_bus_master(dev->intr_handle.vfio_dev_fd, false)) {
-		RTE_LOG(ERR, EAL, "  %s cannot unset bus mastering for PCI device!\n",
-				pci_addr);
-		return -1;
-	}
-
-	ret = vfio_release_device(pci_get_sysfs_path(), pci_addr,
-				  dev->intr_handle.vfio_dev_fd);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot release device\n", __func__);
-		return ret;
-	}
-
-	vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-	/* Get vfio_res */
-	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-		if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
-			continue;
-		break;
-	}
-	/* if we haven't found our tailq entry, something's wrong */
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
-				pci_addr);
-		return -1;
-	}
-
-	/* unmap BARs */
-	maps = vfio_res->maps;
-
-	RTE_LOG(INFO, EAL, "Releasing pci mapped resource for %s\n",
-		pci_addr);
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-
-		/*
-		 * We do not need to be aware of MSI-X table BAR mappings as
-		 * when mapping. Just using current maps array is enough
-		 */
-		if (maps[i].addr) {
-			RTE_LOG(INFO, EAL, "Calling pci_unmap_resource for %s at %p\n",
-				pci_addr, maps[i].addr);
-			pci_unmap_resource(maps[i].addr, maps[i].size);
-		}
-	}
-
-	TAILQ_REMOVE(vfio_res_list, vfio_res, next);
-
-	return 0;
-}
-
-int
-pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
-		    struct rte_pci_ioport *p)
-{
-	if (bar < VFIO_PCI_BAR0_REGION_INDEX ||
-	    bar > VFIO_PCI_BAR5_REGION_INDEX) {
-		RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar);
-		return -1;
-	}
-
-	p->dev = dev;
-	p->base = VFIO_GET_REGION_ADDR(bar);
-	return 0;
-}
-
-void
-pci_vfio_ioport_read(struct rte_pci_ioport *p,
-		     void *data, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
-
-	if (pread64(intr_handle->vfio_dev_fd, data,
-		    len, p->base + offset) <= 0)
-		RTE_LOG(ERR, EAL,
-			"Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n",
-			VFIO_GET_REGION_IDX(p->base), (int)offset);
-}
-
-void
-pci_vfio_ioport_write(struct rte_pci_ioport *p,
-		      const void *data, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
-
-	if (pwrite64(intr_handle->vfio_dev_fd, data,
-		     len, p->base + offset) <= 0)
-		RTE_LOG(ERR, EAL,
-			"Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n",
-			VFIO_GET_REGION_IDX(p->base), (int)offset);
-}
-
-int
-pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
-{
-	RTE_SET_USED(p);
-	return -1;
-}
-
-int
-pci_vfio_enable(void)
-{
-	return vfio_enable("vfio_pci");
-}
-
-int
-pci_vfio_is_enabled(void)
-{
-	return vfio_is_enabled("vfio_pci");
-}
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
deleted file mode 100644
index 7e8095c..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <pthread.h>
-
-/* sys/un.h with __USE_MISC uses strlen, which is unsafe */
-#ifdef __USE_MISC
-#define REMOVED_USE_MISC
-#undef __USE_MISC
-#endif
-#include <sys/un.h>
-/* make sure we redefine __USE_MISC only if it was previously undefined */
-#ifdef REMOVED_USE_MISC
-#define __USE_MISC
-#undef REMOVED_USE_MISC
-#endif
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-#include "eal_thread.h"
-
-/**
- * @file
- * VFIO socket for communication between primary and secondary processes.
- *
- * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
- */
-
-#ifdef VFIO_PRESENT
-
-#define SOCKET_PATH_FMT "%s/.%s_mp_socket"
-#define CMSGLEN (CMSG_LEN(sizeof(int)))
-#define FD_TO_CMSGHDR(fd, chdr) \
-		do {\
-			(chdr).cmsg_len = CMSGLEN;\
-			(chdr).cmsg_level = SOL_SOCKET;\
-			(chdr).cmsg_type = SCM_RIGHTS;\
-			memcpy((chdr).__cmsg_data, &(fd), sizeof(fd));\
-		} while (0)
-#define CMSGHDR_TO_FD(chdr, fd) \
-			memcpy(&(fd), (chdr).__cmsg_data, sizeof(fd))
-
-static pthread_t socket_thread;
-static int mp_socket_fd;
-
-
-/* get socket path (/var/run if root, $HOME otherwise) */
-static void
-get_socket_path(char *buffer, int bufsz)
-{
-	const char *dir = "/var/run";
-	const char *home_dir = getenv("HOME");
-
-	if (getuid() != 0 && home_dir != NULL)
-		dir = home_dir;
-
-	/* use current prefix as file path */
-	snprintf(buffer, bufsz, SOCKET_PATH_FMT, dir,
-			internal_config.hugefile_prefix);
-}
-
-
-
-/*
- * data flow for socket comm protocol:
- * 1. client sends SOCKET_REQ_CONTAINER or SOCKET_REQ_GROUP
- * 1a. in case of SOCKET_REQ_GROUP, client also then sends group number
- * 2. server receives message
- * 2a. in case of invalid group, SOCKET_ERR is sent back to client
- * 2b. in case of unbound group, SOCKET_NO_FD is sent back to client
- * 2c. in case of valid group, SOCKET_OK is sent and immediately followed by fd
- *
- * in case of any error, socket is closed.
- */
-
-/* send a request, return -1 on error */
-int
-vfio_mp_sync_send_request(int socket, int req)
-{
-	struct msghdr hdr;
-	struct iovec iov;
-	int buf;
-	int ret;
-
-	memset(&hdr, 0, sizeof(hdr));
-
-	buf = req;
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-
-	ret = sendmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-	return 0;
-}
-
-/* receive a request and return it */
-int
-vfio_mp_sync_receive_request(int socket)
-{
-	int buf;
-	struct msghdr hdr;
-	struct iovec iov;
-	int ret, req;
-
-	memset(&hdr, 0, sizeof(hdr));
-
-	buf = SOCKET_ERR;
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-
-	ret = recvmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-
-	req = buf;
-
-	return req;
-}
-
-/* send OK in message, fd in control message */
-int
-vfio_mp_sync_send_fd(int socket, int fd)
-{
-	int buf;
-	struct msghdr hdr;
-	struct cmsghdr *chdr;
-	char chdr_buf[CMSGLEN];
-	struct iovec iov;
-	int ret;
-
-	chdr = (struct cmsghdr *) chdr_buf;
-	memset(chdr, 0, sizeof(chdr_buf));
-	memset(&hdr, 0, sizeof(hdr));
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-	hdr.msg_control = chdr;
-	hdr.msg_controllen = CMSGLEN;
-
-	buf = SOCKET_OK;
-	FD_TO_CMSGHDR(fd, *chdr);
-
-	ret = sendmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-	return 0;
-}
-
-/* receive OK in message, fd in control message */
-int
-vfio_mp_sync_receive_fd(int socket)
-{
-	int buf;
-	struct msghdr hdr;
-	struct cmsghdr *chdr;
-	char chdr_buf[CMSGLEN];
-	struct iovec iov;
-	int ret, req, fd;
-
-	buf = SOCKET_ERR;
-
-	chdr = (struct cmsghdr *) chdr_buf;
-	memset(chdr, 0, sizeof(chdr_buf));
-	memset(&hdr, 0, sizeof(hdr));
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-	hdr.msg_control = chdr;
-	hdr.msg_controllen = CMSGLEN;
-
-	ret = recvmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-
-	req = buf;
-
-	if (req != SOCKET_OK)
-		return -1;
-
-	CMSGHDR_TO_FD(*chdr, fd);
-
-	return fd;
-}
-
-/* connect socket_fd in secondary process to the primary process's socket */
-int
-vfio_mp_sync_connect_to_primary(void)
-{
-	struct sockaddr_un addr;
-	socklen_t sockaddr_len;
-	int socket_fd;
-
-	/* set up a socket */
-	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-	if (socket_fd < 0) {
-		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
-		return -1;
-	}
-
-	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
-	addr.sun_family = AF_UNIX;
-
-	sockaddr_len = sizeof(struct sockaddr_un);
-
-	if (connect(socket_fd, (struct sockaddr *) &addr, sockaddr_len) == 0)
-		return socket_fd;
-
-	/* if connect failed */
-	close(socket_fd);
-	return -1;
-}
-
-
-
-/*
- * socket listening thread for primary process
- */
-static __attribute__((noreturn)) void *
-vfio_mp_sync_thread(void __rte_unused * arg)
-{
-	int ret, fd, vfio_data;
-
-	/* wait for requests on the socket */
-	for (;;) {
-		int conn_sock;
-		struct sockaddr_un addr;
-		socklen_t sockaddr_len = sizeof(addr);
-
-		/* this is a blocking call */
-		conn_sock = accept(mp_socket_fd, (struct sockaddr *) &addr,
-				&sockaddr_len);
-
-		/* just restart on error */
-		if (conn_sock == -1)
-			continue;
-
-		/* set socket to linger after close */
-		struct linger l;
-		l.l_onoff = 1;
-		l.l_linger = 60;
-
-		if (setsockopt(conn_sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0)
-			RTE_LOG(WARNING, EAL, "Cannot set SO_LINGER option "
-					"on listen socket (%s)\n", strerror(errno));
-
-		ret = vfio_mp_sync_receive_request(conn_sock);
-
-		switch (ret) {
-		case SOCKET_REQ_CONTAINER:
-			fd = vfio_get_container_fd();
-			if (fd < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			else
-				vfio_mp_sync_send_fd(conn_sock, fd);
-			close(fd);
-			break;
-		case SOCKET_REQ_GROUP:
-			/* wait for group number */
-			vfio_data = vfio_mp_sync_receive_request(conn_sock);
-			if (vfio_data < 0) {
-				close(conn_sock);
-				continue;
-			}
-
-			fd = vfio_get_group_fd(vfio_data);
-
-			if (fd < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			/* if VFIO group exists but isn't bound to VFIO driver */
-			else if (fd == 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
-			/* if group exists and is bound to VFIO driver */
-			else {
-				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
-				vfio_mp_sync_send_fd(conn_sock, fd);
-			}
-			break;
-		case SOCKET_CLR_GROUP:
-			/* wait for group fd */
-			vfio_data = vfio_mp_sync_receive_request(conn_sock);
-			if (vfio_data < 0) {
-				close(conn_sock);
-				continue;
-			}
-
-			ret = clear_group(vfio_data);
-
-			if (ret < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
-			else
-				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
-			break;
-		default:
-			vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			break;
-		}
-		close(conn_sock);
-	}
-}
-
-static int
-vfio_mp_sync_socket_setup(void)
-{
-	int ret, socket_fd;
-	struct sockaddr_un addr;
-	socklen_t sockaddr_len;
-
-	/* set up a socket */
-	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-	if (socket_fd < 0) {
-		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
-		return -1;
-	}
-
-	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
-	addr.sun_family = AF_UNIX;
-
-	sockaddr_len = sizeof(struct sockaddr_un);
-
-	unlink(addr.sun_path);
-
-	ret = bind(socket_fd, (struct sockaddr *) &addr, sockaddr_len);
-	if (ret) {
-		RTE_LOG(ERR, EAL, "Failed to bind socket: %s!\n", strerror(errno));
-		close(socket_fd);
-		return -1;
-	}
-
-	ret = listen(socket_fd, 50);
-	if (ret) {
-		RTE_LOG(ERR, EAL, "Failed to listen: %s!\n", strerror(errno));
-		close(socket_fd);
-		return -1;
-	}
-
-	/* save the socket in local configuration */
-	mp_socket_fd = socket_fd;
-
-	return 0;
-}
-
-/*
- * set up a local socket and tell it to listen for incoming connections
- */
-int
-vfio_mp_sync_setup(void)
-{
-	int ret;
-	char thread_name[RTE_MAX_THREAD_NAME_LEN];
-
-	if (vfio_mp_sync_socket_setup() < 0) {
-		RTE_LOG(ERR, EAL, "Failed to set up local socket!\n");
-		return -1;
-	}
-
-	ret = pthread_create(&socket_thread, NULL,
-			vfio_mp_sync_thread, NULL);
-	if (ret) {
-		RTE_LOG(ERR, EAL,
-			"Failed to create thread for communication with secondary processes!\n");
-		close(mp_socket_fd);
-		return -1;
-	}
-
-	/* Set thread_name for aid in debugging. */
-	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "vfio-sync");
-	ret = rte_thread_setname(socket_thread, thread_name);
-	if (ret)
-		RTE_LOG(DEBUG, EAL,
-			"Failed to set thread name for secondary processes!\n");
-
-	return 0;
-}
-
-#endif
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 0adf327..654bdf5 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1076,8 +1076,6 @@ TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
 	} \
 } while (0)
 
-#define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
-
 /**
  * l2 tunnel configuration.
  */
diff --git a/lib/librte_pci/Makefile b/lib/librte_pci/Makefile
new file mode 100644
index 0000000..e3c6ca5
--- /dev/null
+++ b/lib/librte_pci/Makefile
@@ -0,0 +1,49 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_pci.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -I$(SRCDIR) -I$(SRCDIR)/include
+
+EXPORT_MAP := rte_pci_version.map
+
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_PCI) += rte_pci.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI)-include += include/rte_pci.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
new file mode 100644
index 0000000..3858e80
--- /dev/null
+++ b/lib/librte_pci/include/rte_pci.h
@@ -0,0 +1,279 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_PCI_H_
+#define _RTE_PCI_H_
+
+/**
+ * @file
+ *
+ * RTE PCI Library
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+
+/** Formatting string for PCI device identifier: Ex: 0000:00:01.0 */
+#define PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+#define PCI_PRI_STR_SIZE sizeof("XXXXXXXX:XX:XX.X")
+
+/** Short formatting string, without domain, for PCI device: Ex: 00:01.0 */
+#define PCI_SHORT_PRI_FMT "%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+
+/** Nb. of values in PCI device identifier format string. */
+#define PCI_FMT_NVAL 4
+
+/** Nb. of values in PCI resource format. */
+#define PCI_RESOURCE_FMT_NVAL 3
+
+/** Maximum number of PCI resources. */
+#define PCI_MAX_RESOURCE 6
+
+/**
+ * A structure describing an ID for a PCI driver. Each driver provides a
+ * table of these IDs for each device that it supports.
+ */
+struct rte_pci_id {
+	uint32_t class_id;            /**< Class ID or RTE_CLASS_ANY_ID. */
+	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
+	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
+	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
+	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
+};
+
+/**
+ * A structure describing the location of a PCI device.
+ */
+struct rte_pci_addr {
+	uint32_t domain;                /**< Device domain */
+	uint8_t bus;                    /**< Device bus */
+	uint8_t devid;                  /**< Device ID */
+	uint8_t function;               /**< Device function. */
+};
+
+/** Any PCI device identifier (vendor, device, ...) */
+#define PCI_ANY_ID (0xffff)
+#define RTE_CLASS_ANY_ID (0xffffff)
+
+/**
+ * A structure describing a PCI mapping.
+ */
+struct pci_map {
+	void *addr;
+	char *path;
+	uint64_t offset;
+	uint64_t size;
+	uint64_t phaddr;
+};
+
+/**
+ * A structure describing a mapped PCI resource.
+ * For multi-process we need to reproduce all PCI mappings in secondary
+ * processes, so save them in a tailq.
+ */
+struct mapped_pci_resource {
+	TAILQ_ENTRY(mapped_pci_resource) next;
+
+	struct rte_pci_addr pci_addr;
+	char path[PATH_MAX];
+	int nb_maps;
+	struct pci_map maps[PCI_MAX_RESOURCE];
+};
+
+/** mapped pci device list */
+TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
+
+/**< Internal use only - Macro used by pci addr parsing functions **/
+#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
+do {                                                               \
+	unsigned long val;                                      \
+	char *end;                                              \
+	errno = 0;                                              \
+	val = strtoul((in), &end, 16);                          \
+	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
+		return -EINVAL;                                 \
+	(fd) = (typeof (fd))val;                                \
+	(in) = end + 1;                                         \
+} while(0)
+
+/**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided without
+ * a domain prefix (i.e. domain returned is always 0)
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned. Domain will always be
+ *	returned as 0
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	dev_addr->domain = 0;
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+/**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided including
+ * a domain prefix.
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XXXX:XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+#undef GET_PCIADDR_FIELD
+
+/**
+ * Utility function to write a pci device name, this device name can later be
+ * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
+ * BDF helpers.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ */
+static inline void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+		char *output, size_t size)
+{
+	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+			    addr->domain, addr->bus,
+			    addr->devid, addr->function) >= 0);
+}
+
+/* Compare two PCI device addresses. */
+/**
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
+static inline int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			 const struct rte_pci_addr *addr2)
+{
+	uint64_t dev_addr, dev_addr2;
+
+	if ((addr == NULL) || (addr2 == NULL))
+		return -1;
+
+	dev_addr = ((uint64_t)addr->domain << 24) |
+		(addr->bus << 16) | (addr->devid << 8) | addr->function;
+	dev_addr2 = ((uint64_t)addr2->domain << 24) |
+		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+	if (dev_addr > dev_addr2)
+		return 1;
+	else if (dev_addr < dev_addr2)
+		return -1;
+	else
+		return 0;
+}
+
+/**
+ * Map a particular resource from a file.
+ *
+ * @param requested_addr
+ *      The starting address for the new mapping range.
+ * @param fd
+ *      The file descriptor.
+ * @param offset
+ *      The offset for the mapping range.
+ * @param size
+ *      The size for the mapping range.
+ * @param additional_flags
+ *      The additional flags for the mapping range.
+ * @return
+ *   - On success, the function returns a pointer to the mapped area.
+ *   - On error, the value MAP_FAILED is returned.
+ */
+void *pci_map_resource(void *requested_addr, int fd, off_t offset,
+		size_t size, int additional_flags);
+
+/**
+ * Unmap a particular resource.
+ *
+ * @param requested_addr
+ *      The address for the unmapping range.
+ * @param size
+ *      The size for the unmapping range.
+ */
+void pci_unmap_resource(void *requested_addr, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PCI_H_ */
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
new file mode 100644
index 0000000..9dfdd3f
--- /dev/null
+++ b/lib/librte_pci/rte_pci.c
@@ -0,0 +1,92 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+
+#include "rte_pci.h"
+
+/* map a particular resource from a file */
+void *
+pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+		 int additional_flags)
+{
+	void *mapaddr;
+
+	/* Map the PCI memory resource of device */
+	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+			MAP_SHARED | additional_flags, fd, offset);
+	if (mapaddr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
+			__func__, fd, requested_addr,
+			(unsigned long)size, (unsigned long)offset,
+			strerror(errno), mapaddr);
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
+
+	return mapaddr;
+}
+
+/* unmap a particular resource */
+void
+pci_unmap_resource(void *requested_addr, size_t size)
+{
+	if (requested_addr == NULL)
+		return;
+
+	/* Unmap the PCI memory resource of device */
+	if (munmap(requested_addr, size)) {
+		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+			__func__, requested_addr, (unsigned long)size,
+			strerror(errno));
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
+				requested_addr);
+}
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
new file mode 100644
index 0000000..64dec54
--- /dev/null
+++ b/lib/librte_pci/rte_pci_version.map
@@ -0,0 +1,8 @@
+DPDK_17.11 {
+	global:
+
+	pci_map_resource;
+	pci_unmap_resource;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index c25fdd9..f93618f 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -96,6 +96,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI)            += -lrte_pci
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
@@ -104,6 +105,8 @@ ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
 endif
 
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI_BUS)        += -lrte_bus_pci
+
 ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
 # plugins (link only if static libraries)
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH 06/13] pci: avoid inlining functions
  2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
                   ` (4 preceding siblings ...)
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 05/13] pci: introduce PCI lib and bus Gaetan Rivet
@ 2017-08-25  9:04 ` Gaetan Rivet
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 07/13] pci: avoid over-complicated macro Gaetan Rivet
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-08-25  9:04 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Parsing operations should not happen in performance critical sections.
Headers should not propose implementations unless duly required.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_pci/include/rte_pci.h   | 69 ++++----------------------------------
 lib/librte_pci/rte_pci.c           | 65 +++++++++++++++++++++++++++++++++++
 lib/librte_pci/rte_pci_version.map |  4 +++
 3 files changed, 75 insertions(+), 63 deletions(-)

diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
index 3858e80..09a609a 100644
--- a/lib/librte_pci/include/rte_pci.h
+++ b/lib/librte_pci/include/rte_pci.h
@@ -126,19 +126,6 @@ struct mapped_pci_resource {
 /** mapped pci device list */
 TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 
-/**< Internal use only - Macro used by pci addr parsing functions **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
-do {                                                               \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
-
 /**
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided without
@@ -152,15 +139,7 @@ do {                                                               \
  * @return
  *  0 on success, negative on error.
  */
-static inline int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
+int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to produce a PCI Bus-Device-Function value
@@ -174,16 +153,7 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
  * @return
  *  0 on success, negative on error.
  */
-static inline int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-#undef GET_PCIADDR_FIELD
+int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to write a pci device name, this device name can later be
@@ -197,17 +167,9 @@ eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
  * @param size
  *	The output buffer size
  */
-static inline void
-rte_pci_device_name(const struct rte_pci_addr *addr,
-		char *output, size_t size)
-{
-	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
-	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
-			    addr->domain, addr->bus,
-			    addr->devid, addr->function) >= 0);
-}
+void rte_pci_device_name(const struct rte_pci_addr *addr,
+			 char *output, size_t size);
 
-/* Compare two PCI device addresses. */
 /**
  * Utility function to compare two PCI device addresses.
  *
@@ -220,27 +182,8 @@ rte_pci_device_name(const struct rte_pci_addr *addr,
  *	Positive on addr is greater than addr2.
  *	Negative on addr is less than addr2, or error.
  */
-static inline int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			 const struct rte_pci_addr *addr2)
-{
-	uint64_t dev_addr, dev_addr2;
-
-	if ((addr == NULL) || (addr2 == NULL))
-		return -1;
-
-	dev_addr = ((uint64_t)addr->domain << 24) |
-		(addr->bus << 16) | (addr->devid << 8) | addr->function;
-	dev_addr2 = ((uint64_t)addr2->domain << 24) |
-		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
-
-	if (dev_addr > dev_addr2)
-		return 1;
-	else if (dev_addr < dev_addr2)
-		return -1;
-	else
-		return 0;
-}
+int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			     const struct rte_pci_addr *addr2);
 
 /**
  * Map a particular resource from a file.
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index 9dfdd3f..8584b55 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -53,6 +53,71 @@
 
 #include "rte_pci.h"
 
+/* Macro used by pci addr parsing functions. **/
+#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                     \
+do {                                                            \
+	unsigned long val;                                      \
+	char *end;                                              \
+	errno = 0;                                              \
+	val = strtoul((in), &end, 16);                          \
+	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
+		return -EINVAL;                                 \
+	(fd) = (typeof (fd))val;                                \
+	(in) = end + 1;                                         \
+} while(0)
+
+int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	dev_addr->domain = 0;
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+		    char *output, size_t size)
+{
+	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+			    addr->domain, addr->bus,
+			    addr->devid, addr->function) >= 0);
+}
+
+int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			 const struct rte_pci_addr *addr2)
+{
+	uint64_t dev_addr, dev_addr2;
+
+	if ((addr == NULL) || (addr2 == NULL))
+		return -1;
+
+	dev_addr = ((uint64_t)addr->domain << 24) |
+		(addr->bus << 16) | (addr->devid << 8) | addr->function;
+	dev_addr2 = ((uint64_t)addr2->domain << 24) |
+		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+	if (dev_addr > dev_addr2)
+		return 1;
+	else if (dev_addr < dev_addr2)
+		return -1;
+	else
+		return 0;
+}
+
 /* map a particular resource from a file */
 void *
 pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index 64dec54..a940259 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -1,8 +1,12 @@
 DPDK_17.11 {
 	global:
 
+	eal_parse_pci_BDF;
+	eal_parse_pci_DomBDF;
 	pci_map_resource;
 	pci_unmap_resource;
+	rte_eal_compare_pci_addr;
+	rte_pci_device_name;
 
 	local: *;
 };
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH 07/13] pci: avoid over-complicated macro
  2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
                   ` (5 preceding siblings ...)
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 06/13] pci: avoid inlining functions Gaetan Rivet
@ 2017-08-25  9:04 ` Gaetan Rivet
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 08/13] pci: deprecate misnamed functions Gaetan Rivet
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-08-25  9:04 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Using a macro helps writing the code to the detriment of the reader in
this case. This is backward. Write once, read many.

The few LOCs gained is not worth the opacity of the implementation.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_pci/rte_pci.c | 65 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 46 insertions(+), 19 deletions(-)

diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index 8584b55..cbb5359 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -53,36 +53,63 @@
 
 #include "rte_pci.h"
 
-/* Macro used by pci addr parsing functions. **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                     \
-do {                                                            \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
+static inline const char *
+get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
+{
+	unsigned long val;
+	uint8_t *u8 = _u8;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != dlm || val > UINT8_MAX) {
+		errno = errno ? errno : EINVAL;
+		return NULL;
+	}
+	*u8 = (uint8_t)val;
+	return end + 1;
+}
 
 int
 eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	const char *in = input;
+
 	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
 	return 0;
 }
 
 int
 eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
 {
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	const char *in = input;
+	unsigned long val;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != ':' || val > UINT16_MAX)
+		return -EINVAL;
+	dev_addr->domain = (uint16_t)val;
+	in = end + 1;
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
 	return 0;
 }
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH 08/13] pci: deprecate misnamed functions
  2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
                   ` (6 preceding siblings ...)
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 07/13] pci: avoid over-complicated macro Gaetan Rivet
@ 2017-08-25  9:04 ` Gaetan Rivet
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 09/13] lib: include rte_bus_pci Gaetan Rivet
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-08-25  9:04 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Rename misnamed functions and describe the change in a deprecation
notice.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst | 10 ++++++
 lib/librte_pci/include/rte_pci.h     | 63 ++++++++++++++++++++++++++++++++++++
 lib/librte_pci/rte_pci.c             | 26 +++++++++++++++
 lib/librte_pci/rte_pci_version.map   |  4 +++
 4 files changed, 103 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 3362f33..1828e57 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -120,3 +120,13 @@ Deprecation Notices
   The non-"do-sig" versions of the hash tables will be removed
   (including the ``signature_offset`` parameter)
   and the "do-sig" versions renamed accordingly.
+
+* pci: Several exposed functions are misnamed.
+  The following functions are deprecated starting from v17.11 and are replaced:
+
+  - ``eal_parse_pci_BDF`` replaced by ``pci_parse_BDF``
+  - ``eal_parse_pci_DomBDF`` replaced by ``pci_parse_DomBDF``
+  - ``rte_eal_compare_pci_addr`` replaced by ``pci_addr_cmp``
+  - ``rte_pci_device_name`` replaced by ``pci_device_name``
+
+  The functions are only renamed. Their behavior is not affected.
diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
index 09a609a..224cea0 100644
--- a/lib/librte_pci/include/rte_pci.h
+++ b/lib/librte_pci/include/rte_pci.h
@@ -127,6 +127,7 @@ struct mapped_pci_resource {
 TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 
 /**
+ * @deprecated
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided without
  * a domain prefix (i.e. domain returned is always 0)
@@ -143,6 +144,22 @@ int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided without
+ * a domain prefix (i.e. domain returned is always 0)
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned. Domain will always be
+ *	returned as 0
+ * @return
+ *  0 on success, negative on error.
+ */
+int pci_parse_BDF(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
+ * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided including
  * a domain prefix.
  *
@@ -156,6 +173,21 @@ int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided including
+ * a domain prefix.
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XXXX:XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned
+ * @return
+ *  0 on success, negative on error.
+ */
+int pci_parse_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
  * Utility function to write a pci device name, this device name can later be
  * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
  * BDF helpers.
@@ -171,6 +203,22 @@ void rte_pci_device_name(const struct rte_pci_addr *addr,
 			 char *output, size_t size);
 
 /**
+ * Utility function to write a pci device name, this device name can later be
+ * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
+ * BDF helpers.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ */
+void pci_device_name(const struct rte_pci_addr *addr,
+		     char *output, size_t size);
+
+/**
+ * @deprecated
  * Utility function to compare two PCI device addresses.
  *
  * @param addr
@@ -186,6 +234,21 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 			     const struct rte_pci_addr *addr2);
 
 /**
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
+int pci_addr_cmp(const struct rte_pci_addr *addr,
+		 const struct rte_pci_addr *addr2);
+
+/**
  * Map a particular resource from a file.
  *
  * @param requested_addr
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index cbb5359..54ce10d 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -73,6 +73,12 @@ get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
 int
 eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	return pci_parse_BDF(input, dev_addr);
+}
+
+int
+pci_parse_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
 	const char *in = input;
 
 	dev_addr->domain = 0;
@@ -91,6 +97,12 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 int
 eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	return pci_parse_DomBDF(input, dev_addr);
+}
+
+int
+pci_parse_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
 	const char *in = input;
 	unsigned long val;
 	char *end;
@@ -117,6 +129,13 @@ void
 rte_pci_device_name(const struct rte_pci_addr *addr,
 		    char *output, size_t size)
 {
+	pci_device_name(addr, output, size);
+}
+
+void
+pci_device_name(const struct rte_pci_addr *addr,
+		char *output, size_t size)
+{
 	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
 	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
 			    addr->domain, addr->bus,
@@ -127,6 +146,13 @@ int
 rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 			 const struct rte_pci_addr *addr2)
 {
+	return pci_addr_cmp(addr, addr2);
+}
+
+int
+pci_addr_cmp(const struct rte_pci_addr *addr,
+	     const struct rte_pci_addr *addr2)
+{
 	uint64_t dev_addr, dev_addr2;
 
 	if ((addr == NULL) || (addr2 == NULL))
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index a940259..541769f 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -3,7 +3,11 @@ DPDK_17.11 {
 
 	eal_parse_pci_BDF;
 	eal_parse_pci_DomBDF;
+	pci_addr_cmp;
+	pci_device_name;
 	pci_map_resource;
+	pci_parse_BDF;
+	pci_parse_DomBDF;
 	pci_unmap_resource;
 	rte_eal_compare_pci_addr;
 	rte_pci_device_name;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH 09/13] lib: include rte_bus_pci
  2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
                   ` (7 preceding siblings ...)
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 08/13] pci: deprecate misnamed functions Gaetan Rivet
@ 2017-08-25  9:04 ` Gaetan Rivet
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 10/13] drivers: " Gaetan Rivet
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-08-25  9:04 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update the libraries, as structuraly unsound as it may be.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ether/rte_ethdev_pci.h          | 1 +
 lib/librte_eventdev/rte_eventdev_pmd_pci.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h
index 56b1072..722075e 100644
--- a/lib/librte_ether/rte_ethdev_pci.h
+++ b/lib/librte_ether/rte_ethdev_pci.h
@@ -36,6 +36,7 @@
 
 #include <rte_malloc.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 
 /**
diff --git a/lib/librte_eventdev/rte_eventdev_pmd_pci.h b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
index b6bd731..ade32b5 100644
--- a/lib/librte_eventdev/rte_eventdev_pmd_pci.h
+++ b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
@@ -50,6 +50,7 @@ extern "C" {
 #include <rte_eal.h>
 #include <rte_lcore.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "rte_eventdev_pmd.h"
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH 10/13] drivers: include rte_bus_pci
  2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
                   ` (8 preceding siblings ...)
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 09/13] lib: include rte_bus_pci Gaetan Rivet
@ 2017-08-25  9:04 ` Gaetan Rivet
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 11/13] test: " Gaetan Rivet
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-08-25  9:04 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update drivers.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/bus/pci/bsd/rte_pci.c            | 1 +
 drivers/bus/pci/linux/rte_pci.c          | 1 +
 drivers/bus/pci/linux/rte_pci_uio.c      | 1 +
 drivers/bus/pci/linux/rte_pci_vfio.c     | 1 +
 drivers/bus/pci/linux/rte_vfio_mp_sync.c | 1 +
 drivers/bus/pci/private.h                | 1 +
 drivers/bus/pci/rte_pci_common.c         | 1 +
 drivers/bus/pci/rte_pci_common_uio.c     | 1 +
 drivers/crypto/qat/qat_qp.c              | 1 +
 drivers/event/octeontx/ssovf_probe.c     | 1 +
 drivers/net/ark/ark_ethdev.c             | 1 +
 drivers/net/avp/avp_ethdev.c             | 2 ++
 drivers/net/bnxt/bnxt.h                  | 1 +
 drivers/net/bonding/rte_eth_bond_args.c  | 1 +
 drivers/net/cxgbe/base/adapter.h         | 1 +
 drivers/net/cxgbe/cxgbe_ethdev.c         | 1 +
 drivers/net/e1000/em_ethdev.c            | 1 +
 drivers/net/e1000/igb_ethdev.c           | 1 +
 drivers/net/e1000/igb_pf.c               | 1 +
 drivers/net/ena/ena_ethdev.h             | 1 +
 drivers/net/enic/base/vnic_dev.h         | 4 +++-
 drivers/net/enic/enic_ethdev.c           | 1 +
 drivers/net/enic/enic_main.c             | 1 +
 drivers/net/i40e/i40e_ethdev.c           | 1 +
 drivers/net/i40e/i40e_ethdev_vf.c        | 1 +
 drivers/net/ixgbe/ixgbe_ethdev.c         | 1 +
 drivers/net/ixgbe/ixgbe_ethdev.h         | 1 +
 drivers/net/mlx5/mlx5.c                  | 1 +
 drivers/net/mlx5/mlx5_ethdev.c           | 1 +
 drivers/net/sfc/sfc.h                    | 1 +
 drivers/net/sfc/sfc_ethdev.c             | 1 +
 drivers/net/thunderx/nicvf_ethdev.c      | 1 +
 drivers/net/virtio/virtio_ethdev.c       | 1 +
 drivers/net/virtio/virtio_pci.h          | 1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c     | 1 +
 35 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/pci/bsd/rte_pci.c b/drivers/bus/pci/bsd/rte_pci.c
index 5bd0f4b..6c7ab81 100644
--- a/drivers/bus/pci/bsd/rte_pci.c
+++ b/drivers/bus/pci/bsd/rte_pci.c
@@ -57,6 +57,7 @@
 #include <rte_interrupts.h>
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_common.h>
 #include <rte_launch.h>
 #include <rte_memory.h>
diff --git a/drivers/bus/pci/linux/rte_pci.c b/drivers/bus/pci/linux/rte_pci.c
index 96f9778..4f5255b 100644
--- a/drivers/bus/pci/linux/rte_pci.c
+++ b/drivers/bus/pci/linux/rte_pci.c
@@ -37,6 +37,7 @@
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 #include <rte_devargs.h>
diff --git a/drivers/bus/pci/linux/rte_pci_uio.c b/drivers/bus/pci/linux/rte_pci_uio.c
index eed6d0f..1f0dacd 100644
--- a/drivers/bus/pci/linux/rte_pci_uio.c
+++ b/drivers/bus/pci/linux/rte_pci_uio.c
@@ -47,6 +47,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_common.h>
 #include <rte_malloc.h>
diff --git a/drivers/bus/pci/linux/rte_pci_vfio.c b/drivers/bus/pci/linux/rte_pci_vfio.c
index 81b67c9..ab63423 100644
--- a/drivers/bus/pci/linux/rte_pci_vfio.c
+++ b/drivers/bus/pci/linux/rte_pci_vfio.c
@@ -42,6 +42,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 
diff --git a/drivers/bus/pci/linux/rte_vfio_mp_sync.c b/drivers/bus/pci/linux/rte_vfio_mp_sync.c
index 2c1654d..d24eba1 100644
--- a/drivers/bus/pci/linux/rte_vfio_mp_sync.c
+++ b/drivers/bus/pci/linux/rte_vfio_mp_sync.c
@@ -50,6 +50,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 7ff1fc4..fdc2c81 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -37,6 +37,7 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 struct rte_pci_driver;
 struct rte_pci_device;
diff --git a/drivers/bus/pci/rte_pci_common.c b/drivers/bus/pci/rte_pci_common.c
index c37b85b..459ae42 100644
--- a/drivers/bus/pci/rte_pci_common.c
+++ b/drivers/bus/pci/rte_pci_common.c
@@ -45,6 +45,7 @@
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_per_lcore.h>
 #include <rte_memory.h>
 #include <rte_memzone.h>
diff --git a/drivers/bus/pci/rte_pci_common_uio.c b/drivers/bus/pci/rte_pci_common_uio.c
index 4365660..544c606 100644
--- a/drivers/bus/pci/rte_pci_common_uio.c
+++ b/drivers/bus/pci/rte_pci_common_uio.c
@@ -40,6 +40,7 @@
 
 #include <rte_eal.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tailq.h>
 #include <rte_log.h>
 #include <rte_malloc.h>
diff --git a/drivers/crypto/qat/qat_qp.c b/drivers/crypto/qat/qat_qp.c
index 5048d21..a22d6ef 100644
--- a/drivers/crypto/qat/qat_qp.c
+++ b/drivers/crypto/qat/qat_qp.c
@@ -37,6 +37,7 @@
 #include <rte_memzone.h>
 #include <rte_cryptodev_pmd.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_prefetch.h>
 
diff --git a/drivers/event/octeontx/ssovf_probe.c b/drivers/event/octeontx/ssovf_probe.c
index e1c0c6d..1cac4bc 100644
--- a/drivers/event/octeontx/ssovf_probe.c
+++ b/drivers/event/octeontx/ssovf_probe.c
@@ -35,6 +35,7 @@
 #include <rte_eal.h>
 #include <rte_io.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "ssovf_evdev.h"
 
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 6db362b..78a4d79 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -35,6 +35,7 @@
 #include <sys/stat.h>
 #include <dlfcn.h>
 
+#include <rte_bus_pci.h>
 #include <rte_ethdev_pci.h>
 #include <rte_kvargs.h>
 
diff --git a/drivers/net/avp/avp_ethdev.c b/drivers/net/avp/avp_ethdev.c
index c746a0e..194aadb 100644
--- a/drivers/net/avp/avp_ethdev.c
+++ b/drivers/net/avp/avp_ethdev.c
@@ -36,6 +36,7 @@
 #include <errno.h>
 #include <unistd.h>
 
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_memcpy.h>
@@ -45,6 +46,7 @@
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 405d94d..d7409a8 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -39,6 +39,7 @@
 #include <sys/queue.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_memory.h>
 #include <rte_lcore.h>
diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index bb634c6..2b7b464 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -33,6 +33,7 @@
 
 #include <rte_devargs.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 
 #include <cmdline_parse.h>
diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index 5e5f221..f2057af 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -36,6 +36,7 @@
 #ifndef __T4_ADAPTER_H__
 #define __T4_ADAPTER_H__
 
+#include <rte_bus_pci.h>
 #include <rte_mbuf.h>
 #include <rte_io.h>
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 7bca456..dc322da 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 3d4ab93..c52e5f7 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index e4f7a9f..36385cf 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/e1000/igb_pf.c b/drivers/net/e1000/igb_pf.c
index 6809d30..cd6ae2f 100644
--- a/drivers/net/e1000/igb_pf.c
+++ b/drivers/net/e1000/igb_pf.c
@@ -39,6 +39,7 @@
 #include <stdarg.h>
 #include <inttypes.h>
 
+#include <rte_bus_pci.h>
 #include <rte_interrupts.h>
 #include <rte_log.h>
 #include <rte_debug.h>
diff --git a/drivers/net/ena/ena_ethdev.h b/drivers/net/ena/ena_ethdev.h
index dc3080f..be8bc9f 100644
--- a/drivers/net/ena/ena_ethdev.h
+++ b/drivers/net/ena/ena_ethdev.h
@@ -35,6 +35,7 @@
 #define _ENA_ETHDEV_H_
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "ena_com.h"
 
diff --git a/drivers/net/enic/base/vnic_dev.h b/drivers/net/enic/base/vnic_dev.h
index 9a9e691..c9ca25b 100644
--- a/drivers/net/enic/base/vnic_dev.h
+++ b/drivers/net/enic/base/vnic_dev.h
@@ -35,8 +35,10 @@
 #ifndef _VNIC_DEV_H_
 #define _VNIC_DEV_H_
 
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+
 #include "enic_compat.h"
-#include "rte_pci.h"
 #include "vnic_resource.h"
 #include "vnic_devcmd.h"
 
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index da8fec2..681efb2 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -37,6 +37,7 @@
 
 #include <rte_dev.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_string_fns.h>
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 40dbec7..b35ad5d 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -40,6 +40,7 @@
 #include <libgen.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_memzone.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 5f26e24..edf6e4c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_eal.h>
 #include <rte_string_fns.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index f6d8293..1686ad0 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -47,6 +47,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 22171d8..a348112 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index caa50c8..383ec71 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -41,6 +41,7 @@
 #include <rte_time.h>
 #include <rte_hash.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tm_driver.h>
 
 /* need update link, bit flag */
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b7e5046..968599e 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -58,6 +58,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_common.h>
 #include <rte_kvargs.h>
 #ifdef PEDANTIC
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index b0eb3cd..c2dc1f1 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -56,6 +56,7 @@
 #endif
 #include <rte_atomic.h>
 #include <rte_ethdev.h>
+#include <rte_bus_pci.h>
 #include <rte_mbuf.h>
 #include <rte_common.h>
 #include <rte_interrupts.h>
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 286d1ac..5944103 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -35,6 +35,7 @@
 #include <stdbool.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_kvargs.h>
 #include <rte_spinlock.h>
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 12bcd6f..74e2486 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -33,6 +33,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_errno.h>
 
 #include "efx.h"
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index edc17f1..e63dc4e 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -61,6 +61,7 @@
 #include <rte_malloc.h>
 #include <rte_random.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tailq.h>
 
 #include "base/nicvf_plat.h"
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index e320811..9a6850d 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -46,6 +46,7 @@
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_common.h>
 #include <rte_errno.h>
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 18caebd..c8261b7 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -37,6 +37,7 @@
 #include <stdint.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 
 struct virtqueue;
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 3910991..bf4900d 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH 11/13] test: include rte_bus_pci
  2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
                   ` (9 preceding siblings ...)
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 10/13] drivers: " Gaetan Rivet
@ 2017-08-25  9:04 ` Gaetan Rivet
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 12/13] app/testpmd: " Gaetan Rivet
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-08-25  9:04 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update test applications.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 test/test/virtual_pmd.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/test/test/virtual_pmd.c b/test/test/virtual_pmd.c
index 9d46ad5..72e784a 100644
--- a/test/test/virtual_pmd.c
+++ b/test/test/virtual_pmd.c
@@ -34,6 +34,7 @@
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_memory.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH 12/13] app/testpmd: include rte_bus_pci
  2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
                   ` (10 preceding siblings ...)
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 11/13] test: " Gaetan Rivet
@ 2017-08-25  9:04 ` Gaetan Rivet
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 13/13] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-08-25  9:04 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update applications.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 app/test-pmd/testpmd.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index c9d7739..787fc03 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -35,6 +35,7 @@
 #define _TESTPMD_H_
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_gro.h>
 
 #define RTE_PORT_ALL            (~(portid_t)0x0)
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH 13/13] cryptodev: move PCI specific helpers to drivers/crypto
  2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
                   ` (11 preceding siblings ...)
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 12/13] app/testpmd: " Gaetan Rivet
@ 2017-08-25  9:04 ` Gaetan Rivet
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-08-25  9:04 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Those helpers rely on the PCI bus driver implementation.
Other similar libraries relied on the bus-specifics being handled in
inlined functions, to be compiled on demand by drivers, once the proper
PCI dependency has been settled. This seems unsafe.

Move the PCI-specific helpers out of the lib directory to the
drivers/crypto directory, properly following the dependency hierarchy.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/Makefile                                 |   2 +-
 drivers/crypto/Makefile                          |   4 +-
 drivers/crypto/pci/Makefile                      |  52 +++++++++
 drivers/crypto/pci/rte_cryptodev_pci.c           | 128 +++++++++++++++++++++++
 drivers/crypto/pci/rte_cryptodev_pci.h           |  94 +++++++++++++++++
 drivers/crypto/pci/rte_cryptodev_pci_version.map |   7 ++
 lib/librte_cryptodev/Makefile                    |   1 -
 lib/librte_cryptodev/rte_cryptodev_pci.h         |  92 ----------------
 lib/librte_cryptodev/rte_cryptodev_pmd.c         |  94 -----------------
 lib/librte_cryptodev/rte_cryptodev_version.map   |   2 -
 10 files changed, 285 insertions(+), 191 deletions(-)
 create mode 100644 drivers/crypto/pci/Makefile
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.c
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.h
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci_version.map
 delete mode 100644 lib/librte_cryptodev/rte_cryptodev_pci.h

diff --git a/drivers/Makefile b/drivers/Makefile
index 7fef66d..a5d3fa0 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -37,7 +37,7 @@ DEPDIRS-mempool := bus
 DIRS-y += net
 DEPDIRS-net := bus mempool
 DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
-DEPDIRS-crypto := mempool
+DEPDIRS-crypto := bus mempool
 DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += event
 DEPDIRS-event := bus
 
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 7a719b9..cfd6cb6 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_cryptodev
 
+DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
+DEPDIRS-pci = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm
 DEPDIRS-aesni_gcm = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb
@@ -42,7 +44,7 @@ DEPDIRS-armv8 = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_OPENSSL) += openssl
 DEPDIRS-openssl = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat
-DEPDIRS-qat = $(core-libs)
+DEPDIRS-qat = $(core-libs) librte_cryptodev_pci
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER) += scheduler
 DEPDIRS-scheduler = $(core-libs) librte_kvargs librte_reorder
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += snow3g
diff --git a/drivers/crypto/pci/Makefile b/drivers/crypto/pci/Makefile
new file mode 100644
index 0000000..da819f2
--- /dev/null
+++ b/drivers/crypto/pci/Makefile
@@ -0,0 +1,52 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A. All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND S.A. nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_cryptodev_pci.a
+
+# library version
+LIBABIVER := 1
+
+# build flags
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# library source files
+SRCS-y += rte_cryptodev_pci.c
+
+# export include files
+SYMLINK-y-include += rte_cryptodev_pci.h
+
+# versioning export map
+EXPORT_MAP := rte_cryptodev_pci_version.map
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/crypto/pci/rte_cryptodev_pci.c b/drivers/crypto/pci/rte_cryptodev_pci.c
new file mode 100644
index 0000000..a2a1366
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci.c
@@ -0,0 +1,128 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of the copyright holder nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_malloc.h>
+
+#include "rte_cryptodev_pci.h"
+
+int
+rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
+			size_t private_data_size,
+			cryptodev_pci_init_t dev_init)
+{
+	struct rte_cryptodev *cryptodev;
+
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+
+	int retval;
+
+	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name, rte_socket_id());
+	if (cryptodev == NULL)
+		return -ENOMEM;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc_socket(
+						"cryptodev private structure",
+						private_data_size,
+						RTE_CACHE_LINE_SIZE,
+						rte_socket_id());
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private "
+					"device data");
+	}
+
+	cryptodev->device = &pci_dev->device;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	/* Invoke PMD device initialization function */
+	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
+	retval = dev_init(cryptodev);
+	if (retval == 0)
+		return 0;
+
+	CDEV_LOG_ERR("driver %s: crypto_dev_init(vendor_id=0x%x device_id=0x%x)"
+			" failed", pci_dev->device.driver->name,
+			(unsigned int) pci_dev->id.vendor_id,
+			(unsigned int) pci_dev->id.device_id);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	return -ENXIO;
+}
+
+int
+rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
+		cryptodev_pci_uninit_t dev_uninit)
+{
+	struct rte_cryptodev *cryptodev;
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+	int ret;
+
+	if (pci_dev == NULL)
+		return -EINVAL;
+
+	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
+	if (cryptodev == NULL)
+		return -ENODEV;
+
+	/* Invoke PMD device uninit function */
+	if (dev_uninit) {
+		ret = dev_uninit(cryptodev);
+		if (ret)
+			return ret;
+	}
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->device = NULL;
+	cryptodev->data = NULL;
+
+	return 0;
+}
diff --git a/drivers/crypto/pci/rte_cryptodev_pci.h b/drivers/crypto/pci/rte_cryptodev_pci.h
new file mode 100644
index 0000000..97b6f1e
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci.h
@@ -0,0 +1,94 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of the copyright holder nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_CRYPTODEV_PCI_H_
+#define _RTE_CRYPTODEV_PCI_H_
+
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
+
+/**
+ * Initialisation function of a crypto driver invoked for each matching
+ * crypto PCI device detected during the PCI probing phase.
+ *
+ * @param	dev	The dev pointer is the address of the *rte_cryptodev*
+ *			structure associated with the matching device and which
+ *			has been [automatically] allocated in the
+ *			*rte_crypto_devices* array.
+ *
+ * @return
+ *   - 0: Success, the device is properly initialised by the driver.
+ *        In particular, the driver MUST have set up the *dev_ops* pointer
+ *        of the *dev* structure.
+ *   - <0: Error code of the device initialisation failure.
+ */
+typedef int (*cryptodev_pci_init_t)(struct rte_cryptodev *dev);
+
+/**
+ * Finalisation function of a driver invoked for each matching
+ * PCI device detected during the PCI closing phase.
+ *
+ * @param	dev	The dev pointer is the address of the *rte_cryptodev*
+ *			structure associated with the matching device and which
+ *			has been [automatically] allocated in the
+ *			*rte_crypto_devices* array.
+ *
+ *  * @return
+ *   - 0: Success, the device is properly finalised by the driver.
+ *        In particular, the driver MUST free the *dev_ops* pointer
+ *        of the *dev* structure.
+ *   - <0: Error code of the device initialisation failure.
+ */
+typedef int (*cryptodev_pci_uninit_t)(struct rte_cryptodev *dev);
+
+/**
+ * @internal
+ * Wrapper for use by pci drivers as a .probe function to attach to a crypto
+ * interface.
+ */
+int
+rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
+			size_t private_data_size,
+			cryptodev_pci_init_t dev_init);
+
+/**
+ * @internal
+ * Wrapper for use by pci drivers as a .remove function to detach a crypto
+ * interface.
+ */
+int
+rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
+		cryptodev_pci_uninit_t dev_uninit);
+
+#endif /* _RTE_CRYPTODEV_PCI_H_ */
diff --git a/drivers/crypto/pci/rte_cryptodev_pci_version.map b/drivers/crypto/pci/rte_cryptodev_pci_version.map
new file mode 100644
index 0000000..0510fef
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci_version.map
@@ -0,0 +1,7 @@
+DPDK_17.11 {
+	global:
+
+	rte_cryptodev_pci_generic_probe;
+	rte_cryptodev_pci_generic_remove;
+
+};
diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index 6ac331b..bd94cf7 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -49,7 +49,6 @@ SYMLINK-y-include += rte_crypto_sym.h
 SYMLINK-y-include += rte_cryptodev.h
 SYMLINK-y-include += rte_cryptodev_pmd.h
 SYMLINK-y-include += rte_cryptodev_vdev.h
-SYMLINK-y-include += rte_cryptodev_pci.h
 
 # versioning export map
 EXPORT_MAP := rte_cryptodev_version.map
diff --git a/lib/librte_cryptodev/rte_cryptodev_pci.h b/lib/librte_cryptodev/rte_cryptodev_pci.h
deleted file mode 100644
index 67eda96..0000000
--- a/lib/librte_cryptodev/rte_cryptodev_pci.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2017 Intel Corporation. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of the copyright holder nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_CRYPTODEV_PCI_H_
-#define _RTE_CRYPTODEV_PCI_H_
-
-#include <rte_pci.h>
-#include "rte_cryptodev.h"
-
-/**
- * Initialisation function of a crypto driver invoked for each matching
- * crypto PCI device detected during the PCI probing phase.
- *
- * @param	dev	The dev pointer is the address of the *rte_cryptodev*
- *			structure associated with the matching device and which
- *			has been [automatically] allocated in the
- *			*rte_crypto_devices* array.
- *
- * @return
- *   - 0: Success, the device is properly initialised by the driver.
- *        In particular, the driver MUST have set up the *dev_ops* pointer
- *        of the *dev* structure.
- *   - <0: Error code of the device initialisation failure.
- */
-typedef int (*cryptodev_pci_init_t)(struct rte_cryptodev *dev);
-
-/**
- * Finalisation function of a driver invoked for each matching
- * PCI device detected during the PCI closing phase.
- *
- * @param	dev	The dev pointer is the address of the *rte_cryptodev*
- *			structure associated with the matching device and which
- *			has been [automatically] allocated in the
- *			*rte_crypto_devices* array.
- *
- *  * @return
- *   - 0: Success, the device is properly finalised by the driver.
- *        In particular, the driver MUST free the *dev_ops* pointer
- *        of the *dev* structure.
- *   - <0: Error code of the device initialisation failure.
- */
-typedef int (*cryptodev_pci_uninit_t)(struct rte_cryptodev *dev);
-
-/**
- * @internal
- * Wrapper for use by pci drivers as a .probe function to attach to a crypto
- * interface.
- */
-int
-rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
-			size_t private_data_size,
-			cryptodev_pci_init_t dev_init);
-
-/**
- * @internal
- * Wrapper for use by pci drivers as a .remove function to detach a crypto
- * interface.
- */
-int
-rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
-		cryptodev_pci_uninit_t dev_uninit);
-
-#endif /* _RTE_CRYPTODEV_PCI_H_ */
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.c b/lib/librte_cryptodev/rte_cryptodev_pmd.c
index a57faad..ec5c33b 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.c
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.c
@@ -33,7 +33,6 @@
 #include <rte_malloc.h>
 
 #include "rte_cryptodev_vdev.h"
-#include "rte_cryptodev_pci.h"
 #include "rte_cryptodev_pmd.h"
 
 /**
@@ -154,96 +153,3 @@ rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
 	rte_kvargs_free(kvlist);
 	return ret;
 }
-
-int
-rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
-			size_t private_data_size,
-			cryptodev_pci_init_t dev_init)
-{
-	struct rte_cryptodev *cryptodev;
-
-	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
-
-	int retval;
-
-	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
-			sizeof(cryptodev_name));
-
-	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name, rte_socket_id());
-	if (cryptodev == NULL)
-		return -ENOMEM;
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-		cryptodev->data->dev_private =
-				rte_zmalloc_socket(
-						"cryptodev private structure",
-						private_data_size,
-						RTE_CACHE_LINE_SIZE,
-						rte_socket_id());
-
-		if (cryptodev->data->dev_private == NULL)
-			rte_panic("Cannot allocate memzone for private "
-					"device data");
-	}
-
-	cryptodev->device = &pci_dev->device;
-
-	/* init user callbacks */
-	TAILQ_INIT(&(cryptodev->link_intr_cbs));
-
-	/* Invoke PMD device initialization function */
-	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
-	retval = dev_init(cryptodev);
-	if (retval == 0)
-		return 0;
-
-	CDEV_LOG_ERR("driver %s: crypto_dev_init(vendor_id=0x%x device_id=0x%x)"
-			" failed", pci_dev->device.driver->name,
-			(unsigned int) pci_dev->id.vendor_id,
-			(unsigned int) pci_dev->id.device_id);
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-		rte_free(cryptodev->data->dev_private);
-
-	/* free crypto device */
-	rte_cryptodev_pmd_release_device(cryptodev);
-
-	return -ENXIO;
-}
-
-int
-rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
-		cryptodev_pci_uninit_t dev_uninit)
-{
-	struct rte_cryptodev *cryptodev;
-	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
-	int ret;
-
-	if (pci_dev == NULL)
-		return -EINVAL;
-
-	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
-			sizeof(cryptodev_name));
-
-	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
-	if (cryptodev == NULL)
-		return -ENODEV;
-
-	/* Invoke PMD device uninit function */
-	if (dev_uninit) {
-		ret = dev_uninit(cryptodev);
-		if (ret)
-			return ret;
-	}
-
-	/* free crypto device */
-	rte_cryptodev_pmd_release_device(cryptodev);
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-		rte_free(cryptodev->data->dev_private);
-
-	cryptodev->device = NULL;
-	cryptodev->data = NULL;
-
-	return 0;
-}
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index e9ba88a..496253d 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -68,8 +68,6 @@ DPDK_17.08 {
 	rte_cryptodev_get_aead_algo_enum;
 	rte_cryptodev_get_header_session_size;
 	rte_cryptodev_get_private_session_size;
-	rte_cryptodev_pci_generic_probe;
-	rte_cryptodev_pci_generic_remove;
 	rte_cryptodev_sym_capability_check_aead;
 	rte_cryptodev_sym_session_init;
 	rte_cryptodev_sym_session_clear;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH 05/13] pci: introduce PCI lib and bus
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 05/13] pci: introduce PCI lib and bus Gaetan Rivet
@ 2017-08-25  9:31   ` Luca Boccassi
  2017-08-25  9:34     ` Gaëtan Rivet
  0 siblings, 1 reply; 156+ messages in thread
From: Luca Boccassi @ 2017-08-25  9:31 UTC (permalink / raw)
  To: Gaetan Rivet, dev

On Fri, 2017-08-25 at 11:04 +0200, Gaetan Rivet wrote:
> The PCI lib defines the types and methods allowing to use PCI
> elements.
> 
> The PCI bus implements a bus driver for PCI devices by constructing
> rte_bus elements using the PCI lib.
> 
> Move the relevant code out of the EAL to their expected place.
> 
> Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> ---
>  config/common_base                             |  15 +
>  drivers/bus/Makefile                           |   2 +
>  drivers/bus/pci/Makefile                       |  60 ++
>  drivers/bus/pci/bsd/Makefile                   |  32 ++
>  drivers/bus/pci/bsd/rte_pci.c                  | 670
> +++++++++++++++++++++++
>  drivers/bus/pci/include/rte_bus_pci.h          | 387 +++++++++++++
>  drivers/bus/pci/linux/Makefile                 |  37 ++
>  drivers/bus/pci/linux/rte_pci.c                | 723
> +++++++++++++++++++++++++
>  drivers/bus/pci/linux/rte_pci_init.h           |  97 ++++
>  drivers/bus/pci/linux/rte_pci_uio.c            | 567
> +++++++++++++++++++
>  drivers/bus/pci/linux/rte_pci_vfio.c           | 674
> +++++++++++++++++++++++
>  drivers/bus/pci/linux/rte_vfio_mp_sync.c       | 424 +++++++++++++++
>  drivers/bus/pci/private.h                      | 173 ++++++
>  drivers/bus/pci/rte_bus_pci_version.map        |  21 +
>  drivers/bus/pci/rte_pci_common.c               | 542
> ++++++++++++++++++
>  drivers/bus/pci/rte_pci_common_uio.c           | 234 ++++++++
>  lib/Makefile                                   |   2 +
>  lib/librte_eal/bsdapp/eal/Makefile             |   3 -
>  lib/librte_eal/bsdapp/eal/eal_pci.c            | 670 -------------
> ----------
>  lib/librte_eal/common/Makefile                 |   2 +-
>  lib/librte_eal/common/eal_common_pci.c         | 580 -------------
> -------
>  lib/librte_eal/common/eal_common_pci_uio.c     | 233 --------
>  lib/librte_eal/common/include/rte_pci.h        | 598 -------------
> -------
>  lib/librte_eal/linuxapp/eal/Makefile           |  10 -
>  lib/librte_eal/linuxapp/eal/eal_pci.c          | 723 -------------
> ------------
>  lib/librte_eal/linuxapp/eal/eal_pci_init.h     |  97 ----
>  lib/librte_eal/linuxapp/eal/eal_pci_uio.c      | 567 -------------
> ------
>  lib/librte_eal/linuxapp/eal/eal_pci_vfio.c     | 674 -------------
> ----------
>  lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c | 424 ---------------
>  lib/librte_ether/rte_ethdev.h                  |   2 -
>  lib/librte_pci/Makefile                        |  49 ++
>  lib/librte_pci/include/rte_pci.h               | 279 ++++++++++
>  lib/librte_pci/rte_pci.c                       |  92 ++++
>  lib/librte_pci/rte_pci_version.map             |   8 +
>  mk/rte.app.mk                                  |   3 +
>  35 files changed, 5092 insertions(+), 4582 deletions(-)
>  create mode 100644 drivers/bus/pci/Makefile
>  create mode 100644 drivers/bus/pci/bsd/Makefile
>  create mode 100644 drivers/bus/pci/bsd/rte_pci.c
>  create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
>  create mode 100644 drivers/bus/pci/linux/Makefile
>  create mode 100644 drivers/bus/pci/linux/rte_pci.c
>  create mode 100644 drivers/bus/pci/linux/rte_pci_init.h
>  create mode 100644 drivers/bus/pci/linux/rte_pci_uio.c
>  create mode 100644 drivers/bus/pci/linux/rte_pci_vfio.c
>  create mode 100644 drivers/bus/pci/linux/rte_vfio_mp_sync.c
>  create mode 100644 drivers/bus/pci/private.h
>  create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
>  create mode 100644 drivers/bus/pci/rte_pci_common.c
>  create mode 100644 drivers/bus/pci/rte_pci_common_uio.c
>  delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
>  delete mode 100644 lib/librte_eal/common/eal_common_pci.c
>  delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
>  delete mode 100644 lib/librte_eal/common/include/rte_pci.h
>  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
>  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
>  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
>  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
>  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
>  create mode 100644 lib/librte_pci/Makefile
>  create mode 100644 lib/librte_pci/include/rte_pci.h
>  create mode 100644 lib/librte_pci/rte_pci.c
>  create mode 100644 lib/librte_pci/rte_pci_version.map
> 
> diff --git a/lib/librte_pci/Makefile b/lib/librte_pci/Makefile
> new file mode 100644
> index 0000000..e3c6ca5
> --- /dev/null
> +++ b/lib/librte_pci/Makefile
> @@ -0,0 +1,49 @@
> +#   BSD LICENSE
> +#
> +#   Copyright(c) 2017 6WIND S.A.
> +#   All rights reserved.
> +#
> +#   Redistribution and use in source and binary forms, with or
> without
> +#   modification, are permitted provided that the following
> conditions
> +#   are met:
> +#
> +#     * Redistributions of source code must retain the above
> copyright
> +#       notice, this list of conditions and the following
> disclaimer.
> +#     * Redistributions in binary form must reproduce the above
> copyright
> +#       notice, this list of conditions and the following disclaimer
> in
> +#       the documentation and/or other materials provided with the
> +#       distribution.
> +#     * Neither the name of 6WIND nor the names of its
> +#       contributors may be used to endorse or promote products
> derived
> +#       from this software without specific prior written
> permission.
> +#
> +#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> CONTRIBUTORS
> +#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
> NOT
> +#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
> FITNESS FOR
> +#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> COPYRIGHT
> +#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
> INCIDENTAL,
> +#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> +#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> USE,
> +#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> ON ANY
> +#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
> TORT
> +#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> THE USE
> +#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
> DAMAGE.
> +
> +include $(RTE_SDK)/mk/rte.vars.mk
> +
> +# library name
> +LIB = librte_pci.a
> +
> +CFLAGS += -O3
> +CFLAGS += $(WERROR_FLAGS)
> +CFLAGS += -I$(SRCDIR) -I$(SRCDIR)/include

This breaks build reproducibility, please use something like:

CFLAGS := -I$(SRCDIR)/include -I$(SRCDIR) $(CFLAGS)
CFLAGS += $(WERROR_FLAGS) -O3

See http://dpdk.org/dev/patchwork/patch/27639/

-- 
Kind regards,
Luca Boccassi

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH 05/13] pci: introduce PCI lib and bus
  2017-08-25  9:31   ` Luca Boccassi
@ 2017-08-25  9:34     ` Gaëtan Rivet
  0 siblings, 0 replies; 156+ messages in thread
From: Gaëtan Rivet @ 2017-08-25  9:34 UTC (permalink / raw)
  To: Luca Boccassi; +Cc: dev

On Fri, Aug 25, 2017 at 10:31:05AM +0100, Luca Boccassi wrote:
> On Fri, 2017-08-25 at 11:04 +0200, Gaetan Rivet wrote:
> > The PCI lib defines the types and methods allowing to use PCI
> > elements.
> > 
> > The PCI bus implements a bus driver for PCI devices by constructing
> > rte_bus elements using the PCI lib.
> > 
> > Move the relevant code out of the EAL to their expected place.
> > 
> > Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> > ---
> >  config/common_base                             |  15 +
> >  drivers/bus/Makefile                           |   2 +
> >  drivers/bus/pci/Makefile                       |  60 ++
> >  drivers/bus/pci/bsd/Makefile                   |  32 ++
> >  drivers/bus/pci/bsd/rte_pci.c                  | 670
> > +++++++++++++++++++++++
> >  drivers/bus/pci/include/rte_bus_pci.h          | 387 +++++++++++++
> >  drivers/bus/pci/linux/Makefile                 |  37 ++
> >  drivers/bus/pci/linux/rte_pci.c                | 723
> > +++++++++++++++++++++++++
> >  drivers/bus/pci/linux/rte_pci_init.h           |  97 ++++
> >  drivers/bus/pci/linux/rte_pci_uio.c            | 567
> > +++++++++++++++++++
> >  drivers/bus/pci/linux/rte_pci_vfio.c           | 674
> > +++++++++++++++++++++++
> >  drivers/bus/pci/linux/rte_vfio_mp_sync.c       | 424 +++++++++++++++
> >  drivers/bus/pci/private.h                      | 173 ++++++
> >  drivers/bus/pci/rte_bus_pci_version.map        |  21 +
> >  drivers/bus/pci/rte_pci_common.c               | 542
> > ++++++++++++++++++
> >  drivers/bus/pci/rte_pci_common_uio.c           | 234 ++++++++
> >  lib/Makefile                                   |   2 +
> >  lib/librte_eal/bsdapp/eal/Makefile             |   3 -
> >  lib/librte_eal/bsdapp/eal/eal_pci.c            | 670 -------------
> > ----------
> >  lib/librte_eal/common/Makefile                 |   2 +-
> >  lib/librte_eal/common/eal_common_pci.c         | 580 -------------
> > -------
> >  lib/librte_eal/common/eal_common_pci_uio.c     | 233 --------
> >  lib/librte_eal/common/include/rte_pci.h        | 598 -------------
> > -------
> >  lib/librte_eal/linuxapp/eal/Makefile           |  10 -
> >  lib/librte_eal/linuxapp/eal/eal_pci.c          | 723 -------------
> > ------------
> >  lib/librte_eal/linuxapp/eal/eal_pci_init.h     |  97 ----
> >  lib/librte_eal/linuxapp/eal/eal_pci_uio.c      | 567 -------------
> > ------
> >  lib/librte_eal/linuxapp/eal/eal_pci_vfio.c     | 674 -------------
> > ----------
> >  lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c | 424 ---------------
> >  lib/librte_ether/rte_ethdev.h                  |   2 -
> >  lib/librte_pci/Makefile                        |  49 ++
> >  lib/librte_pci/include/rte_pci.h               | 279 ++++++++++
> >  lib/librte_pci/rte_pci.c                       |  92 ++++
> >  lib/librte_pci/rte_pci_version.map             |   8 +
> >  mk/rte.app.mk                                  |   3 +
> >  35 files changed, 5092 insertions(+), 4582 deletions(-)
> >  create mode 100644 drivers/bus/pci/Makefile
> >  create mode 100644 drivers/bus/pci/bsd/Makefile
> >  create mode 100644 drivers/bus/pci/bsd/rte_pci.c
> >  create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
> >  create mode 100644 drivers/bus/pci/linux/Makefile
> >  create mode 100644 drivers/bus/pci/linux/rte_pci.c
> >  create mode 100644 drivers/bus/pci/linux/rte_pci_init.h
> >  create mode 100644 drivers/bus/pci/linux/rte_pci_uio.c
> >  create mode 100644 drivers/bus/pci/linux/rte_pci_vfio.c
> >  create mode 100644 drivers/bus/pci/linux/rte_vfio_mp_sync.c
> >  create mode 100644 drivers/bus/pci/private.h
> >  create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
> >  create mode 100644 drivers/bus/pci/rte_pci_common.c
> >  create mode 100644 drivers/bus/pci/rte_pci_common_uio.c
> >  delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
> >  delete mode 100644 lib/librte_eal/common/eal_common_pci.c
> >  delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
> >  delete mode 100644 lib/librte_eal/common/include/rte_pci.h
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
> >  create mode 100644 lib/librte_pci/Makefile
> >  create mode 100644 lib/librte_pci/include/rte_pci.h
> >  create mode 100644 lib/librte_pci/rte_pci.c
> >  create mode 100644 lib/librte_pci/rte_pci_version.map
> > 
> > diff --git a/lib/librte_pci/Makefile b/lib/librte_pci/Makefile
> > new file mode 100644
> > index 0000000..e3c6ca5
> > --- /dev/null
> > +++ b/lib/librte_pci/Makefile
> > @@ -0,0 +1,49 @@
> > +#   BSD LICENSE
> > +#
> > +#   Copyright(c) 2017 6WIND S.A.
> > +#   All rights reserved.
> > +#
> > +#   Redistribution and use in source and binary forms, with or
> > without
> > +#   modification, are permitted provided that the following
> > conditions
> > +#   are met:
> > +#
> > +#     * Redistributions of source code must retain the above
> > copyright
> > +#       notice, this list of conditions and the following
> > disclaimer.
> > +#     * Redistributions in binary form must reproduce the above
> > copyright
> > +#       notice, this list of conditions and the following disclaimer
> > in
> > +#       the documentation and/or other materials provided with the
> > +#       distribution.
> > +#     * Neither the name of 6WIND nor the names of its
> > +#       contributors may be used to endorse or promote products
> > derived
> > +#       from this software without specific prior written
> > permission.
> > +#
> > +#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> > CONTRIBUTORS
> > +#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
> > NOT
> > +#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
> > FITNESS FOR
> > +#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> > COPYRIGHT
> > +#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
> > INCIDENTAL,
> > +#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > +#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> > USE,
> > +#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> > ON ANY
> > +#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
> > TORT
> > +#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> > THE USE
> > +#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
> > DAMAGE.
> > +
> > +include $(RTE_SDK)/mk/rte.vars.mk
> > +
> > +# library name
> > +LIB = librte_pci.a
> > +
> > +CFLAGS += -O3
> > +CFLAGS += $(WERROR_FLAGS)
> > +CFLAGS += -I$(SRCDIR) -I$(SRCDIR)/include
> 
> This breaks build reproducibility, please use something like:
> 
> CFLAGS := -I$(SRCDIR)/include -I$(SRCDIR) $(CFLAGS)
> CFLAGS += $(WERROR_FLAGS) -O3
> 
> See http://dpdk.org/dev/patchwork/patch/27639/
> 

Sure, thanks for the heads up.

> -- 
> Kind regards,
> Luca Boccassi

-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH 01/13] eal: expose rte_eal_using_phys_addrs
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 01/13] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
@ 2017-09-04 13:24   ` Burakov, Anatoly
  0 siblings, 0 replies; 156+ messages in thread
From: Burakov, Anatoly @ 2017-09-04 13:24 UTC (permalink / raw)
  To: Gaetan Rivet, dev

Hi Gaetan,

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Gaetan Rivet
> Sent: Friday, August 25, 2017 10:04 AM
> To: dev@dpdk.org
> Cc: Gaetan Rivet <gaetan.rivet@6wind.com>
> Subject: [dpdk-dev] [PATCH 01/13] eal: expose rte_eal_using_phys_addrs
> 
> This function was previously private to the EAL layer.
> Other subsystems requires it, such as the PCI bus.
> 
> This function is only exposed for linuxapps.
> 
> In order not to force other components to include stdbool, which is
> incompatible with several NIC drivers, the return type has been changed
> from bool to int.
> 
> Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>

This probably should be moved to common API, and BSD should just implement a stub. Linuxapp-only externally visible API's are not allowed as far as I'm aware.

Thanks,
Anatoly

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL
  2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
                   ` (12 preceding siblings ...)
  2017-08-25  9:04 ` [dpdk-dev] [PATCH 13/13] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
@ 2017-09-18  9:31 ` Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 01/14] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
                     ` (15 more replies)
  13 siblings, 16 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet, Declan Doherty

Hi all,

Here is a new version of the PCI bus move out of the EAL.

The EAL PCI implementation is divided in two parts:

  - librte_pci: library offering helpers to handle PCI objects
  - librte_bus_pci: bus driver for PCI devices

This allows other libraries / tools to use PCI elements (location, mappings,
parsing operations, etc) without forcing a dependency on a bus driver.

The latter should not have to export helpers that others might need. It
is focused on defining the rte_pci_device, rte_pci_driver objects and
their handling.

The cryptodev library has hard dependencies on rte_pci_devices (used by
generic probe function). Other similar libs (ether and eventdev) avoided
the issue by inlining such functions and expecting users to include the
relevant headers once the PCI bus has already been built.

@Declan:
I proposed a solution that would avoid inlining those functions,
which does not feel right. Let me know what you think of it or if you
think of a better solution. I think it would be best to have cryptodev
completely independent from PCI / vdev as far as the lib in concerned
(the vdev bus will move as well).

v2:

  + Made rte_eal_using_phys_addrs common to both linux and bsd interfaces.
  + Added documentation of EAL API changes in release note.
  + Fixed a few rebase-related mistakes.
  + Fixed parallel build race condition reported by Luca Boccassi.
  + Grouped together commits breaking compilation:

    -> pci: introduce PCI lib and bus
    -> lib: include rte_bus_pci
    -> drivers: include rte_bus_pci
    -> test: include rte_bus_pci
    -> app/testpmd: include rte_bus_pci
    -> cryptodev: move PCI specific helpers to drivers/crypto

  Until all of them have been applied, compilation is broken.
  I am currently wondering whether merging some of them might
  be sensible.

  + Not included in this series:

    Several filesystem-related functions are currently
    private to the EAL and directly linked. This is not good,
    but the solution seems to be to have a new lib offering an FS abstraction.
    This seems an overreach for this patchset and should probably come in a
    second step.

Gaetan Rivet (14):
  eal: expose rte_eal_using_phys_addrs
  ethdev: remove useless PCI dependency
  bus: properly include rte_debug
  eal: remove references to PCI
  pci: introduce PCI lib and bus
  lib: include rte_bus_pci
  drivers: include rte_bus_pci
  test: include rte_bus_pci
  app/testpmd: include rte_bus_pci
  cryptodev: move PCI specific helpers to drivers/crypto
  pci: avoid inlining functions
  pci: avoid over-complicated macro
  pci: deprecate misnamed functions
  doc: add notes on EAL PCI API update

 app/test-pmd/testpmd.h                           |   1 +
 config/common_base                               |  10 +
 doc/guides/rel_notes/deprecation.rst             |  10 +
 doc/guides/rel_notes/release_17_11.rst           |  28 +
 drivers/Makefile                                 |   2 +-
 drivers/bus/Makefile                             |   2 +
 drivers/bus/pci/Makefile                         |  59 ++
 drivers/bus/pci/bsd/Makefile                     |  32 +
 drivers/bus/pci/bsd/rte_pci.c                    | 671 +++++++++++++++++++++
 drivers/bus/pci/include/rte_bus_pci.h            | 387 ++++++++++++
 drivers/bus/pci/linux/Makefile                   |  37 ++
 drivers/bus/pci/linux/rte_pci.c                  | 723 +++++++++++++++++++++++
 drivers/bus/pci/linux/rte_pci_init.h             |  97 +++
 drivers/bus/pci/linux/rte_pci_uio.c              | 568 ++++++++++++++++++
 drivers/bus/pci/linux/rte_pci_vfio.c             | 675 +++++++++++++++++++++
 drivers/bus/pci/linux/rte_vfio_mp_sync.c         | 425 +++++++++++++
 drivers/bus/pci/private.h                        | 174 ++++++
 drivers/bus/pci/rte_bus_pci_version.map          |  21 +
 drivers/bus/pci/rte_pci_common.c                 | 543 +++++++++++++++++
 drivers/bus/pci/rte_pci_common_uio.c             | 235 ++++++++
 drivers/crypto/Makefile                          |   4 +-
 drivers/crypto/pci/Makefile                      |  52 ++
 drivers/crypto/pci/rte_cryptodev_pci.c           | 128 ++++
 drivers/crypto/pci/rte_cryptodev_pci.h           |  94 +++
 drivers/crypto/pci/rte_cryptodev_pci_version.map |   7 +
 drivers/crypto/qat/qat_qp.c                      |   1 +
 drivers/event/octeontx/ssovf_probe.c             |   1 +
 drivers/net/ark/ark_ethdev.c                     |   1 +
 drivers/net/avp/avp_ethdev.c                     |   2 +
 drivers/net/bnxt/bnxt.h                          |   1 +
 drivers/net/bonding/rte_eth_bond_args.c          |   1 +
 drivers/net/cxgbe/base/adapter.h                 |   1 +
 drivers/net/cxgbe/cxgbe_ethdev.c                 |   1 +
 drivers/net/e1000/em_ethdev.c                    |   1 +
 drivers/net/e1000/igb_ethdev.c                   |   1 +
 drivers/net/e1000/igb_pf.c                       |   1 +
 drivers/net/ena/ena_ethdev.h                     |   1 +
 drivers/net/enic/base/vnic_dev.h                 |   4 +-
 drivers/net/enic/enic_ethdev.c                   |   1 +
 drivers/net/enic/enic_main.c                     |   1 +
 drivers/net/i40e/i40e_ethdev.c                   |   1 +
 drivers/net/i40e/i40e_ethdev_vf.c                |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c                 |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.h                 |   1 +
 drivers/net/mlx5/mlx5.c                          |   1 +
 drivers/net/mlx5/mlx5_ethdev.c                   |   1 +
 drivers/net/sfc/sfc.h                            |   1 +
 drivers/net/sfc/sfc_ethdev.c                     |   1 +
 drivers/net/thunderx/nicvf_ethdev.c              |   1 +
 drivers/net/virtio/virtio_ethdev.c               |   1 +
 drivers/net/virtio/virtio_pci.h                  |   1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c             |   1 +
 lib/Makefile                                     |   2 +
 lib/librte_cryptodev/Makefile                    |   1 -
 lib/librte_cryptodev/rte_cryptodev_pci.h         |  92 ---
 lib/librte_cryptodev/rte_cryptodev_pmd.c         |  94 ---
 lib/librte_cryptodev/rte_cryptodev_version.map   |   2 -
 lib/librte_eal/bsdapp/eal/Makefile               |   3 -
 lib/librte_eal/bsdapp/eal/eal.c                  |   1 -
 lib/librte_eal/bsdapp/eal/eal_memory.c           |   6 +
 lib/librte_eal/bsdapp/eal/eal_pci.c              | 670 ---------------------
 lib/librte_eal/bsdapp/eal/rte_eal_version.map    |  16 +-
 lib/librte_eal/common/Makefile                   |   2 +-
 lib/librte_eal/common/eal_common_bus.c           |   1 +
 lib/librte_eal/common/eal_common_pci.c           | 580 ------------------
 lib/librte_eal/common/eal_common_pci_uio.c       | 233 --------
 lib/librte_eal/common/eal_private.h              | 143 -----
 lib/librte_eal/common/include/rte_memory.h       |  11 +
 lib/librte_eal/common/include/rte_pci.h          | 598 -------------------
 lib/librte_eal/linuxapp/eal/Makefile             |  10 -
 lib/librte_eal/linuxapp/eal/eal.c                |   1 -
 lib/librte_eal/linuxapp/eal/eal_interrupts.c     |   1 -
 lib/librte_eal/linuxapp/eal/eal_memory.c         |   2 +-
 lib/librte_eal/linuxapp/eal/eal_pci.c            | 722 ----------------------
 lib/librte_eal/linuxapp/eal/eal_pci_init.h       |  97 ---
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c        | 567 ------------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c       | 674 ---------------------
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c   | 424 -------------
 lib/librte_eal/linuxapp/eal/rte_eal_version.map  |  16 +-
 lib/librte_ether/rte_ethdev.c                    |   1 -
 lib/librte_ether/rte_ethdev.h                    |   2 -
 lib/librte_ether/rte_ethdev_pci.h                |   1 +
 lib/librte_eventdev/rte_eventdev_pmd_pci.h       |   1 +
 lib/librte_pci/Makefile                          |  48 ++
 lib/librte_pci/include/rte_pci.h                 | 285 +++++++++
 lib/librte_pci/rte_pci.c                         | 210 +++++++
 lib/librte_pci/rte_pci_version.map               |  16 +
 mk/rte.app.mk                                    |   3 +
 test/test/test_kni.c                             |   1 +
 test/test/virtual_pmd.c                          |   1 +
 90 files changed, 5603 insertions(+), 4951 deletions(-)
 create mode 100644 drivers/bus/pci/Makefile
 create mode 100644 drivers/bus/pci/bsd/Makefile
 create mode 100644 drivers/bus/pci/bsd/rte_pci.c
 create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
 create mode 100644 drivers/bus/pci/linux/Makefile
 create mode 100644 drivers/bus/pci/linux/rte_pci.c
 create mode 100644 drivers/bus/pci/linux/rte_pci_init.h
 create mode 100644 drivers/bus/pci/linux/rte_pci_uio.c
 create mode 100644 drivers/bus/pci/linux/rte_pci_vfio.c
 create mode 100644 drivers/bus/pci/linux/rte_vfio_mp_sync.c
 create mode 100644 drivers/bus/pci/private.h
 create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
 create mode 100644 drivers/bus/pci/rte_pci_common.c
 create mode 100644 drivers/bus/pci/rte_pci_common_uio.c
 create mode 100644 drivers/crypto/pci/Makefile
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.c
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.h
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci_version.map
 delete mode 100644 lib/librte_cryptodev/rte_cryptodev_pci.h
 delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
 delete mode 100644 lib/librte_eal/common/include/rte_pci.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
 create mode 100644 lib/librte_pci/Makefile
 create mode 100644 lib/librte_pci/include/rte_pci.h
 create mode 100644 lib/librte_pci/rte_pci.c
 create mode 100644 lib/librte_pci/rte_pci_version.map

-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 01/14] eal: expose rte_eal_using_phys_addrs
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
@ 2017-09-18  9:31   ` Gaetan Rivet
  2017-09-18 10:47     ` Shreyansh Jain
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 02/14] ethdev: remove useless PCI dependency Gaetan Rivet
                     ` (14 subsequent siblings)
  15 siblings, 1 reply; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

This function was previously private to the EAL layer.
Other subsystems requires it, such as the PCI bus.

In order not to force other components to include stdbool, which is
incompatible with several NIC drivers, the return type has
been changed from bool to int.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/bsdapp/eal/eal_memory.c          |  6 ++++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  1 +
 lib/librte_eal/common/eal_private.h             | 11 -----------
 lib/librte_eal/common/include/rte_memory.h      | 11 +++++++++++
 lib/librte_eal/linuxapp/eal/eal_memory.c        |  2 +-
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  1 +
 6 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal_memory.c b/lib/librte_eal/bsdapp/eal/eal_memory.c
index 3614da8..65c96b0 100644
--- a/lib/librte_eal/bsdapp/eal/eal_memory.c
+++ b/lib/librte_eal/bsdapp/eal/eal_memory.c
@@ -192,3 +192,9 @@ rte_eal_hugepage_attach(void)
 		close(fd_hugepage);
 	return -1;
 }
+
+int
+rte_eal_using_phys_addrs(void)
+{
+	return 0;
+}
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 47a09ea..cff7d18 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -200,6 +200,7 @@ DPDK_17.08 {
 	rte_bus_find;
 	rte_bus_find_by_device;
 	rte_bus_find_by_name;
+	rte_eal_using_phys_addrs;
 	rte_log_get_level;
 
 } DPDK_17.05;
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 597d82e..10a7078 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -333,17 +333,6 @@ int rte_eal_hugepage_init(void);
 int rte_eal_hugepage_attach(void);
 
 /**
- * Returns true if the system is able to obtain
- * physical addresses. Return false if using DMA
- * addresses through an IOMMU.
- *
- * Drivers based on uio will not load unless physical
- * addresses are obtainable. It is only possible to get
- * physical addresses when running as a privileged user.
- */
-bool rte_eal_using_phys_addrs(void);
-
-/**
  * Find a bus capable of identifying a device.
  *
  * @param str
diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h
index 4aa5d1f..5568931 100644
--- a/lib/librte_eal/common/include/rte_memory.h
+++ b/lib/librte_eal/common/include/rte_memory.h
@@ -195,6 +195,17 @@ unsigned rte_memory_get_nchannel(void);
  */
 unsigned rte_memory_get_nrank(void);
 
+/**
+ * Drivers based on uio will not load unless physical
+ * addresses are obtainable. It is only possible to get
+ * physical addresses when running as a privileged user.
+ *
+ * @return
+ *   1 if the system is able to obtain physical addresses.
+ *   0 if using DMA addresses through an IOMMU.
+ */
+int rte_eal_using_phys_addrs(void);
+
 #ifdef RTE_LIBRTE_XEN_DOM0
 
 /**< Internal use only - should DOM0 memory mapping be used */
diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
index 5279128..af8719b 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -1542,7 +1542,7 @@ rte_eal_hugepage_attach(void)
 	return -1;
 }
 
-bool
+int
 rte_eal_using_phys_addrs(void)
 {
 	return phys_addrs_available;
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 8c08b8d..f866b70 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -205,6 +205,7 @@ DPDK_17.08 {
 	rte_bus_find;
 	rte_bus_find_by_device;
 	rte_bus_find_by_name;
+	rte_eal_using_phys_addrs;
 	rte_log_get_level;
 
 } DPDK_17.05;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 02/14] ethdev: remove useless PCI dependency
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 01/14] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
@ 2017-09-18  9:31   ` Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 03/14] bus: properly include rte_debug Gaetan Rivet
                     ` (13 subsequent siblings)
  15 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ether/rte_ethdev.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a88916f..c5b0b17 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -47,7 +47,6 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_interrupts.h>
-#include <rte_pci.h>
 #include <rte_memory.h>
 #include <rte_memcpy.h>
 #include <rte_memzone.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 03/14] bus: properly include rte_debug
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 01/14] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 02/14] ethdev: remove useless PCI dependency Gaetan Rivet
@ 2017-09-18  9:31   ` Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 04/14] eal: remove references to PCI Gaetan Rivet
                     ` (12 subsequent siblings)
  15 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_bus.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
index 08bec2d..9d1be8a 100644
--- a/lib/librte_eal/common/eal_common_bus.c
+++ b/lib/librte_eal/common/eal_common_bus.c
@@ -35,6 +35,7 @@
 #include <sys/queue.h>
 
 #include <rte_bus.h>
+#include <rte_debug.h>
 
 #include "eal_private.h"
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 04/14] eal: remove references to PCI
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
                     ` (2 preceding siblings ...)
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 03/14] bus: properly include rte_debug Gaetan Rivet
@ 2017-09-18  9:31   ` Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 05/14] pci: introduce PCI lib and bus Gaetan Rivet
                     ` (11 subsequent siblings)
  15 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/bsdapp/eal/eal.c              |   1 -
 lib/librte_eal/common/eal_private.h          | 132 ---------------------------
 lib/librte_eal/linuxapp/eal/eal.c            |   1 -
 lib/librte_eal/linuxapp/eal/eal_interrupts.c |   1 -
 4 files changed, 135 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 5fa5988..b7c045f 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -66,7 +66,6 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_bus.h>
-#include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_version.h>
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 10a7078..fc504ef 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,7 +36,6 @@
 
 #include <stdbool.h>
 #include <stdio.h>
-#include <rte_pci.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -109,137 +108,6 @@ int rte_eal_timer_init(void);
  */
 int rte_eal_log_init(const char *id, int facility);
 
-struct rte_pci_driver;
-struct rte_pci_device;
-
-/**
- * Find the name of a PCI device.
- */
-void pci_name_set(struct rte_pci_device *dev);
-
-/**
- * Add a PCI device to the PCI Bus (append to PCI Device list). This function
- * also updates the bus references of the PCI Device (and the generic device
- * object embedded within.
- *
- * @param pci_dev
- *	PCI device to add
- * @return void
- */
-void rte_pci_add_device(struct rte_pci_device *pci_dev);
-
-/**
- * Insert a PCI device in the PCI Bus at a particular location in the device
- * list. It also updates the PCI Bus reference of the new devices to be
- * inserted.
- *
- * @param exist_pci_dev
- *	Existing PCI device in PCI Bus
- * @param new_pci_dev
- *	PCI device to be added before exist_pci_dev
- * @return void
- */
-void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
-		struct rte_pci_device *new_pci_dev);
-
-/**
- * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
- * in the PCI device object as well as the generic device object.
- *
- * @param pci_device
- *	PCI device to be removed from PCI Bus
- * @return void
- */
-void rte_pci_remove_device(struct rte_pci_device *pci_device);
-
-/**
- * Update a pci device object by asking the kernel for the latest information.
- *
- * This function is private to EAL.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to look for
- * @return
- *   - 0 on success.
- *   - negative on error.
- */
-int pci_update_device(const struct rte_pci_addr *addr);
-
-/**
- * Unbind kernel driver for this device
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int pci_unbind_kernel_driver(struct rte_pci_device *dev);
-
-/**
- * Map the PCI resource of a PCI device in virtual memory
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_map_resource(struct rte_pci_device *dev);
-
-/**
- * Unmap the PCI resource of a PCI device
- *
- * This function is private to EAL.
- */
-void pci_uio_unmap_resource(struct rte_pci_device *dev);
-
-/**
- * Allocate uio resource for PCI device
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device to allocate uio resource
- * @param uio_res
- *   Pointer to uio resource.
- *   If the function returns 0, the pointer will be filled.
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res);
-
-/**
- * Free uio resource for PCI device
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device to free uio resource
- * @param uio_res
- *   Pointer to uio resource.
- */
-void pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res);
-
-/**
- * Map device memory to uio resource
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device that has memory information.
- * @param res_idx
- *   Memory resource index of the PCI device.
- * @param uio_res
- *  uio resource that will keep mapping information.
- * @param map_idx
- *   Mapping information index of the uio resource.
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx);
-
 /**
  * Init tail queues for non-EAL library structures. This is to allow
  * the rings, mempools, etc. lists to be shared among multiple processes
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 48f12f4..f72da15 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -71,7 +71,6 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_bus.h>
-#include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_version.h>
diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
index 3e9ac41..0bebf00 100644
--- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
@@ -60,7 +60,6 @@
 #include <rte_branch_prediction.h>
 #include <rte_debug.h>
 #include <rte_log.h>
-#include <rte_pci.h>
 #include <rte_malloc.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 05/14] pci: introduce PCI lib and bus
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
                     ` (3 preceding siblings ...)
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 04/14] eal: remove references to PCI Gaetan Rivet
@ 2017-09-18  9:31   ` Gaetan Rivet
  2017-09-18 11:53     ` Shreyansh Jain
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 06/14] lib: include rte_bus_pci Gaetan Rivet
                     ` (10 subsequent siblings)
  15 siblings, 1 reply; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

The PCI lib defines the types and methods allowing to use PCI elements.

The PCI bus implements a bus driver for PCI devices by constructing
rte_bus elements using the PCI lib.

Move the relevant code out of the EAL to their expected place.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 config/common_base                              |  10 +
 drivers/bus/Makefile                            |   2 +
 drivers/bus/pci/Makefile                        |  59 ++
 drivers/bus/pci/bsd/Makefile                    |  32 ++
 drivers/bus/pci/bsd/rte_pci.c                   | 670 ++++++++++++++++++++++
 drivers/bus/pci/include/rte_bus_pci.h           | 387 +++++++++++++
 drivers/bus/pci/linux/Makefile                  |  37 ++
 drivers/bus/pci/linux/rte_pci.c                 | 722 ++++++++++++++++++++++++
 drivers/bus/pci/linux/rte_pci_init.h            |  97 ++++
 drivers/bus/pci/linux/rte_pci_uio.c             | 567 +++++++++++++++++++
 drivers/bus/pci/linux/rte_pci_vfio.c            | 674 ++++++++++++++++++++++
 drivers/bus/pci/linux/rte_vfio_mp_sync.c        | 424 ++++++++++++++
 drivers/bus/pci/private.h                       | 173 ++++++
 drivers/bus/pci/rte_bus_pci_version.map         |  21 +
 drivers/bus/pci/rte_pci_common.c                | 542 ++++++++++++++++++
 drivers/bus/pci/rte_pci_common_uio.c            | 234 ++++++++
 lib/Makefile                                    |   2 +
 lib/librte_eal/bsdapp/eal/Makefile              |   3 -
 lib/librte_eal/bsdapp/eal/eal_pci.c             | 670 ----------------------
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  15 -
 lib/librte_eal/common/Makefile                  |   2 +-
 lib/librte_eal/common/eal_common_pci.c          | 580 -------------------
 lib/librte_eal/common/eal_common_pci_uio.c      | 233 --------
 lib/librte_eal/common/include/rte_pci.h         | 598 --------------------
 lib/librte_eal/linuxapp/eal/Makefile            |  10 -
 lib/librte_eal/linuxapp/eal/eal_pci.c           | 722 ------------------------
 lib/librte_eal/linuxapp/eal/eal_pci_init.h      |  97 ----
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c       | 567 -------------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c      | 674 ----------------------
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c  | 424 --------------
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  15 -
 lib/librte_ether/rte_ethdev.h                   |   2 -
 lib/librte_pci/Makefile                         |  48 ++
 lib/librte_pci/include/rte_pci.h                | 279 +++++++++
 lib/librte_pci/rte_pci.c                        |  92 +++
 lib/librte_pci/rte_pci_version.map              |   8 +
 mk/rte.app.mk                                   |   3 +
 37 files changed, 5084 insertions(+), 4611 deletions(-)
 create mode 100644 drivers/bus/pci/Makefile
 create mode 100644 drivers/bus/pci/bsd/Makefile
 create mode 100644 drivers/bus/pci/bsd/rte_pci.c
 create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
 create mode 100644 drivers/bus/pci/linux/Makefile
 create mode 100644 drivers/bus/pci/linux/rte_pci.c
 create mode 100644 drivers/bus/pci/linux/rte_pci_init.h
 create mode 100644 drivers/bus/pci/linux/rte_pci_uio.c
 create mode 100644 drivers/bus/pci/linux/rte_pci_vfio.c
 create mode 100644 drivers/bus/pci/linux/rte_vfio_mp_sync.c
 create mode 100644 drivers/bus/pci/private.h
 create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
 create mode 100644 drivers/bus/pci/rte_pci_common.c
 create mode 100644 drivers/bus/pci/rte_pci_common_uio.c
 delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
 delete mode 100644 lib/librte_eal/common/include/rte_pci.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
 create mode 100644 lib/librte_pci/Makefile
 create mode 100644 lib/librte_pci/include/rte_pci.h
 create mode 100644 lib/librte_pci/rte_pci.c
 create mode 100644 lib/librte_pci/rte_pci_version.map

diff --git a/config/common_base b/config/common_base
index 5e97a08..08db392 100644
--- a/config/common_base
+++ b/config/common_base
@@ -122,6 +122,11 @@ CONFIG_RTE_EAL_PMD_PATH=""
 CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
 
 #
+# Compile the PCI library
+#
+CONFIG_RTE_LIBRTE_PCI=y
+
+#
 # Compile the argument parser library
 #
 CONFIG_RTE_LIBRTE_KVARGS=y
@@ -146,6 +151,11 @@ CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
 CONFIG_RTE_ETHDEV_TX_PREPARE_NOOP=n
 
 #
+# Compile PCI bus driver
+#
+CONFIG_RTE_LIBRTE_PCI_BUS=y
+
+#
 # Compile burst-oriented Amazon ENA PMD driver
 #
 CONFIG_RTE_LIBRTE_ENA_PMD=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 0224214..4b5bafe 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -34,5 +34,7 @@ core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
 
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DEPDIRS-fslmc = $(core-libs)
+DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
+DEPDIRS-pci = $(core-libs)
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/pci/Makefile b/drivers/bus/pci/Makefile
new file mode 100644
index 0000000..7365925
--- /dev/null
+++ b/drivers/bus/pci/Makefile
@@ -0,0 +1,59 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+LIB = librte_bus_pci.a
+LIBABIVER := 1
+EXPORT_MAP := rte_bus_pci_version.map
+
+CFLAGS := -I$(SRCDIR)/include -I$(SRCDIR) $(CFLAGS)
+CFLAGS += -O3 $(WERROR_FLAGS)
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),)
+SYSTEM := linux
+endif
+ifneq ($(CONFIG_RTE_EXEC_ENV_BSDAPP),)
+SYSTEM := bsd
+endif
+
+CFLAGS += -I$(RTE_SDK)/drivers/bus/pci/$(SYSTEM)
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/$(SYSTEM)app/eal
+
+include $(RTE_SDK)/drivers/bus/pci/$(SYSTEM)/Makefile
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) := $(addprefix $(SYSTEM)/,$(SRCS))
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += rte_pci_common.c
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += rte_pci_common_uio.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI_BUS)-include += include/rte_bus_pci.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/pci/bsd/Makefile b/drivers/bus/pci/bsd/Makefile
new file mode 100644
index 0000000..77cf539
--- /dev/null
+++ b/drivers/bus/pci/bsd/Makefile
@@ -0,0 +1,32 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += rte_pci.c
diff --git a/drivers/bus/pci/bsd/rte_pci.c b/drivers/bus/pci/bsd/rte_pci.c
new file mode 100644
index 0000000..5bd0f4b
--- /dev/null
+++ b/drivers/bus/pci/bsd/rte_pci.c
@@ -0,0 +1,670 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/pciio.h>
+#include <dev/pci/pcireg.h>
+
+#if defined(RTE_ARCH_X86)
+#include <machine/cpufunc.h>
+#endif
+
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_common.h>
+#include <rte_launch.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+#include <rte_debug.h>
+#include <rte_devargs.h>
+
+#include "eal_filesystem.h"
+#include "private.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in
+ * sysfs. Moreover, when a registered driver matches a device, the
+ * kernel driver currently using it is unloaded and replaced by
+ * igb_uio module, which is a very minimal userland driver for Intel
+ * network card, only providing access to PCI BAR to applications, and
+ * enabling bus master.
+ */
+
+extern struct rte_pci_bus rte_pci_bus;
+
+/* Map pci device */
+int
+rte_pci_map_device(struct rte_pci_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources */
+	switch (dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		/* map resources for devices that use uio */
+		ret = pci_uio_map_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+/* Unmap pci device */
+void
+rte_pci_unmap_device(struct rte_pci_device *dev)
+{
+	/* try unmapping the NIC resources */
+	switch (dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		/* unmap resources for devices that use uio */
+		pci_uio_unmap_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+void
+pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res)
+{
+	rte_free(uio_res);
+
+	if (dev->intr_handle.fd) {
+		close(dev->intr_handle.fd);
+		dev->intr_handle.fd = -1;
+		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	}
+}
+
+int
+pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res)
+{
+	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+
+	snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
+			dev->addr.bus, dev->addr.devid, dev->addr.function);
+
+	if (access(devname, O_RDWR) < 0) {
+		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+		return 1;
+	}
+
+	/* save fd if in primary process */
+	dev->intr_handle.fd = open(devname, O_RDWR);
+	if (dev->intr_handle.fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			devname, strerror(errno));
+		goto error;
+	}
+	dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+
+	/* allocate the mapping details for secondary processes*/
+	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
+	if (*uio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto error;
+	}
+
+	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
+	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
+
+	return 0;
+
+error:
+	pci_uio_free_resource(dev, *uio_res);
+	return -1;
+}
+
+int
+pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx)
+{
+	int fd;
+	char *devname;
+	void *mapaddr;
+	uint64_t offset;
+	uint64_t pagesz;
+	struct pci_map *maps;
+
+	maps = uio_res->maps;
+	devname = uio_res->path;
+	pagesz = sysconf(_SC_PAGESIZE);
+
+	/* allocate memory to keep path */
+	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+	if (maps[map_idx].path == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+				strerror(errno));
+		return -1;
+	}
+
+	/*
+	 * open resource file, to mmap it
+	 */
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				devname, strerror(errno));
+		goto error;
+	}
+
+	/* if matching map is found, then use it */
+	offset = res_idx * pagesz;
+	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
+			(size_t)dev->mem_resource[res_idx].len, 0);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		goto error;
+
+	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+	maps[map_idx].size = dev->mem_resource[res_idx].len;
+	maps[map_idx].addr = mapaddr;
+	maps[map_idx].offset = offset;
+	strcpy(maps[map_idx].path, devname);
+	dev->mem_resource[res_idx].addr = mapaddr;
+
+	return 0;
+
+error:
+	rte_free(maps[map_idx].path);
+	return -1;
+}
+
+static int
+pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
+{
+	struct rte_pci_device *dev;
+	struct pci_bar_io bar;
+	unsigned i, max;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL) {
+		return -1;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr.domain = conf->pc_sel.pc_domain;
+	dev->addr.bus = conf->pc_sel.pc_bus;
+	dev->addr.devid = conf->pc_sel.pc_dev;
+	dev->addr.function = conf->pc_sel.pc_func;
+
+	/* get vendor id */
+	dev->id.vendor_id = conf->pc_vendor;
+
+	/* get device id */
+	dev->id.device_id = conf->pc_device;
+
+	/* get subsystem_vendor id */
+	dev->id.subsystem_vendor_id = conf->pc_subvendor;
+
+	/* get subsystem_device id */
+	dev->id.subsystem_device_id = conf->pc_subdevice;
+
+	/* get class id */
+	dev->id.class_id = (conf->pc_class << 16) |
+			   (conf->pc_subclass << 8) |
+			   (conf->pc_progif);
+
+	/* TODO: get max_vfs */
+	dev->max_vfs = 0;
+
+	/* FreeBSD has no NUMA support (yet) */
+	dev->device.numa_node = 0;
+
+	pci_name_set(dev);
+
+	/* FreeBSD has only one pass through driver */
+	dev->kdrv = RTE_KDRV_NIC_UIO;
+
+	/* parse resources */
+	switch (conf->pc_hdr & PCIM_HDRTYPE) {
+	case PCIM_HDRTYPE_NORMAL:
+		max = PCIR_MAX_BAR_0;
+		break;
+	case PCIM_HDRTYPE_BRIDGE:
+		max = PCIR_MAX_BAR_1;
+		break;
+	case PCIM_HDRTYPE_CARDBUS:
+		max = PCIR_MAX_BAR_2;
+		break;
+	default:
+		goto skipdev;
+	}
+
+	for (i = 0; i <= max; i++) {
+		bar.pbi_sel = conf->pc_sel;
+		bar.pbi_reg = PCIR_BAR(i);
+		if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
+			continue;
+
+		dev->mem_resource[i].len = bar.pbi_length;
+		if (PCI_BAR_IO(bar.pbi_base)) {
+			dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
+			continue;
+		}
+		dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
+	}
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
+		rte_pci_add_device(dev);
+	}
+	else {
+		struct rte_pci_device *dev2 = NULL;
+		int ret;
+
+		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
+			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+			else if (ret < 0) {
+				rte_pci_insert_device(dev2, dev);
+			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->max_vfs = dev->max_vfs;
+				pci_name_set(dev2);
+				memmove(dev2->mem_resource,
+					dev->mem_resource,
+					sizeof(dev->mem_resource));
+				free(dev);
+			}
+			return 0;
+		}
+		rte_pci_add_device(dev);
+	}
+
+	return 0;
+
+skipdev:
+	free(dev);
+	return 0;
+}
+
+/*
+ * Scan the content of the PCI bus, and add the devices in the devices
+ * list. Call pci_scan_one() for each pci entry found.
+ */
+int
+rte_pci_scan(void)
+{
+	int fd;
+	unsigned dev_count = 0;
+	struct pci_conf matches[16];
+	struct pci_conf_io conf_io = {
+			.pat_buf_len = 0,
+			.num_patterns = 0,
+			.patterns = NULL,
+			.match_buf_len = sizeof(matches),
+			.matches = &matches[0],
+	};
+
+	/* for debug purposes, PCI can be disabled */
+	if (internal_config.no_pci)
+		return 0;
+
+	fd = open("/dev/pci", O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	do {
+		unsigned i;
+		if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+			RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+					__func__, strerror(errno));
+			goto error;
+		}
+
+		for (i = 0; i < conf_io.num_matches; i++)
+			if (pci_scan_one(fd, &matches[i]) < 0)
+				goto error;
+
+		dev_count += conf_io.num_matches;
+	} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
+
+	close(fd);
+
+	RTE_LOG(DEBUG, EAL, "PCI scan found %u devices\n", dev_count);
+	return 0;
+
+error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+	int fd;
+	struct pci_conf matches[2];
+	struct pci_match_conf match = {
+		.pc_sel = {
+			.pc_domain = addr->domain,
+			.pc_bus = addr->bus,
+			.pc_dev = addr->devid,
+			.pc_func = addr->function,
+		},
+	};
+	struct pci_conf_io conf_io = {
+		.pat_buf_len = 0,
+		.num_patterns = 1,
+		.patterns = &match,
+		.match_buf_len = sizeof(matches),
+		.matches = &matches[0],
+	};
+
+	fd = open("/dev/pci", O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+				__func__, strerror(errno));
+		goto error;
+	}
+
+	if (conf_io.num_matches != 1)
+		goto error;
+
+	if (pci_scan_one(fd, &matches[0]) < 0)
+		goto error;
+
+	close(fd);
+
+	return 0;
+
+error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/* Read PCI config space. */
+int rte_pci_read_config(const struct rte_pci_device *dev,
+		void *buf, size_t len, off_t offset)
+{
+	int fd = -1;
+	int size;
+	struct pci_io pi = {
+		.pi_sel = {
+			.pc_domain = dev->addr.domain,
+			.pc_bus = dev->addr.bus,
+			.pc_dev = dev->addr.devid,
+			.pc_func = dev->addr.function,
+		},
+		.pi_reg = offset,
+	};
+
+	fd = open("/dev/pci", O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	while (len > 0) {
+		size = (len >= 4) ? 4 : ((len >= 2) ? 2 : 1);
+		pi.pi_width = size;
+
+		if (ioctl(fd, PCIOCREAD, &pi) < 0)
+			goto error;
+		memcpy(buf, &pi.pi_data, size);
+
+		buf = (char *)buf + size;
+		pi.pi_reg += size;
+		len -= size;
+	}
+	close(fd);
+
+	return 0;
+
+ error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/* Write PCI config space. */
+int rte_pci_write_config(const struct rte_pci_device *dev,
+		const void *buf, size_t len, off_t offset)
+{
+	int fd = -1;
+
+	struct pci_io pi = {
+		.pi_sel = {
+			.pc_domain = dev->addr.domain,
+			.pc_bus = dev->addr.bus,
+			.pc_dev = dev->addr.devid,
+			.pc_func = dev->addr.function,
+		},
+		.pi_reg = offset,
+		.pi_data = *(const uint32_t *)buf,
+		.pi_width = len,
+	};
+
+	if (len == 3 || len > sizeof(pi.pi_data)) {
+		RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__);
+		goto error;
+	}
+
+	memcpy(&pi.pi_data, buf, len);
+
+	fd = open("/dev/pci", O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	if (ioctl(fd, PCIOCWRITE, &pi) < 0)
+		goto error;
+
+	close(fd);
+	return 0;
+
+ error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+int
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p)
+{
+	int ret;
+
+	switch (dev->kdrv) {
+#if defined(RTE_ARCH_X86)
+	case RTE_KDRV_NIC_UIO:
+		if ((uintptr_t) dev->mem_resource[bar].addr <= UINT16_MAX) {
+			p->base = (uintptr_t)dev->mem_resource[bar].addr;
+			ret = 0;
+		} else
+			ret = -1;
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	if (!ret)
+		p->dev = dev;
+
+	return ret;
+}
+
+static void
+pci_uio_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+#if defined(RTE_ARCH_X86)
+	uint8_t *d;
+	int size;
+	unsigned short reg = p->base + offset;
+
+	for (d = data; len > 0; d += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+			*(uint32_t *)d = inl(reg);
+		} else if (len >= 2) {
+			size = 2;
+			*(uint16_t *)d = inw(reg);
+		} else {
+			size = 1;
+			*d = inb(reg);
+		}
+	}
+#else
+	RTE_SET_USED(p);
+	RTE_SET_USED(data);
+	RTE_SET_USED(len);
+	RTE_SET_USED(offset);
+#endif
+}
+
+void
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+pci_uio_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+#if defined(RTE_ARCH_X86)
+	const uint8_t *s;
+	int size;
+	unsigned short reg = p->base + offset;
+
+	for (s = data; len > 0; s += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+			outl(reg, *(const uint32_t *)s);
+		} else if (len >= 2) {
+			size = 2;
+			outw(reg, *(const uint16_t *)s);
+		} else {
+			size = 1;
+			outb(reg, *s);
+		}
+	}
+#else
+	RTE_SET_USED(p);
+	RTE_SET_USED(data);
+	RTE_SET_USED(len);
+	RTE_SET_USED(offset);
+#endif
+}
+
+void
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	default:
+		break;
+	}
+}
+
+int
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
+{
+	int ret;
+
+	switch (p->dev->kdrv) {
+#if defined(RTE_ARCH_X86)
+	case RTE_KDRV_NIC_UIO:
+		ret = 0;
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/bus/pci/include/rte_bus_pci.h b/drivers/bus/pci/include/rte_bus_pci.h
new file mode 100644
index 0000000..b05dbf9
--- /dev/null
+++ b/drivers/bus/pci/include/rte_bus_pci.h
@@ -0,0 +1,387 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_BUS_PCI_H_
+#define _RTE_BUS_PCI_H_
+
+/**
+ * @file
+ *
+ * RTE PCI Bus Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+
+/** Pathname of PCI devices directory. */
+const char *pci_get_sysfs_path(void);
+
+/* Forward declarations */
+struct rte_pci_device;
+struct rte_pci_driver;
+
+/** List of PCI devices */
+TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
+/** List of PCI drivers */
+TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
+
+/* PCI Bus iterators */
+#define FOREACH_DEVICE_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
+
+#define FOREACH_DRIVER_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
+
+struct rte_devargs;
+
+/**
+ * A structure describing a PCI device.
+ */
+struct rte_pci_device {
+	TAILQ_ENTRY(rte_pci_device) next;   /**< Next probed PCI device. */
+	struct rte_device device;           /**< Inherit core device */
+	struct rte_pci_addr addr;           /**< PCI location. */
+	struct rte_pci_id id;               /**< PCI ID. */
+	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
+					    /**< PCI Memory Resource */
+	struct rte_intr_handle intr_handle; /**< Interrupt handle */
+	struct rte_pci_driver *driver;      /**< Associated driver */
+	uint16_t max_vfs;                   /**< sriov enable if not zero */
+	enum rte_kernel_driver kdrv;        /**< Kernel driver passthrough */
+	char name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_pci_device.
+ */
+#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
+
+#define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
+
+/** Any PCI device identifier (vendor, device, ...) */
+#define PCI_ANY_ID (0xffff)
+#define RTE_CLASS_ANY_ID (0xffffff)
+
+#ifdef __cplusplus
+/** C++ macro used to help building up tables of device IDs */
+#define RTE_PCI_DEVICE(vend, dev) \
+	RTE_CLASS_ANY_ID,         \
+	(vend),                   \
+	(dev),                    \
+	PCI_ANY_ID,               \
+	PCI_ANY_ID
+#else
+/** Macro used to help building up tables of device IDs */
+#define RTE_PCI_DEVICE(vend, dev)          \
+	.class_id = RTE_CLASS_ANY_ID,      \
+	.vendor_id = (vend),               \
+	.device_id = (dev),                \
+	.subsystem_vendor_id = PCI_ANY_ID, \
+	.subsystem_device_id = PCI_ANY_ID
+#endif
+
+/**
+ * Initialisation function for the driver called during PCI probing.
+ */
+typedef int (pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
+
+/**
+ * Uninitialisation function for the driver called during hotplugging.
+ */
+typedef int (pci_remove_t)(struct rte_pci_device *);
+
+/**
+ * A structure describing a PCI driver.
+ */
+struct rte_pci_driver {
+	TAILQ_ENTRY(rte_pci_driver) next;  /**< Next in list. */
+	struct rte_driver driver;          /**< Inherit core driver. */
+	struct rte_pci_bus *bus;           /**< PCI bus reference. */
+	pci_probe_t *probe;                /**< Device Probe function. */
+	pci_remove_t *remove;              /**< Device Remove function. */
+	const struct rte_pci_id *id_table; /**< ID table, NULL terminated. */
+	uint32_t drv_flags;                /**< Flags contolling handling of device. */
+};
+
+/**
+ * Structure describing the PCI bus
+ */
+struct rte_pci_bus {
+	struct rte_bus bus;               /**< Inherit the generic class */
+	struct rte_pci_device_list device_list;  /**< List of PCI devices */
+	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
+};
+
+/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
+#define RTE_PCI_DRV_NEED_MAPPING 0x0001
+/** Device driver supports link state interrupt */
+#define RTE_PCI_DRV_INTR_LSC	0x0008
+/** Device driver supports device removal interrupt */
+#define RTE_PCI_DRV_INTR_RMV 0x0010
+/** Device driver needs to keep mapped resources if unsupported dev detected */
+#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
+
+/**
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ *
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_pci_scan(void);
+
+/**
+ * Probe the PCI bus
+ *
+ * @return
+ *   - 0 on success.
+ *   - !0 on error.
+ */
+int
+rte_pci_probe(void);
+
+/**
+ * Map the PCI device resources in user space virtual memory address
+ *
+ * Note that driver should not call this function when flag
+ * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for
+ * you when it's on.
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ *
+ * @return
+ *   0 on success, negative on error and positive if no driver
+ *   is found for the device.
+ */
+int rte_pci_map_device(struct rte_pci_device *dev);
+
+/**
+ * Unmap this device
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ */
+void rte_pci_unmap_device(struct rte_pci_device *dev);
+
+/**
+ * Probe the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the probe() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to probe.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_probe_one(const struct rte_pci_addr *addr);
+
+/**
+ * Close the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the remove() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_detach(const struct rte_pci_addr *addr);
+
+/**
+ * Dump the content of the PCI bus.
+ *
+ * @param f
+ *   A pointer to a file for output
+ */
+void rte_pci_dump(FILE *f);
+
+/**
+ * Register a PCI driver.
+ *
+ * @param driver
+ *   A pointer to a rte_pci_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_pci_register(struct rte_pci_driver *driver);
+
+/** Helper for PCI device registration from driver (eth, crypto) instance */
+#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
+RTE_INIT(pciinitfn_ ##nm); \
+static void pciinitfn_ ##nm(void) \
+{\
+	(pci_drv).driver.name = RTE_STR(nm);\
+	rte_pci_register(&pci_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a PCI driver.
+ *
+ * @param driver
+ *   A pointer to a rte_pci_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_pci_unregister(struct rte_pci_driver *driver);
+
+/**
+ * Read PCI config space.
+ *
+ * @param device
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ * @param buf
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into PCI config space
+ */
+int rte_pci_read_config(const struct rte_pci_device *device,
+		void *buf, size_t len, off_t offset);
+
+/**
+ * Write PCI config space.
+ *
+ * @param device
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ * @param buf
+ *   A data buffer containing the bytes should be written
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into PCI config space
+ */
+int rte_pci_write_config(const struct rte_pci_device *device,
+		const void *buf, size_t len, off_t offset);
+
+/**
+ * A structure used to access io resources for a pci device.
+ * rte_pci_ioport is arch, os, driver specific, and should not be used outside
+ * of pci ioport api.
+ */
+struct rte_pci_ioport {
+	struct rte_pci_device *dev;
+	uint64_t base;
+	uint64_t len; /* only filled for memory mapped ports */
+};
+
+/**
+ * Initialize a rte_pci_ioport object for a pci device io resource.
+ *
+ * This object is then used to gain access to those io resources (see below).
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use.
+ * @param bar
+ *   Index of the io pci resource we want to access.
+ * @param p
+ *   The rte_pci_ioport object to be initialized.
+ * @return
+ *  0 on success, negative on error.
+ */
+int rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p);
+
+/**
+ * Release any resources used in a rte_pci_ioport object.
+ *
+ * @param p
+ *   The rte_pci_ioport object to be uninitialized.
+ * @return
+ *  0 on success, negative on error.
+ */
+int rte_pci_ioport_unmap(struct rte_pci_ioport *p);
+
+/**
+ * Read from a io pci resource.
+ *
+ * @param p
+ *   The rte_pci_ioport object from which we want to read.
+ * @param data
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into the pci io resource.
+ */
+void rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset);
+
+/**
+ * Write to a io pci resource.
+ *
+ * @param p
+ *   The rte_pci_ioport object to which we want to write.
+ * @param data
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into the pci io resource.
+ */
+void rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_BUS_PCI_H_ */
diff --git a/drivers/bus/pci/linux/Makefile b/drivers/bus/pci/linux/Makefile
new file mode 100644
index 0000000..d2ea84c
--- /dev/null
+++ b/drivers/bus/pci/linux/Makefile
@@ -0,0 +1,37 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += rte_pci.c
+SRCS += rte_pci_uio.c
+SRCS += rte_pci_vfio.c
+SRCS += rte_vfio_mp_sync.c
+
+CFLAGS += -D_GNU_SOURCE
diff --git a/drivers/bus/pci/linux/rte_pci.c b/drivers/bus/pci/linux/rte_pci.c
new file mode 100644
index 0000000..c2ac82b
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_pci.c
@@ -0,0 +1,722 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <dirent.h>
+
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+#include <rte_devargs.h>
+#include <rte_memcpy.h>
+
+#include "eal_filesystem.h"
+#include "private.h"
+#include "rte_pci_init.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in sysfs.
+ * When a registered device matches a driver, it is then initialized with
+ * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
+ */
+
+extern struct rte_pci_bus rte_pci_bus;
+
+static int
+pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
+{
+	int count;
+	char path[PATH_MAX];
+	char *name;
+
+	if (!filename || !dri_name)
+		return -1;
+
+	count = readlink(filename, path, PATH_MAX);
+	if (count >= PATH_MAX)
+		return -1;
+
+	/* For device does not have a driver */
+	if (count < 0)
+		return 1;
+
+	path[count] = '\0';
+
+	name = strrchr(path, '/');
+	if (name) {
+		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
+		return 0;
+	}
+
+	return -1;
+}
+
+/* Map pci device */
+int
+rte_pci_map_device(struct rte_pci_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_map_resource(dev);
+#endif
+		break;
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+		if (rte_eal_using_phys_addrs()) {
+			/* map resources for devices that use uio */
+			ret = pci_uio_map_resource(dev);
+		}
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+/* Unmap pci device */
+void
+rte_pci_unmap_device(struct rte_pci_device *dev)
+{
+	/* try unmapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+		if (pci_vfio_is_enabled())
+			pci_vfio_unmap_resource(dev);
+#endif
+		break;
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+		/* unmap resources for devices that use uio */
+		pci_uio_unmap_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+void *
+pci_find_max_end_va(void)
+{
+	const struct rte_memseg *seg = rte_eal_get_physmem_layout();
+	const struct rte_memseg *last = seg;
+	unsigned i = 0;
+
+	for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
+		if (seg->addr == NULL)
+			break;
+
+		if (seg->addr > last->addr)
+			last = seg;
+
+	}
+	return RTE_PTR_ADD(last->addr, last->len);
+}
+
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int
+pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+	uint64_t *end_addr, uint64_t *flags)
+{
+	union pci_resource_info {
+		struct {
+			char *phys_addr;
+			char *end_addr;
+			char *flags;
+		};
+		char *ptrs[PCI_RESOURCE_FMT_NVAL];
+	} res_info;
+
+	if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
+		RTE_LOG(ERR, EAL,
+			"%s(): bad resource format\n", __func__);
+		return -1;
+	}
+	errno = 0;
+	*phys_addr = strtoull(res_info.phys_addr, NULL, 16);
+	*end_addr = strtoull(res_info.end_addr, NULL, 16);
+	*flags = strtoull(res_info.flags, NULL, 16);
+	if (errno != 0) {
+		RTE_LOG(ERR, EAL,
+			"%s(): bad resource format\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
+
+/* parse the "resource" sysfs file */
+static int
+pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
+{
+	FILE *f;
+	char buf[BUFSIZ];
+	int i;
+	uint64_t phys_addr, end_addr, flags;
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
+		return -1;
+	}
+
+	for (i = 0; i<PCI_MAX_RESOURCE; i++) {
+
+		if (fgets(buf, sizeof(buf), f) == NULL) {
+			RTE_LOG(ERR, EAL,
+				"%s(): cannot read resource\n", __func__);
+			goto error;
+		}
+		if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+				&end_addr, &flags) < 0)
+			goto error;
+
+		if (flags & IORESOURCE_MEM) {
+			dev->mem_resource[i].phys_addr = phys_addr;
+			dev->mem_resource[i].len = end_addr - phys_addr + 1;
+			/* not mapped for now */
+			dev->mem_resource[i].addr = NULL;
+		}
+	}
+	fclose(f);
+	return 0;
+
+error:
+	fclose(f);
+	return -1;
+}
+
+/* Scan one pci sysfs entry, and fill the devices list from it. */
+static int
+pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
+{
+	char filename[PATH_MAX];
+	unsigned long tmp;
+	struct rte_pci_device *dev;
+	char driver[PATH_MAX];
+	int ret;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL)
+		return -1;
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr = *addr;
+
+	/* get vendor id */
+	snprintf(filename, sizeof(filename), "%s/vendor", dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.vendor_id = (uint16_t)tmp;
+
+	/* get device id */
+	snprintf(filename, sizeof(filename), "%s/device", dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.device_id = (uint16_t)tmp;
+
+	/* get subsystem_vendor id */
+	snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.subsystem_vendor_id = (uint16_t)tmp;
+
+	/* get subsystem_device id */
+	snprintf(filename, sizeof(filename), "%s/subsystem_device",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.subsystem_device_id = (uint16_t)tmp;
+
+	/* get class_id */
+	snprintf(filename, sizeof(filename), "%s/class",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	/* the least 24 bits are valid: class, subclass, program interface */
+	dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
+
+	/* get max_vfs */
+	dev->max_vfs = 0;
+	snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
+	if (!access(filename, F_OK) &&
+	    eal_parse_sysfs_value(filename, &tmp) == 0)
+		dev->max_vfs = (uint16_t)tmp;
+	else {
+		/* for non igb_uio driver, need kernel version >= 3.8 */
+		snprintf(filename, sizeof(filename),
+			 "%s/sriov_numvfs", dirname);
+		if (!access(filename, F_OK) &&
+		    eal_parse_sysfs_value(filename, &tmp) == 0)
+			dev->max_vfs = (uint16_t)tmp;
+	}
+
+	/* get numa node, default to 0 if not present */
+	snprintf(filename, sizeof(filename), "%s/numa_node",
+		 dirname);
+
+	if (access(filename, F_OK) != -1) {
+		if (eal_parse_sysfs_value(filename, &tmp) == 0)
+			dev->device.numa_node = tmp;
+		else
+			dev->device.numa_node = -1;
+	} else {
+		dev->device.numa_node = 0;
+	}
+
+	pci_name_set(dev);
+
+	/* parse resources */
+	snprintf(filename, sizeof(filename), "%s/resource", dirname);
+	if (pci_parse_sysfs_resource(filename, dev) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
+		free(dev);
+		return -1;
+	}
+
+	/* parse driver */
+	snprintf(filename, sizeof(filename), "%s/driver", dirname);
+	ret = pci_get_kernel_driver_by_path(filename, driver);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
+		free(dev);
+		return -1;
+	}
+
+	if (!ret) {
+		if (!strcmp(driver, "vfio-pci"))
+			dev->kdrv = RTE_KDRV_VFIO;
+		else if (!strcmp(driver, "igb_uio"))
+			dev->kdrv = RTE_KDRV_IGB_UIO;
+		else if (!strcmp(driver, "uio_pci_generic"))
+			dev->kdrv = RTE_KDRV_UIO_GENERIC;
+		else
+			dev->kdrv = RTE_KDRV_UNKNOWN;
+	} else
+		dev->kdrv = RTE_KDRV_NONE;
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
+		rte_pci_add_device(dev);
+	} else {
+		struct rte_pci_device *dev2;
+		int ret;
+
+		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
+			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+
+			if (ret < 0) {
+				rte_pci_insert_device(dev2, dev);
+			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->max_vfs = dev->max_vfs;
+				pci_name_set(dev2);
+				memmove(dev2->mem_resource, dev->mem_resource,
+					sizeof(dev->mem_resource));
+				free(dev);
+			}
+			return 0;
+		}
+
+		rte_pci_add_device(dev);
+	}
+
+	return 0;
+}
+
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+	char filename[PATH_MAX];
+
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
+		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
+		 addr->function);
+
+	return pci_scan_one(filename, addr);
+}
+
+/*
+ * split up a pci address into its constituent parts.
+ */
+static int
+parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
+{
+	/* first split on ':' */
+	union splitaddr {
+		struct {
+			char *domain;
+			char *bus;
+			char *devid;
+			char *function;
+		};
+		char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
+	} splitaddr;
+
+	char *buf_copy = strndup(buf, bufsize);
+	if (buf_copy == NULL)
+		return -1;
+
+	if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
+			!= PCI_FMT_NVAL - 1)
+		goto error;
+	/* final split is on '.' between devid and function */
+	splitaddr.function = strchr(splitaddr.devid,'.');
+	if (splitaddr.function == NULL)
+		goto error;
+	*splitaddr.function++ = '\0';
+
+	/* now convert to int values */
+	errno = 0;
+	addr->domain = strtoul(splitaddr.domain, NULL, 16);
+	addr->bus = strtoul(splitaddr.bus, NULL, 16);
+	addr->devid = strtoul(splitaddr.devid, NULL, 16);
+	addr->function = strtoul(splitaddr.function, NULL, 10);
+	if (errno != 0)
+		goto error;
+
+	free(buf_copy); /* free the copy made with strdup */
+	return 0;
+error:
+	free(buf_copy);
+	return -1;
+}
+
+/*
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ */
+int
+rte_pci_scan(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+	struct rte_pci_addr addr;
+
+	/* for debug purposes, PCI can be disabled */
+	if (internal_config.no_pci)
+		return 0;
+
+	dir = opendir(pci_get_sysfs_path());
+	if (dir == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
+			continue;
+
+		snprintf(dirname, sizeof(dirname), "%s/%s",
+				pci_get_sysfs_path(), e->d_name);
+
+		if (pci_scan_one(dirname, &addr) < 0)
+			goto error;
+	}
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
+
+/* Read PCI config space. */
+int rte_pci_read_config(const struct rte_pci_device *device,
+		void *buf, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &device->intr_handle;
+
+	switch (intr_handle->type) {
+	case RTE_INTR_HANDLE_UIO:
+	case RTE_INTR_HANDLE_UIO_INTX:
+		return pci_uio_read_config(intr_handle, buf, len, offset);
+
+#ifdef VFIO_PRESENT
+	case RTE_INTR_HANDLE_VFIO_MSIX:
+	case RTE_INTR_HANDLE_VFIO_MSI:
+	case RTE_INTR_HANDLE_VFIO_LEGACY:
+		return pci_vfio_read_config(intr_handle, buf, len, offset);
+#endif
+	default:
+		RTE_LOG(ERR, EAL,
+			"Unknown handle type of fd %d\n",
+					intr_handle->fd);
+		return -1;
+	}
+}
+
+/* Write PCI config space. */
+int rte_pci_write_config(const struct rte_pci_device *device,
+		const void *buf, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &device->intr_handle;
+
+	switch (intr_handle->type) {
+	case RTE_INTR_HANDLE_UIO:
+	case RTE_INTR_HANDLE_UIO_INTX:
+		return pci_uio_write_config(intr_handle, buf, len, offset);
+
+#ifdef VFIO_PRESENT
+	case RTE_INTR_HANDLE_VFIO_MSIX:
+	case RTE_INTR_HANDLE_VFIO_MSI:
+	case RTE_INTR_HANDLE_VFIO_LEGACY:
+		return pci_vfio_write_config(intr_handle, buf, len, offset);
+#endif
+	default:
+		RTE_LOG(ERR, EAL,
+			"Unknown handle type of fd %d\n",
+					intr_handle->fd);
+		return -1;
+	}
+}
+
+#if defined(RTE_ARCH_X86)
+static int
+pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
+		struct rte_pci_ioport *p)
+{
+	uint16_t start, end;
+	FILE *fp;
+	char *line = NULL;
+	char pci_id[16];
+	int found = 0;
+	size_t linesz;
+
+	snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
+		 dev->addr.domain, dev->addr.bus,
+		 dev->addr.devid, dev->addr.function);
+
+	fp = fopen("/proc/ioports", "r");
+	if (fp == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);
+		return -1;
+	}
+
+	while (getdelim(&line, &linesz, '\n', fp) > 0) {
+		char *ptr = line;
+		char *left;
+		int n;
+
+		n = strcspn(ptr, ":");
+		ptr[n] = 0;
+		left = &ptr[n + 1];
+
+		while (*left && isspace(*left))
+			left++;
+
+		if (!strncmp(left, pci_id, strlen(pci_id))) {
+			found = 1;
+
+			while (*ptr && isspace(*ptr))
+				ptr++;
+
+			sscanf(ptr, "%04hx-%04hx", &start, &end);
+
+			break;
+		}
+	}
+
+	free(line);
+	fclose(fp);
+
+	if (!found)
+		return -1;
+
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	p->base = start;
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
+
+	return 0;
+}
+#endif
+
+int
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p)
+{
+	int ret = -1;
+
+	switch (dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_ioport_map(dev, bar, p);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		ret = pci_uio_ioport_map(dev, bar, p);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+		ret = pci_ioport_map(dev, bar, p);
+#else
+		ret = pci_uio_ioport_map(dev, bar, p);
+#endif
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		ret = pci_ioport_map(dev, bar, p);
+#endif
+		break;
+	default:
+		break;
+	}
+
+	if (!ret)
+		p->dev = dev;
+
+	return ret;
+}
+
+void
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		pci_vfio_ioport_read(p, data, len, offset);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		pci_uio_ioport_read(p, data, len, offset);
+#endif
+		break;
+	default:
+		break;
+	}
+}
+
+void
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		pci_vfio_ioport_write(p, data, len, offset);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		pci_uio_ioport_write(p, data, len, offset);
+#endif
+		break;
+	default:
+		break;
+	}
+}
+
+int
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
+{
+	int ret = -1;
+
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_ioport_unmap(p);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		ret = pci_uio_ioport_unmap(p);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+		ret = 0;
+#else
+		ret = pci_uio_ioport_unmap(p);
+#endif
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		ret = 0;
+#endif
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/bus/pci/linux/rte_pci_init.h b/drivers/bus/pci/linux/rte_pci_init.h
new file mode 100644
index 0000000..ae2980d
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_pci_init.h
@@ -0,0 +1,97 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EAL_PCI_INIT_H_
+#define EAL_PCI_INIT_H_
+
+#include "eal_vfio.h"
+
+/** IO resource type: */
+#define IORESOURCE_IO         0x00000100
+#define IORESOURCE_MEM        0x00000200
+
+/*
+ * Helper function to map PCI resources right after hugepages in virtual memory
+ */
+extern void *pci_map_addr;
+void *pci_find_max_end_va(void);
+
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+	uint64_t *end_addr, uint64_t *flags);
+
+int pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res);
+void pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res);
+int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx);
+
+int pci_uio_read_config(const struct rte_intr_handle *intr_handle,
+			void *buf, size_t len, off_t offs);
+int pci_uio_write_config(const struct rte_intr_handle *intr_handle,
+			 const void *buf, size_t len, off_t offs);
+
+int pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		       struct rte_pci_ioport *p);
+void pci_uio_ioport_read(struct rte_pci_ioport *p,
+			 void *data, size_t len, off_t offset);
+void pci_uio_ioport_write(struct rte_pci_ioport *p,
+			  const void *data, size_t len, off_t offset);
+int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
+
+#ifdef VFIO_PRESENT
+
+/* access config space */
+int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
+			 void *buf, size_t len, off_t offs);
+int pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
+			  const void *buf, size_t len, off_t offs);
+
+int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
+		        struct rte_pci_ioport *p);
+void pci_vfio_ioport_read(struct rte_pci_ioport *p,
+			  void *data, size_t len, off_t offset);
+void pci_vfio_ioport_write(struct rte_pci_ioport *p,
+			   const void *data, size_t len, off_t offset);
+int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
+
+/* map/unmap VFIO resource prototype */
+int pci_vfio_map_resource(struct rte_pci_device *dev);
+int pci_vfio_unmap_resource(struct rte_pci_device *dev);
+
+#endif
+
+#endif /* EAL_PCI_INIT_H_ */
diff --git a/drivers/bus/pci/linux/rte_pci_uio.c b/drivers/bus/pci/linux/rte_pci_uio.c
new file mode 100644
index 0000000..eed6d0f
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_pci_uio.c
@@ -0,0 +1,567 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/sysmacros.h>
+#include <linux/pci_regs.h>
+
+#if defined(RTE_ARCH_X86)
+#include <sys/io.h>
+#endif
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_common.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "rte_pci_init.h"
+
+void *pci_map_addr = NULL;
+
+#define OFF_MAX              ((uint64_t)(off_t)-1)
+
+int
+pci_uio_read_config(const struct rte_intr_handle *intr_handle,
+		    void *buf, size_t len, off_t offset)
+{
+	return pread(intr_handle->uio_cfg_fd, buf, len, offset);
+}
+
+int
+pci_uio_write_config(const struct rte_intr_handle *intr_handle,
+		     const void *buf, size_t len, off_t offset)
+{
+	return pwrite(intr_handle->uio_cfg_fd, buf, len, offset);
+}
+
+static int
+pci_uio_set_bus_master(int dev_fd)
+{
+	uint16_t reg;
+	int ret;
+
+	ret = pread(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL,
+			"Cannot read command from PCI config space!\n");
+		return -1;
+	}
+
+	/* return if bus mastering is already on */
+	if (reg & PCI_COMMAND_MASTER)
+		return 0;
+
+	reg |= PCI_COMMAND_MASTER;
+
+	ret = pwrite(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL,
+			"Cannot write command to PCI config space!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
+{
+	FILE *f;
+	char filename[PATH_MAX];
+	int ret;
+	unsigned major, minor;
+	dev_t dev;
+
+	/* get the name of the sysfs file that contains the major and minor
+	 * of the uio device and read its content */
+	snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path);
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n",
+			__func__);
+		return -1;
+	}
+
+	ret = fscanf(f, "%u:%u", &major, &minor);
+	if (ret != 2) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n",
+			__func__);
+		fclose(f);
+		return -1;
+	}
+	fclose(f);
+
+	/* create the char device "mknod /dev/uioX c major minor" */
+	snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
+	dev = makedev(major, minor);
+	ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
+	if (ret != 0) {
+		RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	return ret;
+}
+
+/*
+ * Return the uioX char device used for a pci device. On success, return
+ * the UIO number and fill dstbuf string with the path of the device in
+ * sysfs. On error, return a negative value. In this case dstbuf is
+ * invalid.
+ */
+static int
+pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
+			   unsigned int buflen, int create)
+{
+	struct rte_pci_addr *loc = &dev->addr;
+	unsigned int uio_num;
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+
+	/* depending on kernel version, uio can be located in uio/uioX
+	 * or uio:uioX */
+
+	snprintf(dirname, sizeof(dirname),
+			"%s/" PCI_PRI_FMT "/uio", pci_get_sysfs_path(),
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	dir = opendir(dirname);
+	if (dir == NULL) {
+		/* retry with the parent directory */
+		snprintf(dirname, sizeof(dirname),
+				"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
+				loc->domain, loc->bus, loc->devid, loc->function);
+		dir = opendir(dirname);
+
+		if (dir == NULL) {
+			RTE_LOG(ERR, EAL, "Cannot opendir %s\n", dirname);
+			return -1;
+		}
+	}
+
+	/* take the first file starting with "uio" */
+	while ((e = readdir(dir)) != NULL) {
+		/* format could be uio%d ...*/
+		int shortprefix_len = sizeof("uio") - 1;
+		/* ... or uio:uio%d */
+		int longprefix_len = sizeof("uio:uio") - 1;
+		char *endptr;
+
+		if (strncmp(e->d_name, "uio", 3) != 0)
+			continue;
+
+		/* first try uio%d */
+		errno = 0;
+		uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
+		if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
+			snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
+			break;
+		}
+
+		/* then try uio:uio%d */
+		errno = 0;
+		uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
+		if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
+			snprintf(dstbuf, buflen, "%s/uio:uio%u", dirname, uio_num);
+			break;
+		}
+	}
+	closedir(dir);
+
+	/* No uio resource found */
+	if (e == NULL)
+		return -1;
+
+	/* create uio device if we've been asked to */
+	if (internal_config.create_uio_dev && create &&
+			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
+		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
+
+	return uio_num;
+}
+
+void
+pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res)
+{
+	rte_free(uio_res);
+
+	if (dev->intr_handle.uio_cfg_fd >= 0) {
+		close(dev->intr_handle.uio_cfg_fd);
+		dev->intr_handle.uio_cfg_fd = -1;
+	}
+	if (dev->intr_handle.fd >= 0) {
+		close(dev->intr_handle.fd);
+		dev->intr_handle.fd = -1;
+		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	}
+}
+
+int
+pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res)
+{
+	char dirname[PATH_MAX];
+	char cfgname[PATH_MAX];
+	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	int uio_num;
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+
+	/* find uio resource */
+	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 1);
+	if (uio_num < 0) {
+		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+		return 1;
+	}
+	snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
+
+	/* save fd if in primary process */
+	dev->intr_handle.fd = open(devname, O_RDWR);
+	if (dev->intr_handle.fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			devname, strerror(errno));
+		goto error;
+	}
+
+	snprintf(cfgname, sizeof(cfgname),
+			"/sys/class/uio/uio%u/device/config", uio_num);
+	dev->intr_handle.uio_cfg_fd = open(cfgname, O_RDWR);
+	if (dev->intr_handle.uio_cfg_fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			cfgname, strerror(errno));
+		goto error;
+	}
+
+	if (dev->kdrv == RTE_KDRV_IGB_UIO)
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+	else {
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
+
+		/* set bus master that is not done by uio_pci_generic */
+		if (pci_uio_set_bus_master(dev->intr_handle.uio_cfg_fd)) {
+			RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
+			goto error;
+		}
+	}
+
+	/* allocate the mapping details for secondary processes*/
+	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
+	if (*uio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto error;
+	}
+
+	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
+	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
+
+	return 0;
+
+error:
+	pci_uio_free_resource(dev, *uio_res);
+	return -1;
+}
+
+int
+pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx)
+{
+	int fd;
+	char devname[PATH_MAX];
+	void *mapaddr;
+	struct rte_pci_addr *loc;
+	struct pci_map *maps;
+
+	loc = &dev->addr;
+	maps = uio_res->maps;
+
+	/* update devname for mmap  */
+	snprintf(devname, sizeof(devname),
+			"%s/" PCI_PRI_FMT "/resource%d",
+			pci_get_sysfs_path(),
+			loc->domain, loc->bus, loc->devid,
+			loc->function, res_idx);
+
+	/* allocate memory to keep path */
+	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+	if (maps[map_idx].path == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+				strerror(errno));
+		return -1;
+	}
+
+	/*
+	 * open resource file, to mmap it
+	 */
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				devname, strerror(errno));
+		goto error;
+	}
+
+	/* try mapping somewhere close to the end of hugepages */
+	if (pci_map_addr == NULL)
+		pci_map_addr = pci_find_max_end_va();
+
+	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
+			(size_t)dev->mem_resource[res_idx].len, 0);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		goto error;
+
+	pci_map_addr = RTE_PTR_ADD(mapaddr,
+			(size_t)dev->mem_resource[res_idx].len);
+
+	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+	maps[map_idx].size = dev->mem_resource[res_idx].len;
+	maps[map_idx].addr = mapaddr;
+	maps[map_idx].offset = 0;
+	strcpy(maps[map_idx].path, devname);
+	dev->mem_resource[res_idx].addr = mapaddr;
+
+	return 0;
+
+error:
+	rte_free(maps[map_idx].path);
+	return -1;
+}
+
+#if defined(RTE_ARCH_X86)
+int
+pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		   struct rte_pci_ioport *p)
+{
+	char dirname[PATH_MAX];
+	char filename[PATH_MAX];
+	int uio_num;
+	unsigned long start;
+
+	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 0);
+	if (uio_num < 0)
+		return -1;
+
+	/* get portio start */
+	snprintf(filename, sizeof(filename),
+		 "%s/portio/port%d/start", dirname, bar);
+	if (eal_parse_sysfs_value(filename, &start) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
+			__func__);
+		return -1;
+	}
+	/* ensure we don't get anything funny here, read/write will cast to
+	 * uin16_t */
+	if (start > UINT16_MAX)
+		return -1;
+
+	/* FIXME only for primary process ? */
+	if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {
+
+		snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
+		dev->intr_handle.fd = open(filename, O_RDWR);
+		if (dev->intr_handle.fd < 0) {
+			RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				filename, strerror(errno));
+			return -1;
+		}
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+	}
+
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);
+
+	p->base = start;
+	p->len = 0;
+	return 0;
+}
+#else
+int
+pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		   struct rte_pci_ioport *p)
+{
+	FILE *f;
+	char buf[BUFSIZ];
+	char filename[PATH_MAX];
+	uint64_t phys_addr, end_addr, flags;
+	int fd, i;
+	void *addr;
+
+	/* open and read addresses of the corresponding resource in sysfs */
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
+		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function);
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",
+			strerror(errno));
+		return -1;
+	}
+	for (i = 0; i < bar + 1; i++) {
+		if (fgets(buf, sizeof(buf), f) == NULL) {
+			RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");
+			goto error;
+		}
+	}
+	if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+			&end_addr, &flags) < 0)
+		goto error;
+	if ((flags & IORESOURCE_IO) == 0) {
+		RTE_LOG(ERR, EAL, "BAR %d is not an IO resource\n", bar);
+		goto error;
+	}
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
+		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function, bar);
+
+	/* mmap the pci resource */
+	fd = open(filename, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
+			strerror(errno));
+		goto error;
+	}
+	addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
+		MAP_SHARED, fd, 0);
+	close(fd);
+	if (addr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s\n",
+			strerror(errno));
+		goto error;
+	}
+
+	/* strangely, the base address is mmap addr + phys_addr */
+	p->base = (uintptr_t)addr + phys_addr;
+	p->len = end_addr + 1;
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"\n", p->base);
+	fclose(f);
+
+	return 0;
+
+error:
+	fclose(f);
+	return -1;
+}
+#endif
+
+void
+pci_uio_ioport_read(struct rte_pci_ioport *p,
+		    void *data, size_t len, off_t offset)
+{
+	uint8_t *d;
+	int size;
+	uintptr_t reg = p->base + offset;
+
+	for (d = data; len > 0; d += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+#if defined(RTE_ARCH_X86)
+			*(uint32_t *)d = inl(reg);
+#else
+			*(uint32_t *)d = *(volatile uint32_t *)reg;
+#endif
+		} else if (len >= 2) {
+			size = 2;
+#if defined(RTE_ARCH_X86)
+			*(uint16_t *)d = inw(reg);
+#else
+			*(uint16_t *)d = *(volatile uint16_t *)reg;
+#endif
+		} else {
+			size = 1;
+#if defined(RTE_ARCH_X86)
+			*d = inb(reg);
+#else
+			*d = *(volatile uint8_t *)reg;
+#endif
+		}
+	}
+}
+
+void
+pci_uio_ioport_write(struct rte_pci_ioport *p,
+		     const void *data, size_t len, off_t offset)
+{
+	const uint8_t *s;
+	int size;
+	uintptr_t reg = p->base + offset;
+
+	for (s = data; len > 0; s += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+#if defined(RTE_ARCH_X86)
+			outl_p(*(const uint32_t *)s, reg);
+#else
+			*(volatile uint32_t *)reg = *(const uint32_t *)s;
+#endif
+		} else if (len >= 2) {
+			size = 2;
+#if defined(RTE_ARCH_X86)
+			outw_p(*(const uint16_t *)s, reg);
+#else
+			*(volatile uint16_t *)reg = *(const uint16_t *)s;
+#endif
+		} else {
+			size = 1;
+#if defined(RTE_ARCH_X86)
+			outb_p(*s, reg);
+#else
+			*(volatile uint8_t *)reg = *s;
+#endif
+		}
+	}
+}
+
+int
+pci_uio_ioport_unmap(struct rte_pci_ioport *p)
+{
+#if defined(RTE_ARCH_X86)
+	RTE_SET_USED(p);
+	/* FIXME close intr fd ? */
+	return 0;
+#else
+	return munmap((void *)(uintptr_t)p->base, p->len);
+#endif
+}
diff --git a/drivers/bus/pci/linux/rte_pci_vfio.c b/drivers/bus/pci/linux/rte_pci_vfio.c
new file mode 100644
index 0000000..81b67c9
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_pci_vfio.c
@@ -0,0 +1,674 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <fcntl.h>
+#include <linux/pci_regs.h>
+#include <sys/eventfd.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "rte_pci_init.h"
+#include "eal_vfio.h"
+#include "private.h"
+
+/**
+ * @file
+ * PCI probing under linux (VFIO version)
+ *
+ * This code tries to determine if the PCI device is bound to VFIO driver,
+ * and initialize it (map BARs, set up interrupts) if that's the case.
+ *
+ * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
+ */
+
+#ifdef VFIO_PRESENT
+
+#define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
+#define PAGE_MASK   (~(PAGE_SIZE - 1))
+
+static struct rte_tailq_elem rte_vfio_tailq = {
+	.name = "VFIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_vfio_tailq)
+
+int
+pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
+		    void *buf, size_t len, off_t offs)
+{
+	return pread64(intr_handle->vfio_dev_fd, buf, len,
+	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
+}
+
+int
+pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
+		    const void *buf, size_t len, off_t offs)
+{
+	return pwrite64(intr_handle->vfio_dev_fd, buf, len,
+	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
+}
+
+/* get PCI BAR number where MSI-X interrupts are */
+static int
+pci_vfio_get_msix_bar(int fd, int *msix_bar, uint32_t *msix_table_offset,
+		      uint32_t *msix_table_size)
+{
+	int ret;
+	uint32_t reg;
+	uint16_t flags;
+	uint8_t cap_id, cap_offset;
+
+	/* read PCI capability pointer from config space */
+	ret = pread64(fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_CAPABILITY_LIST);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
+				"config space!\n");
+		return -1;
+	}
+
+	/* we need first byte */
+	cap_offset = reg & 0xFF;
+
+	while (cap_offset) {
+
+		/* read PCI capability ID */
+		ret = pread64(fd, &reg, sizeof(reg),
+				VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+				cap_offset);
+		if (ret != sizeof(reg)) {
+			RTE_LOG(ERR, EAL, "Cannot read capability ID from PCI "
+					"config space!\n");
+			return -1;
+		}
+
+		/* we need first byte */
+		cap_id = reg & 0xFF;
+
+		/* if we haven't reached MSI-X, check next capability */
+		if (cap_id != PCI_CAP_ID_MSIX) {
+			ret = pread64(fd, &reg, sizeof(reg),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset);
+			if (ret != sizeof(reg)) {
+				RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
+						"config space!\n");
+				return -1;
+			}
+
+			/* we need second byte */
+			cap_offset = (reg & 0xFF00) >> 8;
+
+			continue;
+		}
+		/* else, read table offset */
+		else {
+			/* table offset resides in the next 4 bytes */
+			ret = pread64(fd, &reg, sizeof(reg),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset + 4);
+			if (ret != sizeof(reg)) {
+				RTE_LOG(ERR, EAL, "Cannot read table offset from PCI config "
+						"space!\n");
+				return -1;
+			}
+
+			ret = pread64(fd, &flags, sizeof(flags),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset + 2);
+			if (ret != sizeof(flags)) {
+				RTE_LOG(ERR, EAL, "Cannot read table flags from PCI config "
+						"space!\n");
+				return -1;
+			}
+
+			*msix_bar = reg & RTE_PCI_MSIX_TABLE_BIR;
+			*msix_table_offset = reg & RTE_PCI_MSIX_TABLE_OFFSET;
+			*msix_table_size = 16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE));
+
+			return 0;
+		}
+	}
+	return 0;
+}
+
+/* set PCI bus mastering */
+static int
+pci_vfio_set_bus_master(int dev_fd, bool op)
+{
+	uint16_t reg;
+	int ret;
+
+	ret = pread64(dev_fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n");
+		return -1;
+	}
+
+	if (op)
+		/* set the master bit */
+		reg |= PCI_COMMAND_MASTER;
+	else
+		reg &= ~(PCI_COMMAND_MASTER);
+
+	ret = pwrite64(dev_fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_COMMAND);
+
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* set up interrupt support (but not enable interrupts) */
+static int
+pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
+{
+	int i, ret, intr_idx;
+
+	/* default to invalid index */
+	intr_idx = VFIO_PCI_NUM_IRQS;
+
+	/* get interrupt type from internal config (MSI-X by default, can be
+	 * overridden from the command line
+	 */
+	switch (internal_config.vfio_intr_mode) {
+	case RTE_INTR_MODE_MSIX:
+		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
+		break;
+	case RTE_INTR_MODE_MSI:
+		intr_idx = VFIO_PCI_MSI_IRQ_INDEX;
+		break;
+	case RTE_INTR_MODE_LEGACY:
+		intr_idx = VFIO_PCI_INTX_IRQ_INDEX;
+		break;
+	/* don't do anything if we want to automatically determine interrupt type */
+	case RTE_INTR_MODE_NONE:
+		break;
+	default:
+		RTE_LOG(ERR, EAL, "  unknown default interrupt type!\n");
+		return -1;
+	}
+
+	/* start from MSI-X interrupt type */
+	for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) {
+		struct vfio_irq_info irq = { .argsz = sizeof(irq) };
+		int fd = -1;
+
+		/* skip interrupt modes we don't want */
+		if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE &&
+				i != intr_idx)
+			continue;
+
+		irq.index = i;
+
+		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  cannot get IRQ info, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+
+		/* if this vector cannot be used with eventfd, fail if we explicitly
+		 * specified interrupt type, otherwise continue */
+		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
+			if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE) {
+				RTE_LOG(ERR, EAL,
+						"  interrupt vector does not support eventfd!\n");
+				return -1;
+			} else
+				continue;
+		}
+
+		/* set up an eventfd for interrupts */
+		fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
+		if (fd < 0) {
+			RTE_LOG(ERR, EAL, "  cannot set up eventfd, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+
+		dev->intr_handle.fd = fd;
+		dev->intr_handle.vfio_dev_fd = vfio_dev_fd;
+
+		switch (i) {
+		case VFIO_PCI_MSIX_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSIX;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
+			break;
+		case VFIO_PCI_MSI_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSI;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
+			break;
+		case VFIO_PCI_INTX_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_LEGACY;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
+			break;
+		default:
+			RTE_LOG(ERR, EAL, "  unknown interrupt type!\n");
+			return -1;
+		}
+
+		return 0;
+	}
+
+	/* if we're here, we haven't found a suitable interrupt vector */
+	return -1;
+}
+
+/*
+ * map the PCI resources of a PCI device in virtual memory (VFIO version).
+ * primary and secondary processes follow almost exactly the same path
+ */
+int
+pci_vfio_map_resource(struct rte_pci_device *dev)
+{
+	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+	char pci_addr[PATH_MAX] = {0};
+	int vfio_dev_fd;
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret, msix_bar;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+
+	struct pci_map *maps;
+	uint32_t msix_table_offset = 0;
+	uint32_t msix_table_size = 0;
+	uint32_t ioport_bar;
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	if ((ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
+					&vfio_dev_fd, &device_info)))
+		return ret;
+
+	/* get MSI-X BAR, if any (we have to know where it is because we can't
+	 * easily mmap it when using VFIO) */
+	msix_bar = -1;
+	ret = pci_vfio_get_msix_bar(vfio_dev_fd, &msix_bar,
+				    &msix_table_offset, &msix_table_size);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "  %s cannot get MSI-X BAR number!\n", pci_addr);
+		close(vfio_dev_fd);
+		return -1;
+	}
+
+	/* if we're in a primary process, allocate vfio_res and get region info */
+	if (internal_config.process_type == RTE_PROC_PRIMARY) {
+		vfio_res = rte_zmalloc("VFIO_RES", sizeof(*vfio_res), 0);
+		if (vfio_res == NULL) {
+			RTE_LOG(ERR, EAL,
+				"%s(): cannot store uio mmap details\n", __func__);
+			close(vfio_dev_fd);
+			return -1;
+		}
+		memcpy(&vfio_res->pci_addr, &dev->addr, sizeof(vfio_res->pci_addr));
+
+		/* get number of registers (up to BAR5) */
+		vfio_res->nb_maps = RTE_MIN((int) device_info.num_regions,
+				VFIO_PCI_BAR5_REGION_INDEX + 1);
+	} else {
+		/* if we're in a secondary process, just find our tailq entry */
+		TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
+			if (rte_eal_compare_pci_addr(&vfio_res->pci_addr,
+						     &dev->addr))
+				continue;
+			break;
+		}
+		/* if we haven't found our tailq entry, something's wrong */
+		if (vfio_res == NULL) {
+			RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
+					pci_addr);
+			close(vfio_dev_fd);
+			return -1;
+		}
+	}
+
+	/* map BARs */
+	maps = vfio_res->maps;
+
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+		struct vfio_region_info reg = { .argsz = sizeof(reg) };
+		void *bar_addr;
+		struct memreg {
+			unsigned long offset, size;
+		} memreg[2] = {};
+
+		reg.index = i;
+
+		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg);
+
+		if (ret) {
+			RTE_LOG(ERR, EAL, "  %s cannot get device region info "
+					"error %i (%s)\n", pci_addr, errno, strerror(errno));
+			close(vfio_dev_fd);
+			if (internal_config.process_type == RTE_PROC_PRIMARY)
+				rte_free(vfio_res);
+			return -1;
+		}
+
+		/* chk for io port region */
+		ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar),
+			      VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX)
+			      + PCI_BASE_ADDRESS_0 + i*4);
+
+		if (ret != sizeof(ioport_bar)) {
+			RTE_LOG(ERR, EAL,
+				"Cannot read command (%x) from config space!\n",
+				PCI_BASE_ADDRESS_0 + i*4);
+			return -1;
+		}
+
+		if (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) {
+			RTE_LOG(INFO, EAL,
+				"Ignore mapping IO port bar(%d) addr: %x\n",
+				 i, ioport_bar);
+			continue;
+		}
+
+		/* skip non-mmapable BARs */
+		if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0)
+			continue;
+
+		if (i == msix_bar) {
+			/*
+			 * VFIO will not let us map the MSI-X table,
+			 * but we can map around it.
+			 */
+			uint32_t table_start = msix_table_offset;
+			uint32_t table_end = table_start + msix_table_size;
+			table_end = (table_end + ~PAGE_MASK) & PAGE_MASK;
+			table_start &= PAGE_MASK;
+
+			if (table_start == 0 && table_end >= reg.size) {
+				/* Cannot map this BAR */
+				RTE_LOG(DEBUG, EAL, "Skipping BAR %d\n", i);
+				continue;
+			} else {
+				memreg[0].offset = reg.offset;
+				memreg[0].size = table_start;
+				memreg[1].offset = reg.offset + table_end;
+				memreg[1].size = reg.size - table_end;
+
+				RTE_LOG(DEBUG, EAL,
+					"Trying to map BAR %d that contains the MSI-X "
+					"table. Trying offsets: "
+					"0x%04lx:0x%04lx, 0x%04lx:0x%04lx\n", i,
+					memreg[0].offset, memreg[0].size,
+					memreg[1].offset, memreg[1].size);
+			}
+		} else {
+			memreg[0].offset = reg.offset;
+			memreg[0].size = reg.size;
+		}
+
+		/* try to figure out an address */
+		if (internal_config.process_type == RTE_PROC_PRIMARY) {
+			/* try mapping somewhere close to the end of hugepages */
+			if (pci_map_addr == NULL)
+				pci_map_addr = pci_find_max_end_va();
+
+			bar_addr = pci_map_addr;
+			pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
+		} else {
+			bar_addr = maps[i].addr;
+		}
+
+		/* reserve the address using an inaccessible mapping */
+		bar_addr = mmap(bar_addr, reg.size, 0, MAP_PRIVATE |
+				MAP_ANONYMOUS, -1, 0);
+		if (bar_addr != MAP_FAILED) {
+			void *map_addr = NULL;
+			if (memreg[0].size) {
+				/* actual map of first part */
+				map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
+							    memreg[0].offset,
+							    memreg[0].size,
+							    MAP_FIXED);
+			}
+
+			/* if there's a second part, try to map it */
+			if (map_addr != MAP_FAILED
+			    && memreg[1].offset && memreg[1].size) {
+				void *second_addr = RTE_PTR_ADD(bar_addr,
+								memreg[1].offset -
+								(uintptr_t)reg.offset);
+				map_addr = pci_map_resource(second_addr,
+							    vfio_dev_fd, memreg[1].offset,
+							    memreg[1].size,
+							    MAP_FIXED);
+			}
+
+			if (map_addr == MAP_FAILED || !map_addr) {
+				munmap(bar_addr, reg.size);
+				bar_addr = MAP_FAILED;
+			}
+		}
+
+		if (bar_addr == MAP_FAILED ||
+				(internal_config.process_type == RTE_PROC_SECONDARY &&
+						bar_addr != maps[i].addr)) {
+			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n", pci_addr, i,
+					strerror(errno));
+			close(vfio_dev_fd);
+			if (internal_config.process_type == RTE_PROC_PRIMARY)
+				rte_free(vfio_res);
+			return -1;
+		}
+
+		maps[i].addr = bar_addr;
+		maps[i].offset = reg.offset;
+		maps[i].size = reg.size;
+		maps[i].path = NULL; /* vfio doesn't have per-resource paths */
+		dev->mem_resource[i].addr = bar_addr;
+	}
+
+	/* if secondary process, do not set up interrupts */
+	if (internal_config.process_type == RTE_PROC_PRIMARY) {
+		if (pci_vfio_setup_interrupts(dev, vfio_dev_fd) != 0) {
+			RTE_LOG(ERR, EAL, "  %s error setting up interrupts!\n", pci_addr);
+			close(vfio_dev_fd);
+			rte_free(vfio_res);
+			return -1;
+		}
+
+		/* set bus mastering for the device */
+		if (pci_vfio_set_bus_master(vfio_dev_fd, true)) {
+			RTE_LOG(ERR, EAL, "  %s cannot set up bus mastering!\n", pci_addr);
+			close(vfio_dev_fd);
+			rte_free(vfio_res);
+			return -1;
+		}
+
+		/* Reset the device */
+		ioctl(vfio_dev_fd, VFIO_DEVICE_RESET);
+	}
+
+	if (internal_config.process_type == RTE_PROC_PRIMARY)
+		TAILQ_INSERT_TAIL(vfio_res_list, vfio_res, next);
+
+	return 0;
+}
+
+int
+pci_vfio_unmap_resource(struct rte_pci_device *dev)
+{
+	char pci_addr[PATH_MAX] = {0};
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list;
+
+	struct pci_map *maps;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+
+	if (close(dev->intr_handle.fd) < 0) {
+		RTE_LOG(INFO, EAL, "Error when closing eventfd file descriptor for %s\n",
+			pci_addr);
+		return -1;
+	}
+
+	if (pci_vfio_set_bus_master(dev->intr_handle.vfio_dev_fd, false)) {
+		RTE_LOG(ERR, EAL, "  %s cannot unset bus mastering for PCI device!\n",
+				pci_addr);
+		return -1;
+	}
+
+	ret = vfio_release_device(pci_get_sysfs_path(), pci_addr,
+				  dev->intr_handle.vfio_dev_fd);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot release device\n", __func__);
+		return ret;
+	}
+
+	vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+	/* Get vfio_res */
+	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
+		if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
+			continue;
+		break;
+	}
+	/* if we haven't found our tailq entry, something's wrong */
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
+				pci_addr);
+		return -1;
+	}
+
+	/* unmap BARs */
+	maps = vfio_res->maps;
+
+	RTE_LOG(INFO, EAL, "Releasing pci mapped resource for %s\n",
+		pci_addr);
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+
+		/*
+		 * We do not need to be aware of MSI-X table BAR mappings as
+		 * when mapping. Just using current maps array is enough
+		 */
+		if (maps[i].addr) {
+			RTE_LOG(INFO, EAL, "Calling pci_unmap_resource for %s at %p\n",
+				pci_addr, maps[i].addr);
+			pci_unmap_resource(maps[i].addr, maps[i].size);
+		}
+	}
+
+	TAILQ_REMOVE(vfio_res_list, vfio_res, next);
+
+	return 0;
+}
+
+int
+pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
+		    struct rte_pci_ioport *p)
+{
+	if (bar < VFIO_PCI_BAR0_REGION_INDEX ||
+	    bar > VFIO_PCI_BAR5_REGION_INDEX) {
+		RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar);
+		return -1;
+	}
+
+	p->dev = dev;
+	p->base = VFIO_GET_REGION_ADDR(bar);
+	return 0;
+}
+
+void
+pci_vfio_ioport_read(struct rte_pci_ioport *p,
+		     void *data, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
+
+	if (pread64(intr_handle->vfio_dev_fd, data,
+		    len, p->base + offset) <= 0)
+		RTE_LOG(ERR, EAL,
+			"Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n",
+			VFIO_GET_REGION_IDX(p->base), (int)offset);
+}
+
+void
+pci_vfio_ioport_write(struct rte_pci_ioport *p,
+		      const void *data, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
+
+	if (pwrite64(intr_handle->vfio_dev_fd, data,
+		     len, p->base + offset) <= 0)
+		RTE_LOG(ERR, EAL,
+			"Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n",
+			VFIO_GET_REGION_IDX(p->base), (int)offset);
+}
+
+int
+pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
+{
+	RTE_SET_USED(p);
+	return -1;
+}
+
+int
+pci_vfio_enable(void)
+{
+	return vfio_enable("vfio_pci");
+}
+
+int
+pci_vfio_is_enabled(void)
+{
+	return vfio_is_enabled("vfio_pci");
+}
+#endif
diff --git a/drivers/bus/pci/linux/rte_vfio_mp_sync.c b/drivers/bus/pci/linux/rte_vfio_mp_sync.c
new file mode 100644
index 0000000..2c1654d
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_vfio_mp_sync.c
@@ -0,0 +1,424 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <pthread.h>
+
+/* sys/un.h with __USE_MISC uses strlen, which is unsafe */
+#ifdef __USE_MISC
+#define REMOVED_USE_MISC
+#undef __USE_MISC
+#endif
+#include <sys/un.h>
+/* make sure we redefine __USE_MISC only if it was previously undefined */
+#ifdef REMOVED_USE_MISC
+#define __USE_MISC
+#undef REMOVED_USE_MISC
+#endif
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "eal_thread.h"
+#include "rte_pci_init.h"
+
+/**
+ * @file
+ * VFIO socket for communication between primary and secondary processes.
+ *
+ * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
+ */
+
+#ifdef VFIO_PRESENT
+
+#define SOCKET_PATH_FMT "%s/.%s_mp_socket"
+#define CMSGLEN (CMSG_LEN(sizeof(int)))
+#define FD_TO_CMSGHDR(fd, chdr) \
+		do {\
+			(chdr).cmsg_len = CMSGLEN;\
+			(chdr).cmsg_level = SOL_SOCKET;\
+			(chdr).cmsg_type = SCM_RIGHTS;\
+			memcpy((chdr).__cmsg_data, &(fd), sizeof(fd));\
+		} while (0)
+#define CMSGHDR_TO_FD(chdr, fd) \
+			memcpy(&(fd), (chdr).__cmsg_data, sizeof(fd))
+
+static pthread_t socket_thread;
+static int mp_socket_fd;
+
+
+/* get socket path (/var/run if root, $HOME otherwise) */
+static void
+get_socket_path(char *buffer, int bufsz)
+{
+	const char *dir = "/var/run";
+	const char *home_dir = getenv("HOME");
+
+	if (getuid() != 0 && home_dir != NULL)
+		dir = home_dir;
+
+	/* use current prefix as file path */
+	snprintf(buffer, bufsz, SOCKET_PATH_FMT, dir,
+			internal_config.hugefile_prefix);
+}
+
+
+
+/*
+ * data flow for socket comm protocol:
+ * 1. client sends SOCKET_REQ_CONTAINER or SOCKET_REQ_GROUP
+ * 1a. in case of SOCKET_REQ_GROUP, client also then sends group number
+ * 2. server receives message
+ * 2a. in case of invalid group, SOCKET_ERR is sent back to client
+ * 2b. in case of unbound group, SOCKET_NO_FD is sent back to client
+ * 2c. in case of valid group, SOCKET_OK is sent and immediately followed by fd
+ *
+ * in case of any error, socket is closed.
+ */
+
+/* send a request, return -1 on error */
+int
+vfio_mp_sync_send_request(int socket, int req)
+{
+	struct msghdr hdr;
+	struct iovec iov;
+	int buf;
+	int ret;
+
+	memset(&hdr, 0, sizeof(hdr));
+
+	buf = req;
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+
+	ret = sendmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+	return 0;
+}
+
+/* receive a request and return it */
+int
+vfio_mp_sync_receive_request(int socket)
+{
+	int buf;
+	struct msghdr hdr;
+	struct iovec iov;
+	int ret, req;
+
+	memset(&hdr, 0, sizeof(hdr));
+
+	buf = SOCKET_ERR;
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+
+	ret = recvmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+
+	req = buf;
+
+	return req;
+}
+
+/* send OK in message, fd in control message */
+int
+vfio_mp_sync_send_fd(int socket, int fd)
+{
+	int buf;
+	struct msghdr hdr;
+	struct cmsghdr *chdr;
+	char chdr_buf[CMSGLEN];
+	struct iovec iov;
+	int ret;
+
+	chdr = (struct cmsghdr *) chdr_buf;
+	memset(chdr, 0, sizeof(chdr_buf));
+	memset(&hdr, 0, sizeof(hdr));
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+	hdr.msg_control = chdr;
+	hdr.msg_controllen = CMSGLEN;
+
+	buf = SOCKET_OK;
+	FD_TO_CMSGHDR(fd, *chdr);
+
+	ret = sendmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+	return 0;
+}
+
+/* receive OK in message, fd in control message */
+int
+vfio_mp_sync_receive_fd(int socket)
+{
+	int buf;
+	struct msghdr hdr;
+	struct cmsghdr *chdr;
+	char chdr_buf[CMSGLEN];
+	struct iovec iov;
+	int ret, req, fd;
+
+	buf = SOCKET_ERR;
+
+	chdr = (struct cmsghdr *) chdr_buf;
+	memset(chdr, 0, sizeof(chdr_buf));
+	memset(&hdr, 0, sizeof(hdr));
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+	hdr.msg_control = chdr;
+	hdr.msg_controllen = CMSGLEN;
+
+	ret = recvmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+
+	req = buf;
+
+	if (req != SOCKET_OK)
+		return -1;
+
+	CMSGHDR_TO_FD(*chdr, fd);
+
+	return fd;
+}
+
+/* connect socket_fd in secondary process to the primary process's socket */
+int
+vfio_mp_sync_connect_to_primary(void)
+{
+	struct sockaddr_un addr;
+	socklen_t sockaddr_len;
+	int socket_fd;
+
+	/* set up a socket */
+	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+	if (socket_fd < 0) {
+		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
+		return -1;
+	}
+
+	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
+	addr.sun_family = AF_UNIX;
+
+	sockaddr_len = sizeof(struct sockaddr_un);
+
+	if (connect(socket_fd, (struct sockaddr *) &addr, sockaddr_len) == 0)
+		return socket_fd;
+
+	/* if connect failed */
+	close(socket_fd);
+	return -1;
+}
+
+
+
+/*
+ * socket listening thread for primary process
+ */
+static __attribute__((noreturn)) void *
+vfio_mp_sync_thread(void __rte_unused * arg)
+{
+	int ret, fd, vfio_data;
+
+	/* wait for requests on the socket */
+	for (;;) {
+		int conn_sock;
+		struct sockaddr_un addr;
+		socklen_t sockaddr_len = sizeof(addr);
+
+		/* this is a blocking call */
+		conn_sock = accept(mp_socket_fd, (struct sockaddr *) &addr,
+				&sockaddr_len);
+
+		/* just restart on error */
+		if (conn_sock == -1)
+			continue;
+
+		/* set socket to linger after close */
+		struct linger l;
+		l.l_onoff = 1;
+		l.l_linger = 60;
+
+		if (setsockopt(conn_sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0)
+			RTE_LOG(WARNING, EAL, "Cannot set SO_LINGER option "
+					"on listen socket (%s)\n", strerror(errno));
+
+		ret = vfio_mp_sync_receive_request(conn_sock);
+
+		switch (ret) {
+		case SOCKET_REQ_CONTAINER:
+			fd = vfio_get_container_fd();
+			if (fd < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			else
+				vfio_mp_sync_send_fd(conn_sock, fd);
+			close(fd);
+			break;
+		case SOCKET_REQ_GROUP:
+			/* wait for group number */
+			vfio_data = vfio_mp_sync_receive_request(conn_sock);
+			if (vfio_data < 0) {
+				close(conn_sock);
+				continue;
+			}
+
+			fd = vfio_get_group_fd(vfio_data);
+
+			if (fd < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			/* if VFIO group exists but isn't bound to VFIO driver */
+			else if (fd == 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
+			/* if group exists and is bound to VFIO driver */
+			else {
+				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
+				vfio_mp_sync_send_fd(conn_sock, fd);
+			}
+			break;
+		case SOCKET_CLR_GROUP:
+			/* wait for group fd */
+			vfio_data = vfio_mp_sync_receive_request(conn_sock);
+			if (vfio_data < 0) {
+				close(conn_sock);
+				continue;
+			}
+
+			ret = clear_group(vfio_data);
+
+			if (ret < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
+			else
+				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
+			break;
+		default:
+			vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			break;
+		}
+		close(conn_sock);
+	}
+}
+
+static int
+vfio_mp_sync_socket_setup(void)
+{
+	int ret, socket_fd;
+	struct sockaddr_un addr;
+	socklen_t sockaddr_len;
+
+	/* set up a socket */
+	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+	if (socket_fd < 0) {
+		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
+		return -1;
+	}
+
+	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
+	addr.sun_family = AF_UNIX;
+
+	sockaddr_len = sizeof(struct sockaddr_un);
+
+	unlink(addr.sun_path);
+
+	ret = bind(socket_fd, (struct sockaddr *) &addr, sockaddr_len);
+	if (ret) {
+		RTE_LOG(ERR, EAL, "Failed to bind socket: %s!\n", strerror(errno));
+		close(socket_fd);
+		return -1;
+	}
+
+	ret = listen(socket_fd, 50);
+	if (ret) {
+		RTE_LOG(ERR, EAL, "Failed to listen: %s!\n", strerror(errno));
+		close(socket_fd);
+		return -1;
+	}
+
+	/* save the socket in local configuration */
+	mp_socket_fd = socket_fd;
+
+	return 0;
+}
+
+/*
+ * set up a local socket and tell it to listen for incoming connections
+ */
+int
+vfio_mp_sync_setup(void)
+{
+	int ret;
+	char thread_name[RTE_MAX_THREAD_NAME_LEN];
+
+	if (vfio_mp_sync_socket_setup() < 0) {
+		RTE_LOG(ERR, EAL, "Failed to set up local socket!\n");
+		return -1;
+	}
+
+	ret = pthread_create(&socket_thread, NULL,
+			vfio_mp_sync_thread, NULL);
+	if (ret) {
+		RTE_LOG(ERR, EAL,
+			"Failed to create thread for communication with secondary processes!\n");
+		close(mp_socket_fd);
+		return -1;
+	}
+
+	/* Set thread_name for aid in debugging. */
+	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "vfio-sync");
+	ret = rte_thread_setname(socket_thread, thread_name);
+	if (ret)
+		RTE_LOG(DEBUG, EAL,
+			"Failed to set thread name for secondary processes!\n");
+
+	return 0;
+}
+
+#endif
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
new file mode 100644
index 0000000..7ff1fc4
--- /dev/null
+++ b/drivers/bus/pci/private.h
@@ -0,0 +1,173 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PCI_PRIVATE_H_
+#define _PCI_PRIVATE_H_
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <rte_pci.h>
+
+struct rte_pci_driver;
+struct rte_pci_device;
+
+/**
+ * Find the name of a PCI device.
+ */
+void
+pci_name_set(struct rte_pci_device *dev);
+
+/**
+ * Add a PCI device to the PCI Bus (append to PCI Device list). This function
+ * also updates the bus references of the PCI Device (and the generic device
+ * object embedded within.
+ *
+ * @param pci_dev
+ *	PCI device to add
+ * @return void
+ */
+void rte_pci_add_device(struct rte_pci_device *pci_dev);
+
+/**
+ * Insert a PCI device in the PCI Bus at a particular location in the device
+ * list. It also updates the PCI Bus reference of the new devices to be
+ * inserted.
+ *
+ * @param exist_pci_dev
+ *	Existing PCI device in PCI Bus
+ * @param new_pci_dev
+ *	PCI device to be added before exist_pci_dev
+ * @return void
+ */
+void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+		struct rte_pci_device *new_pci_dev);
+
+/**
+ * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
+ * in the PCI device object as well as the generic device object.
+ *
+ * @param pci_device
+ *	PCI device to be removed from PCI Bus
+ * @return void
+ */
+void rte_pci_remove_device(struct rte_pci_device *pci_device);
+
+/**
+ * Update a pci device object by asking the kernel for the latest information.
+ *
+ * This function is private to EAL.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to look for
+ * @return
+ *   - 0 on success.
+ *   - negative on error.
+ */
+int pci_update_device(const struct rte_pci_addr *addr);
+
+/**
+ * Unbind kernel driver for this device
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_unbind_kernel_driver(struct rte_pci_device *dev);
+
+/**
+ * Map the PCI resource of a PCI device in virtual memory
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_map_resource(struct rte_pci_device *dev);
+
+/**
+ * Unmap the PCI resource of a PCI device
+ *
+ * This function is private to EAL.
+ */
+void pci_uio_unmap_resource(struct rte_pci_device *dev);
+
+/**
+ * Allocate uio resource for PCI device
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device to allocate uio resource
+ * @param uio_res
+ *   Pointer to uio resource.
+ *   If the function returns 0, the pointer will be filled.
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res);
+
+/**
+ * Free uio resource for PCI device
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device to free uio resource
+ * @param uio_res
+ *   Pointer to uio resource.
+ */
+void pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res);
+
+/**
+ * Map device memory to uio resource
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device that has memory information.
+ * @param res_idx
+ *   Memory resource index of the PCI device.
+ * @param uio_res
+ *  uio resource that will keep mapping information.
+ * @param map_idx
+ *   Mapping information index of the uio resource.
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx);
+
+#endif /* _PCI_PRIVATE_H_ */
diff --git a/drivers/bus/pci/rte_bus_pci_version.map b/drivers/bus/pci/rte_bus_pci_version.map
new file mode 100644
index 0000000..eca49e9
--- /dev/null
+++ b/drivers/bus/pci/rte_bus_pci_version.map
@@ -0,0 +1,21 @@
+DPDK_17.08 {
+	global:
+
+	rte_pci_detach;
+	rte_pci_dump;
+	rte_pci_ioport_map;
+	rte_pci_ioport_read;
+	rte_pci_ioport_unmap;
+	rte_pci_ioport_write;
+	rte_pci_map_device;
+	rte_pci_probe;
+	rte_pci_probe_one;
+	rte_pci_read_config;
+	rte_pci_register;
+	rte_pci_scan;
+	rte_pci_unmap_device;
+	rte_pci_unregister;
+	rte_pci_write_config;
+
+	local: *;
+};
diff --git a/drivers/bus/pci/rte_pci_common.c b/drivers/bus/pci/rte_pci_common.c
new file mode 100644
index 0000000..c37b85b
--- /dev/null
+++ b/drivers/bus/pci/rte_pci_common.c
@@ -0,0 +1,542 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+
+#include "private.h"
+
+extern struct rte_pci_bus rte_pci_bus;
+
+#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
+
+const char *pci_get_sysfs_path(void)
+{
+	const char *path = NULL;
+
+	path = getenv("SYSFS_PCI_DEVICES");
+	if (path == NULL)
+		return SYSFS_PCI_DEVICES;
+
+	return path;
+}
+
+static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
+{
+	struct rte_devargs *devargs;
+	struct rte_pci_addr addr;
+	struct rte_bus *pbus;
+
+	pbus = rte_bus_find_by_name("pci");
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->bus != pbus)
+			continue;
+		devargs->bus->parse(devargs->name, &addr);
+		if (!rte_eal_compare_pci_addr(&dev->addr, &addr))
+			return devargs;
+	}
+	return NULL;
+}
+
+void
+pci_name_set(struct rte_pci_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	/* Each device has its internal, canonical name set. */
+	rte_pci_device_name(&dev->addr,
+			dev->name, sizeof(dev->name));
+	devargs = pci_devargs_lookup(dev);
+	dev->device.devargs = devargs;
+	/* In blacklist mode, if the device is not blacklisted, no
+	 * rte_devargs exists for it.
+	 */
+	if (devargs != NULL)
+		/* If an rte_devargs exists, the generic rte_device uses the
+		 * given name as its namea
+		 */
+		dev->device.name = dev->device.devargs->name;
+	else
+		/* Otherwise, it uses the internal, canonical form. */
+		dev->device.name = dev->name;
+}
+
+/*
+ * Match the PCI Driver and Device using the ID Table
+ *
+ * @param pci_drv
+ *	PCI driver from which ID table would be extracted
+ * @param pci_dev
+ *	PCI device to match against the driver
+ * @return
+ *	1 for successful match
+ *	0 for unsuccessful match
+ */
+static int
+rte_pci_match(const struct rte_pci_driver *pci_drv,
+	      const struct rte_pci_device *pci_dev)
+{
+	const struct rte_pci_id *id_table;
+
+	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
+	     id_table++) {
+		/* check if device's identifiers match the driver's ones */
+		if (id_table->vendor_id != pci_dev->id.vendor_id &&
+				id_table->vendor_id != PCI_ANY_ID)
+			continue;
+		if (id_table->device_id != pci_dev->id.device_id &&
+				id_table->device_id != PCI_ANY_ID)
+			continue;
+		if (id_table->subsystem_vendor_id !=
+		    pci_dev->id.subsystem_vendor_id &&
+		    id_table->subsystem_vendor_id != PCI_ANY_ID)
+			continue;
+		if (id_table->subsystem_device_id !=
+		    pci_dev->id.subsystem_device_id &&
+		    id_table->subsystem_device_id != PCI_ANY_ID)
+			continue;
+		if (id_table->class_id != pci_dev->id.class_id &&
+				id_table->class_id != RTE_CLASS_ANY_ID)
+			continue;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * If vendor/device ID match, call the probe() function of the
+ * driver.
+ */
+static int
+rte_pci_probe_one_driver(struct rte_pci_driver *dr,
+			 struct rte_pci_device *dev)
+{
+	int ret;
+	struct rte_pci_addr *loc;
+
+	if ((dr == NULL) || (dev == NULL))
+		return -EINVAL;
+
+	loc = &dev->addr;
+
+	/* The device is not blacklisted; Check if driver supports it */
+	if (!rte_pci_match(dr, dev))
+		/* Match of device and driver failed */
+		return 1;
+
+	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			loc->domain, loc->bus, loc->devid, loc->function,
+			dev->device.numa_node);
+
+	/* no initialization when blacklisted, return without error */
+	if (dev->device.devargs != NULL &&
+		dev->device.devargs->policy ==
+			RTE_DEV_BLACKLISTED) {
+		RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
+			" initializing\n");
+		return 1;
+	}
+
+	if (dev->device.numa_node < 0) {
+		RTE_LOG(WARNING, EAL, "  Invalid NUMA socket, default to 0\n");
+		dev->device.numa_node = 0;
+	}
+
+	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
+		dev->id.device_id, dr->driver.name);
+
+	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+		/* map resources for devices that use igb_uio */
+		ret = rte_pci_map_device(dev);
+		if (ret != 0)
+			return ret;
+	}
+
+	/* reference driver structure */
+	dev->driver = dr;
+	dev->device.driver = &dr->driver;
+
+	/* call the driver probe() function */
+	ret = dr->probe(dr, dev);
+	if (ret) {
+		dev->driver = NULL;
+		dev->device.driver = NULL;
+		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
+			/* Don't unmap if device is unsupported and
+			 * driver needs mapped resources.
+			 */
+			!(ret > 0 &&
+				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
+			rte_pci_unmap_device(dev);
+	}
+
+	return ret;
+}
+
+/*
+ * If vendor/device ID match, call the remove() function of the
+ * driver.
+ */
+static int
+rte_pci_detach_dev(struct rte_pci_device *dev)
+{
+	struct rte_pci_addr *loc;
+	struct rte_pci_driver *dr;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	dr = dev->driver;
+	loc = &dev->addr;
+
+	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			loc->domain, loc->bus, loc->devid,
+			loc->function, dev->device.numa_node);
+
+	RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
+			dev->id.device_id, dr->driver.name);
+
+	if (dr->remove && (dr->remove(dev) < 0))
+		return -1;	/* negative value is an error */
+
+	/* clear driver structure */
+	dev->driver = NULL;
+
+	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
+		/* unmap resources for devices that use igb_uio */
+		rte_pci_unmap_device(dev);
+
+	return 0;
+}
+
+/*
+ * If vendor/device ID match, call the probe() function of all
+ * registered driver for the given device. Return -1 if initialization
+ * failed, return 1 if no driver is found for this device.
+ */
+static int
+pci_probe_all_drivers(struct rte_pci_device *dev)
+{
+	struct rte_pci_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	/* Check if a driver is already loaded */
+	if (dev->driver != NULL)
+		return 0;
+
+	FOREACH_DRIVER_ON_PCIBUS(dr) {
+		rc = rte_pci_probe_one_driver(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * Find the pci device specified by pci address, then invoke probe function of
+ * the driver of the device.
+ */
+int
+rte_pci_probe_one(const struct rte_pci_addr *addr)
+{
+	struct rte_pci_device *dev = NULL;
+
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	/* update current pci device in global list, kernel bindings might have
+	 * changed since last time we looked at it.
+	 */
+	if (pci_update_device(addr) < 0)
+		goto err_return;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (rte_eal_compare_pci_addr(&dev->addr, addr))
+			continue;
+
+		ret = pci_probe_all_drivers(dev);
+		if (ret)
+			goto err_return;
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL,
+		"Requested device " PCI_PRI_FMT " cannot be used\n",
+		addr->domain, addr->bus, addr->devid, addr->function);
+	return -1;
+}
+
+/*
+ * Detach device specified by its pci address.
+ */
+int
+rte_pci_detach(const struct rte_pci_addr *addr)
+{
+	struct rte_pci_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (rte_eal_compare_pci_addr(&dev->addr, addr))
+			continue;
+
+		ret = rte_pci_detach_dev(dev);
+		if (ret < 0)
+			/* negative value is an error */
+			goto err_return;
+		if (ret > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+
+		rte_pci_remove_device(dev);
+		free(dev);
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
+			" cannot be used\n", dev->addr.domain, dev->addr.bus,
+			dev->addr.devid, dev->addr.function);
+	return -1;
+}
+
+/*
+ * Scan the content of the PCI bus, and call the probe() function for
+ * all registered drivers that have a matching entry in its id_table
+ * for discovered devices.
+ */
+int
+rte_pci_probe(void)
+{
+	struct rte_pci_device *dev = NULL;
+	size_t probed = 0, failed = 0;
+	struct rte_devargs *devargs;
+	int probe_all = 0;
+	int ret = 0;
+
+	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
+		probe_all = 1;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		probed++;
+
+		devargs = dev->device.devargs;
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = pci_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->policy == RTE_DEV_WHITELISTED)
+			ret = pci_probe_all_drivers(dev);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
+				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
+				 dev->addr.devid, dev->addr.function);
+			rte_errno = errno;
+			failed++;
+			ret = 0;
+		}
+	}
+
+	return (probed && probed == failed) ? -1 : 0;
+}
+
+/* dump one device */
+static int
+pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
+{
+	int i;
+
+	fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
+	       dev->addr.devid, dev->addr.function);
+	fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
+	       dev->id.device_id);
+
+	for (i = 0; i != sizeof(dev->mem_resource) /
+		sizeof(dev->mem_resource[0]); i++) {
+		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
+			dev->mem_resource[i].phys_addr,
+			dev->mem_resource[i].len);
+	}
+	return 0;
+}
+
+/* dump devices on the bus */
+void
+rte_pci_dump(FILE *f)
+{
+	struct rte_pci_device *dev = NULL;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		pci_dump_one_device(f, dev);
+	}
+}
+
+static int
+pci_parse(const char *name, void *addr)
+{
+	struct rte_pci_addr *out = addr;
+	struct rte_pci_addr pci_addr;
+	bool parse;
+
+	parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
+		 eal_parse_pci_DomBDF(name, &pci_addr) == 0);
+	if (parse && addr != NULL)
+		*out = pci_addr;
+	return parse == false;
+}
+
+/* register a driver */
+void
+rte_pci_register(struct rte_pci_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
+	driver->bus = &rte_pci_bus;
+}
+
+/* unregister a driver */
+void
+rte_pci_unregister(struct rte_pci_driver *driver)
+{
+	TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
+	driver->bus = NULL;
+}
+
+/* Add a device to PCI bus */
+void
+rte_pci_add_device(struct rte_pci_device *pci_dev)
+{
+	TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
+}
+
+/* Insert a device into a predefined position in PCI bus */
+void
+rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+		      struct rte_pci_device *new_pci_dev)
+{
+	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
+}
+
+/* Remove a device from PCI bus */
+void
+rte_pci_remove_device(struct rte_pci_device *pci_dev)
+{
+	TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
+}
+
+static struct rte_device *
+pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		const void *data)
+{
+	struct rte_pci_device *dev;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (start && &dev->device == start) {
+			start = NULL; /* starting point found */
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+
+	return NULL;
+}
+
+static int
+pci_plug(struct rte_device *dev)
+{
+	return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
+}
+
+static int
+pci_unplug(struct rte_device *dev)
+{
+	struct rte_pci_device *pdev;
+	int ret;
+
+	pdev = RTE_DEV_TO_PCI(dev);
+	ret = rte_pci_detach_dev(pdev);
+	rte_pci_remove_device(pdev);
+	free(pdev);
+	return ret;
+}
+
+struct rte_pci_bus rte_pci_bus = {
+	.bus = {
+		.scan = rte_pci_scan,
+		.probe = rte_pci_probe,
+		.find_device = pci_find_device,
+		.plug = pci_plug,
+		.unplug = pci_unplug,
+		.parse = pci_parse,
+	},
+	.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
+	.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(pci, rte_pci_bus.bus);
diff --git a/drivers/bus/pci/rte_pci_common_uio.c b/drivers/bus/pci/rte_pci_common_uio.c
new file mode 100644
index 0000000..4365660
--- /dev/null
+++ b/drivers/bus/pci/rte_pci_common_uio.c
@@ -0,0 +1,234 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_tailq.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+
+#include "private.h"
+
+static struct rte_tailq_elem rte_uio_tailq = {
+	.name = "UIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_uio_tailq)
+
+static int
+pci_uio_map_secondary(struct rte_pci_device *dev)
+{
+	int fd, i, j;
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	TAILQ_FOREACH(uio_res, uio_res_list, next) {
+
+		/* skip this element if it doesn't match our PCI address */
+		if (rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+			continue;
+
+		for (i = 0; i != uio_res->nb_maps; i++) {
+			/*
+			 * open devname, to mmap it
+			 */
+			fd = open(uio_res->maps[i].path, O_RDWR);
+			if (fd < 0) {
+				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+					uio_res->maps[i].path, strerror(errno));
+				return -1;
+			}
+
+			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
+					fd, (off_t)uio_res->maps[i].offset,
+					(size_t)uio_res->maps[i].size, 0);
+			/* fd is not needed in slave process, close it */
+			close(fd);
+			if (mapaddr != uio_res->maps[i].addr) {
+				RTE_LOG(ERR, EAL,
+					"Cannot mmap device resource file %s to address: %p\n",
+					uio_res->maps[i].path,
+					uio_res->maps[i].addr);
+				if (mapaddr != MAP_FAILED) {
+					/* unmap addrs correctly mapped */
+					for (j = 0; j < i; j++)
+						pci_unmap_resource(
+							uio_res->maps[j].addr,
+							(size_t)uio_res->maps[j].size);
+					/* unmap addr wrongly mapped */
+					pci_unmap_resource(mapaddr,
+						(size_t)uio_res->maps[i].size);
+				}
+				return -1;
+			}
+		}
+		return 0;
+	}
+
+	RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
+	return 1;
+}
+
+/* map the PCI resource of a PCI device in virtual memory */
+int
+pci_uio_map_resource(struct rte_pci_device *dev)
+{
+	int i, map_idx = 0, ret;
+	uint64_t phaddr;
+	struct mapped_pci_resource *uio_res = NULL;
+	struct mapped_pci_res_list *uio_res_list =
+		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.uio_cfg_fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* secondary processes - use already recorded details */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return pci_uio_map_secondary(dev);
+
+	/* allocate uio resource */
+	ret = pci_uio_alloc_resource(dev, &uio_res);
+	if (ret)
+		return ret;
+
+	/* Map all BARs */
+	for (i = 0; i != PCI_MAX_RESOURCE; i++) {
+		/* skip empty BAR */
+		phaddr = dev->mem_resource[i].phys_addr;
+		if (phaddr == 0)
+			continue;
+
+		ret = pci_uio_map_resource_by_index(dev, i,
+				uio_res, map_idx);
+		if (ret)
+			goto error;
+
+		map_idx++;
+	}
+
+	uio_res->nb_maps = map_idx;
+
+	TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
+
+	return 0;
+error:
+	for (i = 0; i < map_idx; i++) {
+		pci_unmap_resource(uio_res->maps[i].addr,
+				(size_t)uio_res->maps[i].size);
+		rte_free(uio_res->maps[i].path);
+	}
+	pci_uio_free_resource(dev, uio_res);
+	return -1;
+}
+
+static void
+pci_uio_unmap(struct mapped_pci_resource *uio_res)
+{
+	int i;
+
+	if (uio_res == NULL)
+		return;
+
+	for (i = 0; i != uio_res->nb_maps; i++) {
+		pci_unmap_resource(uio_res->maps[i].addr,
+				(size_t)uio_res->maps[i].size);
+		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+			rte_free(uio_res->maps[i].path);
+	}
+}
+
+static struct mapped_pci_resource *
+pci_uio_find_resource(struct rte_pci_device *dev)
+{
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	if (dev == NULL)
+		return NULL;
+
+	TAILQ_FOREACH(uio_res, uio_res_list, next) {
+
+		/* skip this element if it doesn't match our PCI address */
+		if (!rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+			return uio_res;
+	}
+	return NULL;
+}
+
+/* unmap the PCI resource of a PCI device in virtual memory */
+void
+pci_uio_unmap_resource(struct rte_pci_device *dev)
+{
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	if (dev == NULL)
+		return;
+
+	/* find an entry for the device */
+	uio_res = pci_uio_find_resource(dev);
+	if (uio_res == NULL)
+		return;
+
+	/* secondary processes - just free maps */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return pci_uio_unmap(uio_res);
+
+	TAILQ_REMOVE(uio_res_list, uio_res, next);
+
+	/* unmap all resources */
+	pci_uio_unmap(uio_res);
+
+	/* free uio resource */
+	rte_free(uio_res);
+
+	/* close fd if in primary process */
+	close(dev->intr_handle.fd);
+	if (dev->intr_handle.uio_cfg_fd >= 0) {
+		close(dev->intr_handle.uio_cfg_fd);
+		dev->intr_handle.uio_cfg_fd = -1;
+	}
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+}
diff --git a/lib/Makefile b/lib/Makefile
index 86caba1..147be60 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-y += librte_compat
 DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
+DIRS-$(CONFIG_RTE_LIBRTE_PCI) += librte_pci
+DEPDIRS-librte_pci := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
 DEPDIRS-librte_ring := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 005019e..e5273f7 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -55,7 +55,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
@@ -69,8 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_errno.c
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
deleted file mode 100644
index 04eacdc..0000000
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ /dev/null
@@ -1,670 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-#include <limits.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/pciio.h>
-#include <dev/pci/pcireg.h>
-
-#if defined(RTE_ARCH_X86)
-#include <machine/cpufunc.h>
-#endif
-
-#include <rte_interrupts.h>
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_common.h>
-#include <rte_launch.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_eal.h>
-#include <rte_eal_memconfig.h>
-#include <rte_per_lcore.h>
-#include <rte_lcore.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-#include <rte_debug.h>
-#include <rte_devargs.h>
-
-#include "eal_filesystem.h"
-#include "eal_private.h"
-
-/**
- * @file
- * PCI probing under linux
- *
- * This code is used to simulate a PCI probe by parsing information in
- * sysfs. Moreover, when a registered driver matches a device, the
- * kernel driver currently using it is unloaded and replaced by
- * igb_uio module, which is a very minimal userland driver for Intel
- * network card, only providing access to PCI BAR to applications, and
- * enabling bus master.
- */
-
-extern struct rte_pci_bus rte_pci_bus;
-
-/* Map pci device */
-int
-rte_pci_map_device(struct rte_pci_device *dev)
-{
-	int ret = -1;
-
-	/* try mapping the NIC resources */
-	switch (dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		/* map resources for devices that use uio */
-		ret = pci_uio_map_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		ret = 1;
-		break;
-	}
-
-	return ret;
-}
-
-/* Unmap pci device */
-void
-rte_pci_unmap_device(struct rte_pci_device *dev)
-{
-	/* try unmapping the NIC resources */
-	switch (dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		/* unmap resources for devices that use uio */
-		pci_uio_unmap_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		break;
-	}
-}
-
-void
-pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res)
-{
-	rte_free(uio_res);
-
-	if (dev->intr_handle.fd) {
-		close(dev->intr_handle.fd);
-		dev->intr_handle.fd = -1;
-		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	}
-}
-
-int
-pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res)
-{
-	char devname[PATH_MAX]; /* contains the /dev/uioX */
-	struct rte_pci_addr *loc;
-
-	loc = &dev->addr;
-
-	snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
-			dev->addr.bus, dev->addr.devid, dev->addr.function);
-
-	if (access(devname, O_RDWR) < 0) {
-		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
-				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
-		return 1;
-	}
-
-	/* save fd if in primary process */
-	dev->intr_handle.fd = open(devname, O_RDWR);
-	if (dev->intr_handle.fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			devname, strerror(errno));
-		goto error;
-	}
-	dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-
-	/* allocate the mapping details for secondary processes*/
-	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
-	if (*uio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto error;
-	}
-
-	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
-	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
-
-	return 0;
-
-error:
-	pci_uio_free_resource(dev, *uio_res);
-	return -1;
-}
-
-int
-pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx)
-{
-	int fd;
-	char *devname;
-	void *mapaddr;
-	uint64_t offset;
-	uint64_t pagesz;
-	struct pci_map *maps;
-
-	maps = uio_res->maps;
-	devname = uio_res->path;
-	pagesz = sysconf(_SC_PAGESIZE);
-
-	/* allocate memory to keep path */
-	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
-	if (maps[map_idx].path == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
-				strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * open resource file, to mmap it
-	 */
-	fd = open(devname, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				devname, strerror(errno));
-		goto error;
-	}
-
-	/* if matching map is found, then use it */
-	offset = res_idx * pagesz;
-	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
-			(size_t)dev->mem_resource[res_idx].len, 0);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		goto error;
-
-	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
-	maps[map_idx].size = dev->mem_resource[res_idx].len;
-	maps[map_idx].addr = mapaddr;
-	maps[map_idx].offset = offset;
-	strcpy(maps[map_idx].path, devname);
-	dev->mem_resource[res_idx].addr = mapaddr;
-
-	return 0;
-
-error:
-	rte_free(maps[map_idx].path);
-	return -1;
-}
-
-static int
-pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
-{
-	struct rte_pci_device *dev;
-	struct pci_bar_io bar;
-	unsigned i, max;
-
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL) {
-		return -1;
-	}
-
-	memset(dev, 0, sizeof(*dev));
-	dev->addr.domain = conf->pc_sel.pc_domain;
-	dev->addr.bus = conf->pc_sel.pc_bus;
-	dev->addr.devid = conf->pc_sel.pc_dev;
-	dev->addr.function = conf->pc_sel.pc_func;
-
-	/* get vendor id */
-	dev->id.vendor_id = conf->pc_vendor;
-
-	/* get device id */
-	dev->id.device_id = conf->pc_device;
-
-	/* get subsystem_vendor id */
-	dev->id.subsystem_vendor_id = conf->pc_subvendor;
-
-	/* get subsystem_device id */
-	dev->id.subsystem_device_id = conf->pc_subdevice;
-
-	/* get class id */
-	dev->id.class_id = (conf->pc_class << 16) |
-			   (conf->pc_subclass << 8) |
-			   (conf->pc_progif);
-
-	/* TODO: get max_vfs */
-	dev->max_vfs = 0;
-
-	/* FreeBSD has no NUMA support (yet) */
-	dev->device.numa_node = 0;
-
-	pci_name_set(dev);
-
-	/* FreeBSD has only one pass through driver */
-	dev->kdrv = RTE_KDRV_NIC_UIO;
-
-	/* parse resources */
-	switch (conf->pc_hdr & PCIM_HDRTYPE) {
-	case PCIM_HDRTYPE_NORMAL:
-		max = PCIR_MAX_BAR_0;
-		break;
-	case PCIM_HDRTYPE_BRIDGE:
-		max = PCIR_MAX_BAR_1;
-		break;
-	case PCIM_HDRTYPE_CARDBUS:
-		max = PCIR_MAX_BAR_2;
-		break;
-	default:
-		goto skipdev;
-	}
-
-	for (i = 0; i <= max; i++) {
-		bar.pbi_sel = conf->pc_sel;
-		bar.pbi_reg = PCIR_BAR(i);
-		if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
-			continue;
-
-		dev->mem_resource[i].len = bar.pbi_length;
-		if (PCI_BAR_IO(bar.pbi_base)) {
-			dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
-			continue;
-		}
-		dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
-	}
-
-	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-		rte_pci_add_device(dev);
-	}
-	else {
-		struct rte_pci_device *dev2 = NULL;
-		int ret;
-
-		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
-			if (ret > 0)
-				continue;
-			else if (ret < 0) {
-				rte_pci_insert_device(dev2, dev);
-			} else { /* already registered */
-				dev2->kdrv = dev->kdrv;
-				dev2->max_vfs = dev->max_vfs;
-				pci_name_set(dev2);
-				memmove(dev2->mem_resource,
-					dev->mem_resource,
-					sizeof(dev->mem_resource));
-				free(dev);
-			}
-			return 0;
-		}
-		rte_pci_add_device(dev);
-	}
-
-	return 0;
-
-skipdev:
-	free(dev);
-	return 0;
-}
-
-/*
- * Scan the content of the PCI bus, and add the devices in the devices
- * list. Call pci_scan_one() for each pci entry found.
- */
-int
-rte_pci_scan(void)
-{
-	int fd;
-	unsigned dev_count = 0;
-	struct pci_conf matches[16];
-	struct pci_conf_io conf_io = {
-			.pat_buf_len = 0,
-			.num_patterns = 0,
-			.patterns = NULL,
-			.match_buf_len = sizeof(matches),
-			.matches = &matches[0],
-	};
-
-	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
-		return 0;
-
-	fd = open("/dev/pci", O_RDONLY);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	do {
-		unsigned i;
-		if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
-			RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
-					__func__, strerror(errno));
-			goto error;
-		}
-
-		for (i = 0; i < conf_io.num_matches; i++)
-			if (pci_scan_one(fd, &matches[i]) < 0)
-				goto error;
-
-		dev_count += conf_io.num_matches;
-	} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
-
-	close(fd);
-
-	RTE_LOG(DEBUG, EAL, "PCI scan found %u devices\n", dev_count);
-	return 0;
-
-error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-int
-pci_update_device(const struct rte_pci_addr *addr)
-{
-	int fd;
-	struct pci_conf matches[2];
-	struct pci_match_conf match = {
-		.pc_sel = {
-			.pc_domain = addr->domain,
-			.pc_bus = addr->bus,
-			.pc_dev = addr->devid,
-			.pc_func = addr->function,
-		},
-	};
-	struct pci_conf_io conf_io = {
-		.pat_buf_len = 0,
-		.num_patterns = 1,
-		.patterns = &match,
-		.match_buf_len = sizeof(matches),
-		.matches = &matches[0],
-	};
-
-	fd = open("/dev/pci", O_RDONLY);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
-				__func__, strerror(errno));
-		goto error;
-	}
-
-	if (conf_io.num_matches != 1)
-		goto error;
-
-	if (pci_scan_one(fd, &matches[0]) < 0)
-		goto error;
-
-	close(fd);
-
-	return 0;
-
-error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/* Read PCI config space. */
-int rte_pci_read_config(const struct rte_pci_device *dev,
-		void *buf, size_t len, off_t offset)
-{
-	int fd = -1;
-	int size;
-	struct pci_io pi = {
-		.pi_sel = {
-			.pc_domain = dev->addr.domain,
-			.pc_bus = dev->addr.bus,
-			.pc_dev = dev->addr.devid,
-			.pc_func = dev->addr.function,
-		},
-		.pi_reg = offset,
-	};
-
-	fd = open("/dev/pci", O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	while (len > 0) {
-		size = (len >= 4) ? 4 : ((len >= 2) ? 2 : 1);
-		pi.pi_width = size;
-
-		if (ioctl(fd, PCIOCREAD, &pi) < 0)
-			goto error;
-		memcpy(buf, &pi.pi_data, size);
-
-		buf = (char *)buf + size;
-		pi.pi_reg += size;
-		len -= size;
-	}
-	close(fd);
-
-	return 0;
-
- error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/* Write PCI config space. */
-int rte_pci_write_config(const struct rte_pci_device *dev,
-		const void *buf, size_t len, off_t offset)
-{
-	int fd = -1;
-
-	struct pci_io pi = {
-		.pi_sel = {
-			.pc_domain = dev->addr.domain,
-			.pc_bus = dev->addr.bus,
-			.pc_dev = dev->addr.devid,
-			.pc_func = dev->addr.function,
-		},
-		.pi_reg = offset,
-		.pi_data = *(const uint32_t *)buf,
-		.pi_width = len,
-	};
-
-	if (len == 3 || len > sizeof(pi.pi_data)) {
-		RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__);
-		goto error;
-	}
-
-	memcpy(&pi.pi_data, buf, len);
-
-	fd = open("/dev/pci", O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	if (ioctl(fd, PCIOCWRITE, &pi) < 0)
-		goto error;
-
-	close(fd);
-	return 0;
-
- error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-int
-rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p)
-{
-	int ret;
-
-	switch (dev->kdrv) {
-#if defined(RTE_ARCH_X86)
-	case RTE_KDRV_NIC_UIO:
-		if ((uintptr_t) dev->mem_resource[bar].addr <= UINT16_MAX) {
-			p->base = (uintptr_t)dev->mem_resource[bar].addr;
-			ret = 0;
-		} else
-			ret = -1;
-		break;
-#endif
-	default:
-		ret = -1;
-		break;
-	}
-
-	if (!ret)
-		p->dev = dev;
-
-	return ret;
-}
-
-static void
-pci_uio_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-#if defined(RTE_ARCH_X86)
-	uint8_t *d;
-	int size;
-	unsigned short reg = p->base + offset;
-
-	for (d = data; len > 0; d += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-			*(uint32_t *)d = inl(reg);
-		} else if (len >= 2) {
-			size = 2;
-			*(uint16_t *)d = inw(reg);
-		} else {
-			size = 1;
-			*d = inb(reg);
-		}
-	}
-#else
-	RTE_SET_USED(p);
-	RTE_SET_USED(data);
-	RTE_SET_USED(len);
-	RTE_SET_USED(offset);
-#endif
-}
-
-void
-rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	default:
-		break;
-	}
-}
-
-static void
-pci_uio_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-#if defined(RTE_ARCH_X86)
-	const uint8_t *s;
-	int size;
-	unsigned short reg = p->base + offset;
-
-	for (s = data; len > 0; s += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-			outl(reg, *(const uint32_t *)s);
-		} else if (len >= 2) {
-			size = 2;
-			outw(reg, *(const uint16_t *)s);
-		} else {
-			size = 1;
-			outb(reg, *s);
-		}
-	}
-#else
-	RTE_SET_USED(p);
-	RTE_SET_USED(data);
-	RTE_SET_USED(len);
-	RTE_SET_USED(offset);
-#endif
-}
-
-void
-rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	default:
-		break;
-	}
-}
-
-int
-rte_pci_ioport_unmap(struct rte_pci_ioport *p)
-{
-	int ret;
-
-	switch (p->dev->kdrv) {
-#if defined(RTE_ARCH_X86)
-	case RTE_KDRV_NIC_UIO:
-		ret = 0;
-		break;
-#endif
-	default:
-		ret = -1;
-		break;
-	}
-
-	return ret;
-}
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index cff7d18..3ed3283 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -169,21 +169,6 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_pci_detach;
-	rte_pci_dump;
-	rte_pci_ioport_map;
-	rte_pci_ioport_read;
-	rte_pci_ioport_unmap;
-	rte_pci_ioport_write;
-	rte_pci_map_device;
-	rte_pci_probe;
-	rte_pci_probe_one;
-	rte_pci_read_config;
-	rte_pci_register;
-	rte_pci_scan;
-	rte_pci_unmap_device;
-	rte_pci_unregister;
-	rte_pci_write_config;
 	rte_vdev_init;
 	rte_vdev_register;
 	rte_vdev_uninit;
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index e8fd67a..ac8d3bb 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h
 INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
deleted file mode 100644
index 52fd38c..0000000
--- a/lib/librte_eal/common/eal_common_pci.c
+++ /dev/null
@@ -1,580 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   Copyright 2013-2014 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-
-#include <rte_errno.h>
-#include <rte_interrupts.h>
-#include <rte_log.h>
-#include <rte_bus.h>
-#include <rte_pci.h>
-#include <rte_per_lcore.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_eal.h>
-#include <rte_string_fns.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-
-#include "eal_private.h"
-
-extern struct rte_pci_bus rte_pci_bus;
-
-#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
-
-const char *pci_get_sysfs_path(void)
-{
-	const char *path = NULL;
-
-	path = getenv("SYSFS_PCI_DEVICES");
-	if (path == NULL)
-		return SYSFS_PCI_DEVICES;
-
-	return path;
-}
-
-static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_pci_addr addr;
-	struct rte_bus *pbus;
-
-	pbus = rte_bus_find_by_name("pci");
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-		if (devargs->bus != pbus)
-			continue;
-		devargs->bus->parse(devargs->name, &addr);
-		if (!rte_eal_compare_pci_addr(&dev->addr, &addr))
-			return devargs;
-	}
-	return NULL;
-}
-
-void
-pci_name_set(struct rte_pci_device *dev)
-{
-	struct rte_devargs *devargs;
-
-	/* Each device has its internal, canonical name set. */
-	rte_pci_device_name(&dev->addr,
-			dev->name, sizeof(dev->name));
-	devargs = pci_devargs_lookup(dev);
-	dev->device.devargs = devargs;
-	/* In blacklist mode, if the device is not blacklisted, no
-	 * rte_devargs exists for it.
-	 */
-	if (devargs != NULL)
-		/* If an rte_devargs exists, the generic rte_device uses the
-		 * given name as its namea
-		 */
-		dev->device.name = dev->device.devargs->name;
-	else
-		/* Otherwise, it uses the internal, canonical form. */
-		dev->device.name = dev->name;
-}
-
-/* map a particular resource from a file */
-void *
-pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
-		 int additional_flags)
-{
-	void *mapaddr;
-
-	/* Map the PCI memory resource of device */
-	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
-			MAP_SHARED | additional_flags, fd, offset);
-	if (mapaddr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
-			__func__, fd, requested_addr,
-			(unsigned long)size, (unsigned long)offset,
-			strerror(errno), mapaddr);
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
-
-	return mapaddr;
-}
-
-/* unmap a particular resource */
-void
-pci_unmap_resource(void *requested_addr, size_t size)
-{
-	if (requested_addr == NULL)
-		return;
-
-	/* Unmap the PCI memory resource of device */
-	if (munmap(requested_addr, size)) {
-		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
-			__func__, requested_addr, (unsigned long)size,
-			strerror(errno));
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
-				requested_addr);
-}
-
-/*
- * Match the PCI Driver and Device using the ID Table
- *
- * @param pci_drv
- *	PCI driver from which ID table would be extracted
- * @param pci_dev
- *	PCI device to match against the driver
- * @return
- *	1 for successful match
- *	0 for unsuccessful match
- */
-static int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev)
-{
-	const struct rte_pci_id *id_table;
-
-	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
-	     id_table++) {
-		/* check if device's identifiers match the driver's ones */
-		if (id_table->vendor_id != pci_dev->id.vendor_id &&
-				id_table->vendor_id != PCI_ANY_ID)
-			continue;
-		if (id_table->device_id != pci_dev->id.device_id &&
-				id_table->device_id != PCI_ANY_ID)
-			continue;
-		if (id_table->subsystem_vendor_id !=
-		    pci_dev->id.subsystem_vendor_id &&
-		    id_table->subsystem_vendor_id != PCI_ANY_ID)
-			continue;
-		if (id_table->subsystem_device_id !=
-		    pci_dev->id.subsystem_device_id &&
-		    id_table->subsystem_device_id != PCI_ANY_ID)
-			continue;
-		if (id_table->class_id != pci_dev->id.class_id &&
-				id_table->class_id != RTE_CLASS_ANY_ID)
-			continue;
-
-		return 1;
-	}
-
-	return 0;
-}
-
-/*
- * If vendor/device ID match, call the probe() function of the
- * driver.
- */
-static int
-rte_pci_probe_one_driver(struct rte_pci_driver *dr,
-			 struct rte_pci_device *dev)
-{
-	int ret;
-	struct rte_pci_addr *loc;
-
-	if ((dr == NULL) || (dev == NULL))
-		return -EINVAL;
-
-	loc = &dev->addr;
-
-	/* The device is not blacklisted; Check if driver supports it */
-	if (!rte_pci_match(dr, dev))
-		/* Match of device and driver failed */
-		return 1;
-
-	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-			loc->domain, loc->bus, loc->devid, loc->function,
-			dev->device.numa_node);
-
-	/* no initialization when blacklisted, return without error */
-	if (dev->device.devargs != NULL &&
-		dev->device.devargs->policy ==
-			RTE_DEV_BLACKLISTED) {
-		RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
-			" initializing\n");
-		return 1;
-	}
-
-	if (dev->device.numa_node < 0) {
-		RTE_LOG(WARNING, EAL, "  Invalid NUMA socket, default to 0\n");
-		dev->device.numa_node = 0;
-	}
-
-	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
-		dev->id.device_id, dr->driver.name);
-
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
-		/* map resources for devices that use igb_uio */
-		ret = rte_pci_map_device(dev);
-		if (ret != 0)
-			return ret;
-	}
-
-	/* reference driver structure */
-	dev->driver = dr;
-	dev->device.driver = &dr->driver;
-
-	/* call the driver probe() function */
-	ret = dr->probe(dr, dev);
-	if (ret) {
-		dev->driver = NULL;
-		dev->device.driver = NULL;
-		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
-			/* Don't unmap if device is unsupported and
-			 * driver needs mapped resources.
-			 */
-			!(ret > 0 &&
-				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
-			rte_pci_unmap_device(dev);
-	}
-
-	return ret;
-}
-
-/*
- * If vendor/device ID match, call the remove() function of the
- * driver.
- */
-static int
-rte_pci_detach_dev(struct rte_pci_device *dev)
-{
-	struct rte_pci_addr *loc;
-	struct rte_pci_driver *dr;
-
-	if (dev == NULL)
-		return -EINVAL;
-
-	dr = dev->driver;
-	loc = &dev->addr;
-
-	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-			loc->domain, loc->bus, loc->devid,
-			loc->function, dev->device.numa_node);
-
-	RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
-			dev->id.device_id, dr->driver.name);
-
-	if (dr->remove && (dr->remove(dev) < 0))
-		return -1;	/* negative value is an error */
-
-	/* clear driver structure */
-	dev->driver = NULL;
-
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
-		/* unmap resources for devices that use igb_uio */
-		rte_pci_unmap_device(dev);
-
-	return 0;
-}
-
-/*
- * If vendor/device ID match, call the probe() function of all
- * registered driver for the given device. Return -1 if initialization
- * failed, return 1 if no driver is found for this device.
- */
-static int
-pci_probe_all_drivers(struct rte_pci_device *dev)
-{
-	struct rte_pci_driver *dr = NULL;
-	int rc = 0;
-
-	if (dev == NULL)
-		return -1;
-
-	/* Check if a driver is already loaded */
-	if (dev->driver != NULL)
-		return 0;
-
-	FOREACH_DRIVER_ON_PCIBUS(dr) {
-		rc = rte_pci_probe_one_driver(dr, dev);
-		if (rc < 0)
-			/* negative value is an error */
-			return -1;
-		if (rc > 0)
-			/* positive value means driver doesn't support it */
-			continue;
-		return 0;
-	}
-	return 1;
-}
-
-/*
- * Find the pci device specified by pci address, then invoke probe function of
- * the driver of the device.
- */
-int
-rte_pci_probe_one(const struct rte_pci_addr *addr)
-{
-	struct rte_pci_device *dev = NULL;
-
-	int ret = 0;
-
-	if (addr == NULL)
-		return -1;
-
-	/* update current pci device in global list, kernel bindings might have
-	 * changed since last time we looked at it.
-	 */
-	if (pci_update_device(addr) < 0)
-		goto err_return;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_eal_compare_pci_addr(&dev->addr, addr))
-			continue;
-
-		ret = pci_probe_all_drivers(dev);
-		if (ret)
-			goto err_return;
-		return 0;
-	}
-	return -1;
-
-err_return:
-	RTE_LOG(WARNING, EAL,
-		"Requested device " PCI_PRI_FMT " cannot be used\n",
-		addr->domain, addr->bus, addr->devid, addr->function);
-	return -1;
-}
-
-/*
- * Detach device specified by its pci address.
- */
-int
-rte_pci_detach(const struct rte_pci_addr *addr)
-{
-	struct rte_pci_device *dev = NULL;
-	int ret = 0;
-
-	if (addr == NULL)
-		return -1;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_eal_compare_pci_addr(&dev->addr, addr))
-			continue;
-
-		ret = rte_pci_detach_dev(dev);
-		if (ret < 0)
-			/* negative value is an error */
-			goto err_return;
-		if (ret > 0)
-			/* positive value means driver doesn't support it */
-			continue;
-
-		rte_pci_remove_device(dev);
-		free(dev);
-		return 0;
-	}
-	return -1;
-
-err_return:
-	RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
-			" cannot be used\n", dev->addr.domain, dev->addr.bus,
-			dev->addr.devid, dev->addr.function);
-	return -1;
-}
-
-/*
- * Scan the content of the PCI bus, and call the probe() function for
- * all registered drivers that have a matching entry in its id_table
- * for discovered devices.
- */
-int
-rte_pci_probe(void)
-{
-	struct rte_pci_device *dev = NULL;
-	size_t probed = 0, failed = 0;
-	struct rte_devargs *devargs;
-	int probe_all = 0;
-	int ret = 0;
-
-	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
-		probe_all = 1;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		probed++;
-
-		devargs = dev->device.devargs;
-		/* probe all or only whitelisted devices */
-		if (probe_all)
-			ret = pci_probe_all_drivers(dev);
-		else if (devargs != NULL &&
-			devargs->policy == RTE_DEV_WHITELISTED)
-			ret = pci_probe_all_drivers(dev);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
-				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
-				 dev->addr.devid, dev->addr.function);
-			rte_errno = errno;
-			failed++;
-			ret = 0;
-		}
-	}
-
-	return (probed && probed == failed) ? -1 : 0;
-}
-
-/* dump one device */
-static int
-pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
-{
-	int i;
-
-	fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
-	       dev->addr.devid, dev->addr.function);
-	fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
-	       dev->id.device_id);
-
-	for (i = 0; i != sizeof(dev->mem_resource) /
-		sizeof(dev->mem_resource[0]); i++) {
-		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
-			dev->mem_resource[i].phys_addr,
-			dev->mem_resource[i].len);
-	}
-	return 0;
-}
-
-/* dump devices on the bus */
-void
-rte_pci_dump(FILE *f)
-{
-	struct rte_pci_device *dev = NULL;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		pci_dump_one_device(f, dev);
-	}
-}
-
-static int
-pci_parse(const char *name, void *addr)
-{
-	struct rte_pci_addr *out = addr;
-	struct rte_pci_addr pci_addr;
-	bool parse;
-
-	parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
-		 eal_parse_pci_DomBDF(name, &pci_addr) == 0);
-	if (parse && addr != NULL)
-		*out = pci_addr;
-	return parse == false;
-}
-
-/* register a driver */
-void
-rte_pci_register(struct rte_pci_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
-	driver->bus = &rte_pci_bus;
-}
-
-/* unregister a driver */
-void
-rte_pci_unregister(struct rte_pci_driver *driver)
-{
-	TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
-	driver->bus = NULL;
-}
-
-/* Add a device to PCI bus */
-void
-rte_pci_add_device(struct rte_pci_device *pci_dev)
-{
-	TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
-}
-
-/* Insert a device into a predefined position in PCI bus */
-void
-rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
-		      struct rte_pci_device *new_pci_dev)
-{
-	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
-}
-
-/* Remove a device from PCI bus */
-void
-rte_pci_remove_device(struct rte_pci_device *pci_dev)
-{
-	TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
-}
-
-static struct rte_device *
-pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		const void *data)
-{
-	struct rte_pci_device *dev;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (start && &dev->device == start) {
-			start = NULL; /* starting point found */
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-
-	return NULL;
-}
-
-static int
-pci_plug(struct rte_device *dev)
-{
-	return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
-}
-
-static int
-pci_unplug(struct rte_device *dev)
-{
-	struct rte_pci_device *pdev;
-	int ret;
-
-	pdev = RTE_DEV_TO_PCI(dev);
-	ret = rte_pci_detach_dev(pdev);
-	rte_pci_remove_device(pdev);
-	free(pdev);
-	return ret;
-}
-
-struct rte_pci_bus rte_pci_bus = {
-	.bus = {
-		.scan = rte_pci_scan,
-		.probe = rte_pci_probe,
-		.find_device = pci_find_device,
-		.plug = pci_plug,
-		.unplug = pci_unplug,
-		.parse = pci_parse,
-	},
-	.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
-	.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
-};
-
-RTE_REGISTER_BUS(pci, rte_pci_bus.bus);
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
deleted file mode 100644
index 367a681..0000000
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include <rte_eal.h>
-#include <rte_tailq.h>
-#include <rte_log.h>
-#include <rte_malloc.h>
-
-#include "eal_private.h"
-
-static struct rte_tailq_elem rte_uio_tailq = {
-	.name = "UIO_RESOURCE_LIST",
-};
-EAL_REGISTER_TAILQ(rte_uio_tailq)
-
-static int
-pci_uio_map_secondary(struct rte_pci_device *dev)
-{
-	int fd, i, j;
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	TAILQ_FOREACH(uio_res, uio_res_list, next) {
-
-		/* skip this element if it doesn't match our PCI address */
-		if (rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
-			continue;
-
-		for (i = 0; i != uio_res->nb_maps; i++) {
-			/*
-			 * open devname, to mmap it
-			 */
-			fd = open(uio_res->maps[i].path, O_RDWR);
-			if (fd < 0) {
-				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-					uio_res->maps[i].path, strerror(errno));
-				return -1;
-			}
-
-			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
-					fd, (off_t)uio_res->maps[i].offset,
-					(size_t)uio_res->maps[i].size, 0);
-			/* fd is not needed in slave process, close it */
-			close(fd);
-			if (mapaddr != uio_res->maps[i].addr) {
-				RTE_LOG(ERR, EAL,
-					"Cannot mmap device resource file %s to address: %p\n",
-					uio_res->maps[i].path,
-					uio_res->maps[i].addr);
-				if (mapaddr != MAP_FAILED) {
-					/* unmap addrs correctly mapped */
-					for (j = 0; j < i; j++)
-						pci_unmap_resource(
-							uio_res->maps[j].addr,
-							(size_t)uio_res->maps[j].size);
-					/* unmap addr wrongly mapped */
-					pci_unmap_resource(mapaddr,
-						(size_t)uio_res->maps[i].size);
-				}
-				return -1;
-			}
-		}
-		return 0;
-	}
-
-	RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
-	return 1;
-}
-
-/* map the PCI resource of a PCI device in virtual memory */
-int
-pci_uio_map_resource(struct rte_pci_device *dev)
-{
-	int i, map_idx = 0, ret;
-	uint64_t phaddr;
-	struct mapped_pci_resource *uio_res = NULL;
-	struct mapped_pci_res_list *uio_res_list =
-		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.uio_cfg_fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* secondary processes - use already recorded details */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return pci_uio_map_secondary(dev);
-
-	/* allocate uio resource */
-	ret = pci_uio_alloc_resource(dev, &uio_res);
-	if (ret)
-		return ret;
-
-	/* Map all BARs */
-	for (i = 0; i != PCI_MAX_RESOURCE; i++) {
-		/* skip empty BAR */
-		phaddr = dev->mem_resource[i].phys_addr;
-		if (phaddr == 0)
-			continue;
-
-		ret = pci_uio_map_resource_by_index(dev, i,
-				uio_res, map_idx);
-		if (ret)
-			goto error;
-
-		map_idx++;
-	}
-
-	uio_res->nb_maps = map_idx;
-
-	TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
-
-	return 0;
-error:
-	for (i = 0; i < map_idx; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
-				(size_t)uio_res->maps[i].size);
-		rte_free(uio_res->maps[i].path);
-	}
-	pci_uio_free_resource(dev, uio_res);
-	return -1;
-}
-
-static void
-pci_uio_unmap(struct mapped_pci_resource *uio_res)
-{
-	int i;
-
-	if (uio_res == NULL)
-		return;
-
-	for (i = 0; i != uio_res->nb_maps; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
-				(size_t)uio_res->maps[i].size);
-		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-			rte_free(uio_res->maps[i].path);
-	}
-}
-
-static struct mapped_pci_resource *
-pci_uio_find_resource(struct rte_pci_device *dev)
-{
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	if (dev == NULL)
-		return NULL;
-
-	TAILQ_FOREACH(uio_res, uio_res_list, next) {
-
-		/* skip this element if it doesn't match our PCI address */
-		if (!rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
-			return uio_res;
-	}
-	return NULL;
-}
-
-/* unmap the PCI resource of a PCI device in virtual memory */
-void
-pci_uio_unmap_resource(struct rte_pci_device *dev)
-{
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	if (dev == NULL)
-		return;
-
-	/* find an entry for the device */
-	uio_res = pci_uio_find_resource(dev);
-	if (uio_res == NULL)
-		return;
-
-	/* secondary processes - just free maps */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return pci_uio_unmap(uio_res);
-
-	TAILQ_REMOVE(uio_res_list, uio_res, next);
-
-	/* unmap all resources */
-	pci_uio_unmap(uio_res);
-
-	/* free uio resource */
-	rte_free(uio_res);
-
-	/* close fd if in primary process */
-	close(dev->intr_handle.fd);
-	if (dev->intr_handle.uio_cfg_fd >= 0) {
-		close(dev->intr_handle.uio_cfg_fd);
-		dev->intr_handle.uio_cfg_fd = -1;
-	}
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-}
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
deleted file mode 100644
index 8b12339..0000000
--- a/lib/librte_eal/common/include/rte_pci.h
+++ /dev/null
@@ -1,598 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   Copyright 2013-2014 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_PCI_H_
-#define _RTE_PCI_H_
-
-/**
- * @file
- *
- * RTE PCI Interface
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <errno.h>
-#include <sys/queue.h>
-#include <stdint.h>
-#include <inttypes.h>
-
-#include <rte_debug.h>
-#include <rte_interrupts.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-
-/** Pathname of PCI devices directory. */
-const char *pci_get_sysfs_path(void);
-
-/** Formatting string for PCI device identifier: Ex: 0000:00:01.0 */
-#define PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
-#define PCI_PRI_STR_SIZE sizeof("XXXXXXXX:XX:XX.X")
-
-/** Short formatting string, without domain, for PCI device: Ex: 00:01.0 */
-#define PCI_SHORT_PRI_FMT "%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
-
-/** Nb. of values in PCI device identifier format string. */
-#define PCI_FMT_NVAL 4
-
-/** Nb. of values in PCI resource format. */
-#define PCI_RESOURCE_FMT_NVAL 3
-
-/** Maximum number of PCI resources. */
-#define PCI_MAX_RESOURCE 6
-
-/* Forward declarations */
-struct rte_pci_device;
-struct rte_pci_driver;
-
-/** List of PCI devices */
-TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
-/** List of PCI drivers */
-TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
-
-/* PCI Bus iterators */
-#define FOREACH_DEVICE_ON_PCIBUS(p)	\
-		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
-
-#define FOREACH_DRIVER_ON_PCIBUS(p)	\
-		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
-
-/**
- * A structure describing an ID for a PCI driver. Each driver provides a
- * table of these IDs for each device that it supports.
- */
-struct rte_pci_id {
-	uint32_t class_id;            /**< Class ID (class, subclass, pi) or RTE_CLASS_ANY_ID. */
-	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
-	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
-	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
-	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
-};
-
-/**
- * A structure describing the location of a PCI device.
- */
-struct rte_pci_addr {
-	uint32_t domain;                /**< Device domain */
-	uint8_t bus;                    /**< Device bus */
-	uint8_t devid;                  /**< Device ID */
-	uint8_t function;               /**< Device function. */
-};
-
-struct rte_devargs;
-
-/**
- * A structure describing a PCI device.
- */
-struct rte_pci_device {
-	TAILQ_ENTRY(rte_pci_device) next;       /**< Next probed PCI device. */
-	struct rte_device device;               /**< Inherit core device */
-	struct rte_pci_addr addr;               /**< PCI location. */
-	struct rte_pci_id id;                   /**< PCI ID. */
-	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
-						/**< PCI Memory Resource */
-	struct rte_intr_handle intr_handle;     /**< Interrupt handle */
-	struct rte_pci_driver *driver;          /**< Associated driver */
-	uint16_t max_vfs;                       /**< sriov enable if not zero */
-	enum rte_kernel_driver kdrv;            /**< Kernel driver passthrough */
-	char name[PCI_PRI_STR_SIZE+1];          /**< PCI location (ASCII) */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_pci_device.
- */
-#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
-
-/** Any PCI device identifier (vendor, device, ...) */
-#define PCI_ANY_ID (0xffff)
-#define RTE_CLASS_ANY_ID (0xffffff)
-
-#ifdef __cplusplus
-/** C++ macro used to help building up tables of device IDs */
-#define RTE_PCI_DEVICE(vend, dev) \
-	RTE_CLASS_ANY_ID,         \
-	(vend),                   \
-	(dev),                    \
-	PCI_ANY_ID,               \
-	PCI_ANY_ID
-#else
-/** Macro used to help building up tables of device IDs */
-#define RTE_PCI_DEVICE(vend, dev)          \
-	.class_id = RTE_CLASS_ANY_ID,      \
-	.vendor_id = (vend),               \
-	.device_id = (dev),                \
-	.subsystem_vendor_id = PCI_ANY_ID, \
-	.subsystem_device_id = PCI_ANY_ID
-#endif
-
-/**
- * Initialisation function for the driver called during PCI probing.
- */
-typedef int (pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
-
-/**
- * Uninitialisation function for the driver called during hotplugging.
- */
-typedef int (pci_remove_t)(struct rte_pci_device *);
-
-/**
- * A structure describing a PCI driver.
- */
-struct rte_pci_driver {
-	TAILQ_ENTRY(rte_pci_driver) next;       /**< Next in list. */
-	struct rte_driver driver;               /**< Inherit core driver. */
-	struct rte_pci_bus *bus;                /**< PCI bus reference. */
-	pci_probe_t *probe;                     /**< Device Probe function. */
-	pci_remove_t *remove;                   /**< Device Remove function. */
-	const struct rte_pci_id *id_table;	/**< ID table, NULL terminated. */
-	uint32_t drv_flags;                     /**< Flags contolling handling of device. */
-};
-
-/**
- * Structure describing the PCI bus
- */
-struct rte_pci_bus {
-	struct rte_bus bus;               /**< Inherit the generic class */
-	struct rte_pci_device_list device_list;  /**< List of PCI devices */
-	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
-};
-
-/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
-#define RTE_PCI_DRV_NEED_MAPPING 0x0001
-/** Device driver supports link state interrupt */
-#define RTE_PCI_DRV_INTR_LSC	0x0008
-/** Device driver supports device removal interrupt */
-#define RTE_PCI_DRV_INTR_RMV 0x0010
-/** Device driver needs to keep mapped resources if unsupported dev detected */
-#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
-
-/**
- * A structure describing a PCI mapping.
- */
-struct pci_map {
-	void *addr;
-	char *path;
-	uint64_t offset;
-	uint64_t size;
-	uint64_t phaddr;
-};
-
-/**
- * A structure describing a mapped PCI resource.
- * For multi-process we need to reproduce all PCI mappings in secondary
- * processes, so save them in a tailq.
- */
-struct mapped_pci_resource {
-	TAILQ_ENTRY(mapped_pci_resource) next;
-
-	struct rte_pci_addr pci_addr;
-	char path[PATH_MAX];
-	int nb_maps;
-	struct pci_map maps[PCI_MAX_RESOURCE];
-};
-
-/** mapped pci device list */
-TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
-
-/**< Internal use only - Macro used by pci addr parsing functions **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
-do {                                                               \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
-
-/**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided without
- * a domain prefix (i.e. domain returned is always 0)
- *
- * @param input
- *	The input string to be parsed. Should have the format XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned. Domain will always be
- *	returned as 0
- * @return
- *  0 on success, negative on error.
- */
-static inline int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-
-/**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided including
- * a domain prefix.
- *
- * @param input
- *	The input string to be parsed. Should have the format XXXX:XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned
- * @return
- *  0 on success, negative on error.
- */
-static inline int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-#undef GET_PCIADDR_FIELD
-
-/**
- * Utility function to write a pci device name, this device name can later be
- * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
- * BDF helpers.
- *
- * @param addr
- *	The PCI Bus-Device-Function address
- * @param output
- *	The output buffer string
- * @param size
- *	The output buffer size
- */
-static inline void
-rte_pci_device_name(const struct rte_pci_addr *addr,
-		char *output, size_t size)
-{
-	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
-	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
-			    addr->domain, addr->bus,
-			    addr->devid, addr->function) >= 0);
-}
-
-/* Compare two PCI device addresses. */
-/**
- * Utility function to compare two PCI device addresses.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to compare
- * @param addr2
- *	The PCI Bus-Device-Function address to compare
- * @return
- *	0 on equal PCI address.
- *	Positive on addr is greater than addr2.
- *	Negative on addr is less than addr2, or error.
- */
-static inline int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			 const struct rte_pci_addr *addr2)
-{
-	uint64_t dev_addr, dev_addr2;
-
-	if ((addr == NULL) || (addr2 == NULL))
-		return -1;
-
-	dev_addr = ((uint64_t)addr->domain << 24) |
-		(addr->bus << 16) | (addr->devid << 8) | addr->function;
-	dev_addr2 = ((uint64_t)addr2->domain << 24) |
-		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
-
-	if (dev_addr > dev_addr2)
-		return 1;
-	else if (dev_addr < dev_addr2)
-		return -1;
-	else
-		return 0;
-}
-
-/**
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- *
- * @return
- *  0 on success, negative on error
- */
-int rte_pci_scan(void);
-
-/**
- * Probe the PCI bus
- *
- * @return
- *   - 0 on success.
- *   - !0 on error.
- */
-int
-rte_pci_probe(void);
-
-/**
- * Map the PCI device resources in user space virtual memory address
- *
- * Note that driver should not call this function when flag
- * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for
- * you when it's on.
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- *
- * @return
- *   0 on success, negative on error and positive if no driver
- *   is found for the device.
- */
-int rte_pci_map_device(struct rte_pci_device *dev);
-
-/**
- * Unmap this device
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- */
-void rte_pci_unmap_device(struct rte_pci_device *dev);
-
-/**
- * @internal
- * Map a particular resource from a file.
- *
- * @param requested_addr
- *      The starting address for the new mapping range.
- * @param fd
- *      The file descriptor.
- * @param offset
- *      The offset for the mapping range.
- * @param size
- *      The size for the mapping range.
- * @param additional_flags
- *      The additional flags for the mapping range.
- * @return
- *   - On success, the function returns a pointer to the mapped area.
- *   - On error, the value MAP_FAILED is returned.
- */
-void *pci_map_resource(void *requested_addr, int fd, off_t offset,
-		size_t size, int additional_flags);
-
-/**
- * @internal
- * Unmap a particular resource.
- *
- * @param requested_addr
- *      The address for the unmapping range.
- * @param size
- *      The size for the unmapping range.
- */
-void pci_unmap_resource(void *requested_addr, size_t size);
-
-/**
- * Probe the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the probe() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to probe.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_probe_one(const struct rte_pci_addr *addr);
-
-/**
- * Close the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the remove() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to close.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_detach(const struct rte_pci_addr *addr);
-
-/**
- * Dump the content of the PCI bus.
- *
- * @param f
- *   A pointer to a file for output
- */
-void rte_pci_dump(FILE *f);
-
-/**
- * Register a PCI driver.
- *
- * @param driver
- *   A pointer to a rte_pci_driver structure describing the driver
- *   to be registered.
- */
-void rte_pci_register(struct rte_pci_driver *driver);
-
-/** Helper for PCI device registration from driver (eth, crypto) instance */
-#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
-RTE_INIT(pciinitfn_ ##nm); \
-static void pciinitfn_ ##nm(void) \
-{\
-	(pci_drv).driver.name = RTE_STR(nm);\
-	rte_pci_register(&pci_drv); \
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-/**
- * Unregister a PCI driver.
- *
- * @param driver
- *   A pointer to a rte_pci_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_pci_unregister(struct rte_pci_driver *driver);
-
-/**
- * Read PCI config space.
- *
- * @param device
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- * @param buf
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into PCI config space
- */
-int rte_pci_read_config(const struct rte_pci_device *device,
-		void *buf, size_t len, off_t offset);
-
-/**
- * Write PCI config space.
- *
- * @param device
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- * @param buf
- *   A data buffer containing the bytes should be written
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into PCI config space
- */
-int rte_pci_write_config(const struct rte_pci_device *device,
-		const void *buf, size_t len, off_t offset);
-
-/**
- * A structure used to access io resources for a pci device.
- * rte_pci_ioport is arch, os, driver specific, and should not be used outside
- * of pci ioport api.
- */
-struct rte_pci_ioport {
-	struct rte_pci_device *dev;
-	uint64_t base;
-	uint64_t len; /* only filled for memory mapped ports */
-};
-
-/**
- * Initialize a rte_pci_ioport object for a pci device io resource.
- *
- * This object is then used to gain access to those io resources (see below).
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use.
- * @param bar
- *   Index of the io pci resource we want to access.
- * @param p
- *   The rte_pci_ioport object to be initialized.
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p);
-
-/**
- * Release any resources used in a rte_pci_ioport object.
- *
- * @param p
- *   The rte_pci_ioport object to be uninitialized.
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_ioport_unmap(struct rte_pci_ioport *p);
-
-/**
- * Read from a io pci resource.
- *
- * @param p
- *   The rte_pci_ioport object from which we want to read.
- * @param data
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into the pci io resource.
- */
-void rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset);
-
-/**
- * Write to a io pci resource.
- *
- * @param p
- *   The rte_pci_ioport object to which we want to write.
- * @param data
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into the pci io resource.
- */
-void rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RTE_PCI_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 90bca4d..4abc886 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -64,10 +64,6 @@ endif
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
@@ -81,8 +77,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_errno.c
@@ -109,16 +103,12 @@ CFLAGS_eal_common_cpuflags.o := $(CPUFLAGS_LIST)
 
 CFLAGS_eal.o := -D_GNU_SOURCE
 CFLAGS_eal_interrupts.o := -D_GNU_SOURCE
-CFLAGS_eal_vfio_mp_sync.o := -D_GNU_SOURCE
 CFLAGS_eal_timer.o := -D_GNU_SOURCE
 CFLAGS_eal_lcore.o := -D_GNU_SOURCE
 CFLAGS_eal_thread.o := -D_GNU_SOURCE
 CFLAGS_eal_log.o := -D_GNU_SOURCE
 CFLAGS_eal_common_log.o := -D_GNU_SOURCE
 CFLAGS_eal_hugepage_info.o := -D_GNU_SOURCE
-CFLAGS_eal_pci.o := -D_GNU_SOURCE
-CFLAGS_eal_pci_uio.o := -D_GNU_SOURCE
-CFLAGS_eal_pci_vfio.o := -D_GNU_SOURCE
 CFLAGS_eal_common_whitelist.o := -D_GNU_SOURCE
 CFLAGS_eal_common_options.o := -D_GNU_SOURCE
 CFLAGS_eal_common_thread.o := -D_GNU_SOURCE
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
deleted file mode 100644
index 8951ce7..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ /dev/null
@@ -1,722 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <dirent.h>
-
-#include <rte_log.h>
-#include <rte_bus.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-#include <rte_devargs.h>
-#include <rte_memcpy.h>
-
-#include "eal_filesystem.h"
-#include "eal_private.h"
-#include "eal_pci_init.h"
-
-/**
- * @file
- * PCI probing under linux
- *
- * This code is used to simulate a PCI probe by parsing information in sysfs.
- * When a registered device matches a driver, it is then initialized with
- * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
- */
-
-extern struct rte_pci_bus rte_pci_bus;
-
-static int
-pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
-{
-	int count;
-	char path[PATH_MAX];
-	char *name;
-
-	if (!filename || !dri_name)
-		return -1;
-
-	count = readlink(filename, path, PATH_MAX);
-	if (count >= PATH_MAX)
-		return -1;
-
-	/* For device does not have a driver */
-	if (count < 0)
-		return 1;
-
-	path[count] = '\0';
-
-	name = strrchr(path, '/');
-	if (name) {
-		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
-		return 0;
-	}
-
-	return -1;
-}
-
-/* Map pci device */
-int
-rte_pci_map_device(struct rte_pci_device *dev)
-{
-	int ret = -1;
-
-	/* try mapping the NIC resources using VFIO if it exists */
-	switch (dev->kdrv) {
-	case RTE_KDRV_VFIO:
-#ifdef VFIO_PRESENT
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_map_resource(dev);
-#endif
-		break;
-	case RTE_KDRV_IGB_UIO:
-	case RTE_KDRV_UIO_GENERIC:
-		if (rte_eal_using_phys_addrs()) {
-			/* map resources for devices that use uio */
-			ret = pci_uio_map_resource(dev);
-		}
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		ret = 1;
-		break;
-	}
-
-	return ret;
-}
-
-/* Unmap pci device */
-void
-rte_pci_unmap_device(struct rte_pci_device *dev)
-{
-	/* try unmapping the NIC resources using VFIO if it exists */
-	switch (dev->kdrv) {
-	case RTE_KDRV_VFIO:
-#ifdef VFIO_PRESENT
-		if (pci_vfio_is_enabled())
-			pci_vfio_unmap_resource(dev);
-#endif
-		break;
-	case RTE_KDRV_IGB_UIO:
-	case RTE_KDRV_UIO_GENERIC:
-		/* unmap resources for devices that use uio */
-		pci_uio_unmap_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		break;
-	}
-}
-
-void *
-pci_find_max_end_va(void)
-{
-	const struct rte_memseg *seg = rte_eal_get_physmem_layout();
-	const struct rte_memseg *last = seg;
-	unsigned i = 0;
-
-	for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
-		if (seg->addr == NULL)
-			break;
-
-		if (seg->addr > last->addr)
-			last = seg;
-
-	}
-	return RTE_PTR_ADD(last->addr, last->len);
-}
-
-/* parse one line of the "resource" sysfs file (note that the 'line'
- * string is modified)
- */
-int
-pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
-	uint64_t *end_addr, uint64_t *flags)
-{
-	union pci_resource_info {
-		struct {
-			char *phys_addr;
-			char *end_addr;
-			char *flags;
-		};
-		char *ptrs[PCI_RESOURCE_FMT_NVAL];
-	} res_info;
-
-	if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
-		RTE_LOG(ERR, EAL,
-			"%s(): bad resource format\n", __func__);
-		return -1;
-	}
-	errno = 0;
-	*phys_addr = strtoull(res_info.phys_addr, NULL, 16);
-	*end_addr = strtoull(res_info.end_addr, NULL, 16);
-	*flags = strtoull(res_info.flags, NULL, 16);
-	if (errno != 0) {
-		RTE_LOG(ERR, EAL,
-			"%s(): bad resource format\n", __func__);
-		return -1;
-	}
-
-	return 0;
-}
-
-/* parse the "resource" sysfs file */
-static int
-pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
-{
-	FILE *f;
-	char buf[BUFSIZ];
-	int i;
-	uint64_t phys_addr, end_addr, flags;
-
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
-		return -1;
-	}
-
-	for (i = 0; i<PCI_MAX_RESOURCE; i++) {
-
-		if (fgets(buf, sizeof(buf), f) == NULL) {
-			RTE_LOG(ERR, EAL,
-				"%s(): cannot read resource\n", __func__);
-			goto error;
-		}
-		if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
-				&end_addr, &flags) < 0)
-			goto error;
-
-		if (flags & IORESOURCE_MEM) {
-			dev->mem_resource[i].phys_addr = phys_addr;
-			dev->mem_resource[i].len = end_addr - phys_addr + 1;
-			/* not mapped for now */
-			dev->mem_resource[i].addr = NULL;
-		}
-	}
-	fclose(f);
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
-}
-
-/* Scan one pci sysfs entry, and fill the devices list from it. */
-static int
-pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
-{
-	char filename[PATH_MAX];
-	unsigned long tmp;
-	struct rte_pci_device *dev;
-	char driver[PATH_MAX];
-	int ret;
-
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL)
-		return -1;
-
-	memset(dev, 0, sizeof(*dev));
-	dev->addr = *addr;
-
-	/* get vendor id */
-	snprintf(filename, sizeof(filename), "%s/vendor", dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.vendor_id = (uint16_t)tmp;
-
-	/* get device id */
-	snprintf(filename, sizeof(filename), "%s/device", dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.device_id = (uint16_t)tmp;
-
-	/* get subsystem_vendor id */
-	snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.subsystem_vendor_id = (uint16_t)tmp;
-
-	/* get subsystem_device id */
-	snprintf(filename, sizeof(filename), "%s/subsystem_device",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.subsystem_device_id = (uint16_t)tmp;
-
-	/* get class_id */
-	snprintf(filename, sizeof(filename), "%s/class",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	/* the least 24 bits are valid: class, subclass, program interface */
-	dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
-
-	/* get max_vfs */
-	dev->max_vfs = 0;
-	snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
-	if (!access(filename, F_OK) &&
-	    eal_parse_sysfs_value(filename, &tmp) == 0)
-		dev->max_vfs = (uint16_t)tmp;
-	else {
-		/* for non igb_uio driver, need kernel version >= 3.8 */
-		snprintf(filename, sizeof(filename),
-			 "%s/sriov_numvfs", dirname);
-		if (!access(filename, F_OK) &&
-		    eal_parse_sysfs_value(filename, &tmp) == 0)
-			dev->max_vfs = (uint16_t)tmp;
-	}
-
-	/* get numa node, default to 0 if not present */
-	snprintf(filename, sizeof(filename), "%s/numa_node",
-		 dirname);
-
-	if (access(filename, F_OK) != -1) {
-		if (eal_parse_sysfs_value(filename, &tmp) == 0)
-			dev->device.numa_node = tmp;
-		else
-			dev->device.numa_node = -1;
-	} else {
-		dev->device.numa_node = 0;
-	}
-
-	pci_name_set(dev);
-
-	/* parse resources */
-	snprintf(filename, sizeof(filename), "%s/resource", dirname);
-	if (pci_parse_sysfs_resource(filename, dev) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
-		free(dev);
-		return -1;
-	}
-
-	/* parse driver */
-	snprintf(filename, sizeof(filename), "%s/driver", dirname);
-	ret = pci_get_kernel_driver_by_path(filename, driver);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
-		free(dev);
-		return -1;
-	}
-
-	if (!ret) {
-		if (!strcmp(driver, "vfio-pci"))
-			dev->kdrv = RTE_KDRV_VFIO;
-		else if (!strcmp(driver, "igb_uio"))
-			dev->kdrv = RTE_KDRV_IGB_UIO;
-		else if (!strcmp(driver, "uio_pci_generic"))
-			dev->kdrv = RTE_KDRV_UIO_GENERIC;
-		else
-			dev->kdrv = RTE_KDRV_UNKNOWN;
-	} else
-		dev->kdrv = RTE_KDRV_NONE;
-
-	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-		rte_pci_add_device(dev);
-	} else {
-		struct rte_pci_device *dev2;
-		int ret;
-
-		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
-			if (ret > 0)
-				continue;
-
-			if (ret < 0) {
-				rte_pci_insert_device(dev2, dev);
-			} else { /* already registered */
-				dev2->kdrv = dev->kdrv;
-				dev2->max_vfs = dev->max_vfs;
-				pci_name_set(dev2);
-				memmove(dev2->mem_resource, dev->mem_resource,
-					sizeof(dev->mem_resource));
-				free(dev);
-			}
-			return 0;
-		}
-
-		rte_pci_add_device(dev);
-	}
-
-	return 0;
-}
-
-int
-pci_update_device(const struct rte_pci_addr *addr)
-{
-	char filename[PATH_MAX];
-
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
-		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
-		 addr->function);
-
-	return pci_scan_one(filename, addr);
-}
-
-/*
- * split up a pci address into its constituent parts.
- */
-static int
-parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
-{
-	/* first split on ':' */
-	union splitaddr {
-		struct {
-			char *domain;
-			char *bus;
-			char *devid;
-			char *function;
-		};
-		char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
-	} splitaddr;
-
-	char *buf_copy = strndup(buf, bufsize);
-	if (buf_copy == NULL)
-		return -1;
-
-	if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
-			!= PCI_FMT_NVAL - 1)
-		goto error;
-	/* final split is on '.' between devid and function */
-	splitaddr.function = strchr(splitaddr.devid,'.');
-	if (splitaddr.function == NULL)
-		goto error;
-	*splitaddr.function++ = '\0';
-
-	/* now convert to int values */
-	errno = 0;
-	addr->domain = strtoul(splitaddr.domain, NULL, 16);
-	addr->bus = strtoul(splitaddr.bus, NULL, 16);
-	addr->devid = strtoul(splitaddr.devid, NULL, 16);
-	addr->function = strtoul(splitaddr.function, NULL, 10);
-	if (errno != 0)
-		goto error;
-
-	free(buf_copy); /* free the copy made with strdup */
-	return 0;
-error:
-	free(buf_copy);
-	return -1;
-}
-
-/*
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- */
-int
-rte_pci_scan(void)
-{
-	struct dirent *e;
-	DIR *dir;
-	char dirname[PATH_MAX];
-	struct rte_pci_addr addr;
-
-	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
-		return 0;
-
-	dir = opendir(pci_get_sysfs_path());
-	if (dir == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
-			__func__, strerror(errno));
-		return -1;
-	}
-
-	while ((e = readdir(dir)) != NULL) {
-		if (e->d_name[0] == '.')
-			continue;
-
-		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
-			continue;
-
-		snprintf(dirname, sizeof(dirname), "%s/%s",
-				pci_get_sysfs_path(), e->d_name);
-
-		if (pci_scan_one(dirname, &addr) < 0)
-			goto error;
-	}
-	closedir(dir);
-	return 0;
-
-error:
-	closedir(dir);
-	return -1;
-}
-
-/* Read PCI config space. */
-int rte_pci_read_config(const struct rte_pci_device *device,
-		void *buf, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &device->intr_handle;
-
-	switch (intr_handle->type) {
-	case RTE_INTR_HANDLE_UIO:
-	case RTE_INTR_HANDLE_UIO_INTX:
-		return pci_uio_read_config(intr_handle, buf, len, offset);
-
-#ifdef VFIO_PRESENT
-	case RTE_INTR_HANDLE_VFIO_MSIX:
-	case RTE_INTR_HANDLE_VFIO_MSI:
-	case RTE_INTR_HANDLE_VFIO_LEGACY:
-		return pci_vfio_read_config(intr_handle, buf, len, offset);
-#endif
-	default:
-		RTE_LOG(ERR, EAL,
-			"Unknown handle type of fd %d\n",
-					intr_handle->fd);
-		return -1;
-	}
-}
-
-/* Write PCI config space. */
-int rte_pci_write_config(const struct rte_pci_device *device,
-		const void *buf, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &device->intr_handle;
-
-	switch (intr_handle->type) {
-	case RTE_INTR_HANDLE_UIO:
-	case RTE_INTR_HANDLE_UIO_INTX:
-		return pci_uio_write_config(intr_handle, buf, len, offset);
-
-#ifdef VFIO_PRESENT
-	case RTE_INTR_HANDLE_VFIO_MSIX:
-	case RTE_INTR_HANDLE_VFIO_MSI:
-	case RTE_INTR_HANDLE_VFIO_LEGACY:
-		return pci_vfio_write_config(intr_handle, buf, len, offset);
-#endif
-	default:
-		RTE_LOG(ERR, EAL,
-			"Unknown handle type of fd %d\n",
-					intr_handle->fd);
-		return -1;
-	}
-}
-
-#if defined(RTE_ARCH_X86)
-static int
-pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
-		struct rte_pci_ioport *p)
-{
-	uint16_t start, end;
-	FILE *fp;
-	char *line = NULL;
-	char pci_id[16];
-	int found = 0;
-	size_t linesz;
-
-	snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
-		 dev->addr.domain, dev->addr.bus,
-		 dev->addr.devid, dev->addr.function);
-
-	fp = fopen("/proc/ioports", "r");
-	if (fp == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);
-		return -1;
-	}
-
-	while (getdelim(&line, &linesz, '\n', fp) > 0) {
-		char *ptr = line;
-		char *left;
-		int n;
-
-		n = strcspn(ptr, ":");
-		ptr[n] = 0;
-		left = &ptr[n + 1];
-
-		while (*left && isspace(*left))
-			left++;
-
-		if (!strncmp(left, pci_id, strlen(pci_id))) {
-			found = 1;
-
-			while (*ptr && isspace(*ptr))
-				ptr++;
-
-			sscanf(ptr, "%04hx-%04hx", &start, &end);
-
-			break;
-		}
-	}
-
-	free(line);
-	fclose(fp);
-
-	if (!found)
-		return -1;
-
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	p->base = start;
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
-
-	return 0;
-}
-#endif
-
-int
-rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p)
-{
-	int ret = -1;
-
-	switch (dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_ioport_map(dev, bar, p);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		ret = pci_uio_ioport_map(dev, bar, p);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-#if defined(RTE_ARCH_X86)
-		ret = pci_ioport_map(dev, bar, p);
-#else
-		ret = pci_uio_ioport_map(dev, bar, p);
-#endif
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		ret = pci_ioport_map(dev, bar, p);
-#endif
-		break;
-	default:
-		break;
-	}
-
-	if (!ret)
-		p->dev = dev;
-
-	return ret;
-}
-
-void
-rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		pci_vfio_ioport_read(p, data, len, offset);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		pci_uio_ioport_read(p, data, len, offset);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-void
-rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		pci_vfio_ioport_write(p, data, len, offset);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		pci_uio_ioport_write(p, data, len, offset);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-int
-rte_pci_ioport_unmap(struct rte_pci_ioport *p)
-{
-	int ret = -1;
-
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_ioport_unmap(p);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		ret = pci_uio_ioport_unmap(p);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-#if defined(RTE_ARCH_X86)
-		ret = 0;
-#else
-		ret = pci_uio_ioport_unmap(p);
-#endif
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		ret = 0;
-#endif
-		break;
-	default:
-		break;
-	}
-
-	return ret;
-}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
deleted file mode 100644
index ae2980d..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_init.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef EAL_PCI_INIT_H_
-#define EAL_PCI_INIT_H_
-
-#include "eal_vfio.h"
-
-/** IO resource type: */
-#define IORESOURCE_IO         0x00000100
-#define IORESOURCE_MEM        0x00000200
-
-/*
- * Helper function to map PCI resources right after hugepages in virtual memory
- */
-extern void *pci_map_addr;
-void *pci_find_max_end_va(void);
-
-/* parse one line of the "resource" sysfs file (note that the 'line'
- * string is modified)
- */
-int pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
-	uint64_t *end_addr, uint64_t *flags);
-
-int pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res);
-void pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res);
-int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx);
-
-int pci_uio_read_config(const struct rte_intr_handle *intr_handle,
-			void *buf, size_t len, off_t offs);
-int pci_uio_write_config(const struct rte_intr_handle *intr_handle,
-			 const void *buf, size_t len, off_t offs);
-
-int pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		       struct rte_pci_ioport *p);
-void pci_uio_ioport_read(struct rte_pci_ioport *p,
-			 void *data, size_t len, off_t offset);
-void pci_uio_ioport_write(struct rte_pci_ioport *p,
-			  const void *data, size_t len, off_t offset);
-int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
-
-#ifdef VFIO_PRESENT
-
-/* access config space */
-int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
-			 void *buf, size_t len, off_t offs);
-int pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
-			  const void *buf, size_t len, off_t offs);
-
-int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
-		        struct rte_pci_ioport *p);
-void pci_vfio_ioport_read(struct rte_pci_ioport *p,
-			  void *data, size_t len, off_t offset);
-void pci_vfio_ioport_write(struct rte_pci_ioport *p,
-			   const void *data, size_t len, off_t offset);
-int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
-
-/* map/unmap VFIO resource prototype */
-int pci_vfio_map_resource(struct rte_pci_device *dev);
-int pci_vfio_unmap_resource(struct rte_pci_device *dev);
-
-#endif
-
-#endif /* EAL_PCI_INIT_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
deleted file mode 100644
index fa10329..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/sysmacros.h>
-#include <linux/pci_regs.h>
-
-#if defined(RTE_ARCH_X86)
-#include <sys/io.h>
-#endif
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-
-void *pci_map_addr = NULL;
-
-#define OFF_MAX              ((uint64_t)(off_t)-1)
-
-int
-pci_uio_read_config(const struct rte_intr_handle *intr_handle,
-		    void *buf, size_t len, off_t offset)
-{
-	return pread(intr_handle->uio_cfg_fd, buf, len, offset);
-}
-
-int
-pci_uio_write_config(const struct rte_intr_handle *intr_handle,
-		     const void *buf, size_t len, off_t offset)
-{
-	return pwrite(intr_handle->uio_cfg_fd, buf, len, offset);
-}
-
-static int
-pci_uio_set_bus_master(int dev_fd)
-{
-	uint16_t reg;
-	int ret;
-
-	ret = pread(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL,
-			"Cannot read command from PCI config space!\n");
-		return -1;
-	}
-
-	/* return if bus mastering is already on */
-	if (reg & PCI_COMMAND_MASTER)
-		return 0;
-
-	reg |= PCI_COMMAND_MASTER;
-
-	ret = pwrite(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL,
-			"Cannot write command to PCI config space!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-static int
-pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
-{
-	FILE *f;
-	char filename[PATH_MAX];
-	int ret;
-	unsigned major, minor;
-	dev_t dev;
-
-	/* get the name of the sysfs file that contains the major and minor
-	 * of the uio device and read its content */
-	snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path);
-
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n",
-			__func__);
-		return -1;
-	}
-
-	ret = fscanf(f, "%u:%u", &major, &minor);
-	if (ret != 2) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n",
-			__func__);
-		fclose(f);
-		return -1;
-	}
-	fclose(f);
-
-	/* create the char device "mknod /dev/uioX c major minor" */
-	snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
-	dev = makedev(major, minor);
-	ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
-	if (ret != 0) {
-		RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
-			__func__, strerror(errno));
-		return -1;
-	}
-
-	return ret;
-}
-
-/*
- * Return the uioX char device used for a pci device. On success, return
- * the UIO number and fill dstbuf string with the path of the device in
- * sysfs. On error, return a negative value. In this case dstbuf is
- * invalid.
- */
-static int
-pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
-			   unsigned int buflen, int create)
-{
-	struct rte_pci_addr *loc = &dev->addr;
-	unsigned int uio_num;
-	struct dirent *e;
-	DIR *dir;
-	char dirname[PATH_MAX];
-
-	/* depending on kernel version, uio can be located in uio/uioX
-	 * or uio:uioX */
-
-	snprintf(dirname, sizeof(dirname),
-			"%s/" PCI_PRI_FMT "/uio", pci_get_sysfs_path(),
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	dir = opendir(dirname);
-	if (dir == NULL) {
-		/* retry with the parent directory */
-		snprintf(dirname, sizeof(dirname),
-				"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
-				loc->domain, loc->bus, loc->devid, loc->function);
-		dir = opendir(dirname);
-
-		if (dir == NULL) {
-			RTE_LOG(ERR, EAL, "Cannot opendir %s\n", dirname);
-			return -1;
-		}
-	}
-
-	/* take the first file starting with "uio" */
-	while ((e = readdir(dir)) != NULL) {
-		/* format could be uio%d ...*/
-		int shortprefix_len = sizeof("uio") - 1;
-		/* ... or uio:uio%d */
-		int longprefix_len = sizeof("uio:uio") - 1;
-		char *endptr;
-
-		if (strncmp(e->d_name, "uio", 3) != 0)
-			continue;
-
-		/* first try uio%d */
-		errno = 0;
-		uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
-		if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
-			snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
-			break;
-		}
-
-		/* then try uio:uio%d */
-		errno = 0;
-		uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
-		if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
-			snprintf(dstbuf, buflen, "%s/uio:uio%u", dirname, uio_num);
-			break;
-		}
-	}
-	closedir(dir);
-
-	/* No uio resource found */
-	if (e == NULL)
-		return -1;
-
-	/* create uio device if we've been asked to */
-	if (internal_config.create_uio_dev && create &&
-			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
-		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
-
-	return uio_num;
-}
-
-void
-pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res)
-{
-	rte_free(uio_res);
-
-	if (dev->intr_handle.uio_cfg_fd >= 0) {
-		close(dev->intr_handle.uio_cfg_fd);
-		dev->intr_handle.uio_cfg_fd = -1;
-	}
-	if (dev->intr_handle.fd >= 0) {
-		close(dev->intr_handle.fd);
-		dev->intr_handle.fd = -1;
-		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	}
-}
-
-int
-pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res)
-{
-	char dirname[PATH_MAX];
-	char cfgname[PATH_MAX];
-	char devname[PATH_MAX]; /* contains the /dev/uioX */
-	int uio_num;
-	struct rte_pci_addr *loc;
-
-	loc = &dev->addr;
-
-	/* find uio resource */
-	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 1);
-	if (uio_num < 0) {
-		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
-				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
-		return 1;
-	}
-	snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
-
-	/* save fd if in primary process */
-	dev->intr_handle.fd = open(devname, O_RDWR);
-	if (dev->intr_handle.fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			devname, strerror(errno));
-		goto error;
-	}
-
-	snprintf(cfgname, sizeof(cfgname),
-			"/sys/class/uio/uio%u/device/config", uio_num);
-	dev->intr_handle.uio_cfg_fd = open(cfgname, O_RDWR);
-	if (dev->intr_handle.uio_cfg_fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			cfgname, strerror(errno));
-		goto error;
-	}
-
-	if (dev->kdrv == RTE_KDRV_IGB_UIO)
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-	else {
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
-
-		/* set bus master that is not done by uio_pci_generic */
-		if (pci_uio_set_bus_master(dev->intr_handle.uio_cfg_fd)) {
-			RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
-			goto error;
-		}
-	}
-
-	/* allocate the mapping details for secondary processes*/
-	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
-	if (*uio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto error;
-	}
-
-	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
-	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
-
-	return 0;
-
-error:
-	pci_uio_free_resource(dev, *uio_res);
-	return -1;
-}
-
-int
-pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx)
-{
-	int fd;
-	char devname[PATH_MAX];
-	void *mapaddr;
-	struct rte_pci_addr *loc;
-	struct pci_map *maps;
-
-	loc = &dev->addr;
-	maps = uio_res->maps;
-
-	/* update devname for mmap  */
-	snprintf(devname, sizeof(devname),
-			"%s/" PCI_PRI_FMT "/resource%d",
-			pci_get_sysfs_path(),
-			loc->domain, loc->bus, loc->devid,
-			loc->function, res_idx);
-
-	/* allocate memory to keep path */
-	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
-	if (maps[map_idx].path == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
-				strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * open resource file, to mmap it
-	 */
-	fd = open(devname, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				devname, strerror(errno));
-		goto error;
-	}
-
-	/* try mapping somewhere close to the end of hugepages */
-	if (pci_map_addr == NULL)
-		pci_map_addr = pci_find_max_end_va();
-
-	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
-			(size_t)dev->mem_resource[res_idx].len, 0);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		goto error;
-
-	pci_map_addr = RTE_PTR_ADD(mapaddr,
-			(size_t)dev->mem_resource[res_idx].len);
-
-	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
-	maps[map_idx].size = dev->mem_resource[res_idx].len;
-	maps[map_idx].addr = mapaddr;
-	maps[map_idx].offset = 0;
-	strcpy(maps[map_idx].path, devname);
-	dev->mem_resource[res_idx].addr = mapaddr;
-
-	return 0;
-
-error:
-	rte_free(maps[map_idx].path);
-	return -1;
-}
-
-#if defined(RTE_ARCH_X86)
-int
-pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		   struct rte_pci_ioport *p)
-{
-	char dirname[PATH_MAX];
-	char filename[PATH_MAX];
-	int uio_num;
-	unsigned long start;
-
-	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 0);
-	if (uio_num < 0)
-		return -1;
-
-	/* get portio start */
-	snprintf(filename, sizeof(filename),
-		 "%s/portio/port%d/start", dirname, bar);
-	if (eal_parse_sysfs_value(filename, &start) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
-			__func__);
-		return -1;
-	}
-	/* ensure we don't get anything funny here, read/write will cast to
-	 * uin16_t */
-	if (start > UINT16_MAX)
-		return -1;
-
-	/* FIXME only for primary process ? */
-	if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {
-
-		snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
-		dev->intr_handle.fd = open(filename, O_RDWR);
-		if (dev->intr_handle.fd < 0) {
-			RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				filename, strerror(errno));
-			return -1;
-		}
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-	}
-
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);
-
-	p->base = start;
-	p->len = 0;
-	return 0;
-}
-#else
-int
-pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		   struct rte_pci_ioport *p)
-{
-	FILE *f;
-	char buf[BUFSIZ];
-	char filename[PATH_MAX];
-	uint64_t phys_addr, end_addr, flags;
-	int fd, i;
-	void *addr;
-
-	/* open and read addresses of the corresponding resource in sysfs */
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
-		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
-		dev->addr.devid, dev->addr.function);
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",
-			strerror(errno));
-		return -1;
-	}
-	for (i = 0; i < bar + 1; i++) {
-		if (fgets(buf, sizeof(buf), f) == NULL) {
-			RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");
-			goto error;
-		}
-	}
-	if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
-			&end_addr, &flags) < 0)
-		goto error;
-	if ((flags & IORESOURCE_IO) == 0) {
-		RTE_LOG(ERR, EAL, "BAR %d is not an IO resource\n", bar);
-		goto error;
-	}
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
-		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
-		dev->addr.devid, dev->addr.function, bar);
-
-	/* mmap the pci resource */
-	fd = open(filename, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
-			strerror(errno));
-		goto error;
-	}
-	addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
-		MAP_SHARED, fd, 0);
-	close(fd);
-	if (addr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s\n",
-			strerror(errno));
-		goto error;
-	}
-
-	/* strangely, the base address is mmap addr + phys_addr */
-	p->base = (uintptr_t)addr + phys_addr;
-	p->len = end_addr + 1;
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"\n", p->base);
-	fclose(f);
-
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
-}
-#endif
-
-void
-pci_uio_ioport_read(struct rte_pci_ioport *p,
-		    void *data, size_t len, off_t offset)
-{
-	uint8_t *d;
-	int size;
-	uintptr_t reg = p->base + offset;
-
-	for (d = data; len > 0; d += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-#if defined(RTE_ARCH_X86)
-			*(uint32_t *)d = inl(reg);
-#else
-			*(uint32_t *)d = *(volatile uint32_t *)reg;
-#endif
-		} else if (len >= 2) {
-			size = 2;
-#if defined(RTE_ARCH_X86)
-			*(uint16_t *)d = inw(reg);
-#else
-			*(uint16_t *)d = *(volatile uint16_t *)reg;
-#endif
-		} else {
-			size = 1;
-#if defined(RTE_ARCH_X86)
-			*d = inb(reg);
-#else
-			*d = *(volatile uint8_t *)reg;
-#endif
-		}
-	}
-}
-
-void
-pci_uio_ioport_write(struct rte_pci_ioport *p,
-		     const void *data, size_t len, off_t offset)
-{
-	const uint8_t *s;
-	int size;
-	uintptr_t reg = p->base + offset;
-
-	for (s = data; len > 0; s += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-#if defined(RTE_ARCH_X86)
-			outl_p(*(const uint32_t *)s, reg);
-#else
-			*(volatile uint32_t *)reg = *(const uint32_t *)s;
-#endif
-		} else if (len >= 2) {
-			size = 2;
-#if defined(RTE_ARCH_X86)
-			outw_p(*(const uint16_t *)s, reg);
-#else
-			*(volatile uint16_t *)reg = *(const uint16_t *)s;
-#endif
-		} else {
-			size = 1;
-#if defined(RTE_ARCH_X86)
-			outb_p(*s, reg);
-#else
-			*(volatile uint8_t *)reg = *s;
-#endif
-		}
-	}
-}
-
-int
-pci_uio_ioport_unmap(struct rte_pci_ioport *p)
-{
-#if defined(RTE_ARCH_X86)
-	RTE_SET_USED(p);
-	/* FIXME close intr fd ? */
-	return 0;
-#else
-	return munmap((void *)(uintptr_t)p->base, p->len);
-#endif
-}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
deleted file mode 100644
index aa9d96e..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <fcntl.h>
-#include <linux/pci_regs.h>
-#include <sys/eventfd.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <stdbool.h>
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-#include "eal_vfio.h"
-#include "eal_private.h"
-
-/**
- * @file
- * PCI probing under linux (VFIO version)
- *
- * This code tries to determine if the PCI device is bound to VFIO driver,
- * and initialize it (map BARs, set up interrupts) if that's the case.
- *
- * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
- */
-
-#ifdef VFIO_PRESENT
-
-#define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
-#define PAGE_MASK   (~(PAGE_SIZE - 1))
-
-static struct rte_tailq_elem rte_vfio_tailq = {
-	.name = "VFIO_RESOURCE_LIST",
-};
-EAL_REGISTER_TAILQ(rte_vfio_tailq)
-
-int
-pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
-		    void *buf, size_t len, off_t offs)
-{
-	return pread64(intr_handle->vfio_dev_fd, buf, len,
-	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
-}
-
-int
-pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
-		    const void *buf, size_t len, off_t offs)
-{
-	return pwrite64(intr_handle->vfio_dev_fd, buf, len,
-	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
-}
-
-/* get PCI BAR number where MSI-X interrupts are */
-static int
-pci_vfio_get_msix_bar(int fd, int *msix_bar, uint32_t *msix_table_offset,
-		      uint32_t *msix_table_size)
-{
-	int ret;
-	uint32_t reg;
-	uint16_t flags;
-	uint8_t cap_id, cap_offset;
-
-	/* read PCI capability pointer from config space */
-	ret = pread64(fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_CAPABILITY_LIST);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
-				"config space!\n");
-		return -1;
-	}
-
-	/* we need first byte */
-	cap_offset = reg & 0xFF;
-
-	while (cap_offset) {
-
-		/* read PCI capability ID */
-		ret = pread64(fd, &reg, sizeof(reg),
-				VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-				cap_offset);
-		if (ret != sizeof(reg)) {
-			RTE_LOG(ERR, EAL, "Cannot read capability ID from PCI "
-					"config space!\n");
-			return -1;
-		}
-
-		/* we need first byte */
-		cap_id = reg & 0xFF;
-
-		/* if we haven't reached MSI-X, check next capability */
-		if (cap_id != PCI_CAP_ID_MSIX) {
-			ret = pread64(fd, &reg, sizeof(reg),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset);
-			if (ret != sizeof(reg)) {
-				RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
-						"config space!\n");
-				return -1;
-			}
-
-			/* we need second byte */
-			cap_offset = (reg & 0xFF00) >> 8;
-
-			continue;
-		}
-		/* else, read table offset */
-		else {
-			/* table offset resides in the next 4 bytes */
-			ret = pread64(fd, &reg, sizeof(reg),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset + 4);
-			if (ret != sizeof(reg)) {
-				RTE_LOG(ERR, EAL, "Cannot read table offset from PCI config "
-						"space!\n");
-				return -1;
-			}
-
-			ret = pread64(fd, &flags, sizeof(flags),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset + 2);
-			if (ret != sizeof(flags)) {
-				RTE_LOG(ERR, EAL, "Cannot read table flags from PCI config "
-						"space!\n");
-				return -1;
-			}
-
-			*msix_bar = reg & RTE_PCI_MSIX_TABLE_BIR;
-			*msix_table_offset = reg & RTE_PCI_MSIX_TABLE_OFFSET;
-			*msix_table_size = 16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE));
-
-			return 0;
-		}
-	}
-	return 0;
-}
-
-/* set PCI bus mastering */
-static int
-pci_vfio_set_bus_master(int dev_fd, bool op)
-{
-	uint16_t reg;
-	int ret;
-
-	ret = pread64(dev_fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n");
-		return -1;
-	}
-
-	if (op)
-		/* set the master bit */
-		reg |= PCI_COMMAND_MASTER;
-	else
-		reg &= ~(PCI_COMMAND_MASTER);
-
-	ret = pwrite64(dev_fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_COMMAND);
-
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-/* set up interrupt support (but not enable interrupts) */
-static int
-pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
-{
-	int i, ret, intr_idx;
-
-	/* default to invalid index */
-	intr_idx = VFIO_PCI_NUM_IRQS;
-
-	/* get interrupt type from internal config (MSI-X by default, can be
-	 * overridden from the command line
-	 */
-	switch (internal_config.vfio_intr_mode) {
-	case RTE_INTR_MODE_MSIX:
-		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
-		break;
-	case RTE_INTR_MODE_MSI:
-		intr_idx = VFIO_PCI_MSI_IRQ_INDEX;
-		break;
-	case RTE_INTR_MODE_LEGACY:
-		intr_idx = VFIO_PCI_INTX_IRQ_INDEX;
-		break;
-	/* don't do anything if we want to automatically determine interrupt type */
-	case RTE_INTR_MODE_NONE:
-		break;
-	default:
-		RTE_LOG(ERR, EAL, "  unknown default interrupt type!\n");
-		return -1;
-	}
-
-	/* start from MSI-X interrupt type */
-	for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) {
-		struct vfio_irq_info irq = { .argsz = sizeof(irq) };
-		int fd = -1;
-
-		/* skip interrupt modes we don't want */
-		if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE &&
-				i != intr_idx)
-			continue;
-
-		irq.index = i;
-
-		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  cannot get IRQ info, "
-					"error %i (%s)\n", errno, strerror(errno));
-			return -1;
-		}
-
-		/* if this vector cannot be used with eventfd, fail if we explicitly
-		 * specified interrupt type, otherwise continue */
-		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
-			if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE) {
-				RTE_LOG(ERR, EAL,
-						"  interrupt vector does not support eventfd!\n");
-				return -1;
-			} else
-				continue;
-		}
-
-		/* set up an eventfd for interrupts */
-		fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
-		if (fd < 0) {
-			RTE_LOG(ERR, EAL, "  cannot set up eventfd, "
-					"error %i (%s)\n", errno, strerror(errno));
-			return -1;
-		}
-
-		dev->intr_handle.fd = fd;
-		dev->intr_handle.vfio_dev_fd = vfio_dev_fd;
-
-		switch (i) {
-		case VFIO_PCI_MSIX_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSIX;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
-			break;
-		case VFIO_PCI_MSI_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSI;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
-			break;
-		case VFIO_PCI_INTX_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_LEGACY;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
-			break;
-		default:
-			RTE_LOG(ERR, EAL, "  unknown interrupt type!\n");
-			return -1;
-		}
-
-		return 0;
-	}
-
-	/* if we're here, we haven't found a suitable interrupt vector */
-	return -1;
-}
-
-/*
- * map the PCI resources of a PCI device in virtual memory (VFIO version).
- * primary and secondary processes follow almost exactly the same path
- */
-int
-pci_vfio_map_resource(struct rte_pci_device *dev)
-{
-	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
-	char pci_addr[PATH_MAX] = {0};
-	int vfio_dev_fd;
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret, msix_bar;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-
-	struct pci_map *maps;
-	uint32_t msix_table_offset = 0;
-	uint32_t msix_table_size = 0;
-	uint32_t ioport_bar;
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	if ((ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
-					&vfio_dev_fd, &device_info)))
-		return ret;
-
-	/* get MSI-X BAR, if any (we have to know where it is because we can't
-	 * easily mmap it when using VFIO) */
-	msix_bar = -1;
-	ret = pci_vfio_get_msix_bar(vfio_dev_fd, &msix_bar,
-				    &msix_table_offset, &msix_table_size);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "  %s cannot get MSI-X BAR number!\n", pci_addr);
-		close(vfio_dev_fd);
-		return -1;
-	}
-
-	/* if we're in a primary process, allocate vfio_res and get region info */
-	if (internal_config.process_type == RTE_PROC_PRIMARY) {
-		vfio_res = rte_zmalloc("VFIO_RES", sizeof(*vfio_res), 0);
-		if (vfio_res == NULL) {
-			RTE_LOG(ERR, EAL,
-				"%s(): cannot store uio mmap details\n", __func__);
-			close(vfio_dev_fd);
-			return -1;
-		}
-		memcpy(&vfio_res->pci_addr, &dev->addr, sizeof(vfio_res->pci_addr));
-
-		/* get number of registers (up to BAR5) */
-		vfio_res->nb_maps = RTE_MIN((int) device_info.num_regions,
-				VFIO_PCI_BAR5_REGION_INDEX + 1);
-	} else {
-		/* if we're in a secondary process, just find our tailq entry */
-		TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-			if (rte_eal_compare_pci_addr(&vfio_res->pci_addr,
-						     &dev->addr))
-				continue;
-			break;
-		}
-		/* if we haven't found our tailq entry, something's wrong */
-		if (vfio_res == NULL) {
-			RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
-					pci_addr);
-			close(vfio_dev_fd);
-			return -1;
-		}
-	}
-
-	/* map BARs */
-	maps = vfio_res->maps;
-
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-		struct vfio_region_info reg = { .argsz = sizeof(reg) };
-		void *bar_addr;
-		struct memreg {
-			unsigned long offset, size;
-		} memreg[2] = {};
-
-		reg.index = i;
-
-		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg);
-
-		if (ret) {
-			RTE_LOG(ERR, EAL, "  %s cannot get device region info "
-					"error %i (%s)\n", pci_addr, errno, strerror(errno));
-			close(vfio_dev_fd);
-			if (internal_config.process_type == RTE_PROC_PRIMARY)
-				rte_free(vfio_res);
-			return -1;
-		}
-
-		/* chk for io port region */
-		ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar),
-			      VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX)
-			      + PCI_BASE_ADDRESS_0 + i*4);
-
-		if (ret != sizeof(ioport_bar)) {
-			RTE_LOG(ERR, EAL,
-				"Cannot read command (%x) from config space!\n",
-				PCI_BASE_ADDRESS_0 + i*4);
-			return -1;
-		}
-
-		if (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) {
-			RTE_LOG(INFO, EAL,
-				"Ignore mapping IO port bar(%d) addr: %x\n",
-				 i, ioport_bar);
-			continue;
-		}
-
-		/* skip non-mmapable BARs */
-		if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0)
-			continue;
-
-		if (i == msix_bar) {
-			/*
-			 * VFIO will not let us map the MSI-X table,
-			 * but we can map around it.
-			 */
-			uint32_t table_start = msix_table_offset;
-			uint32_t table_end = table_start + msix_table_size;
-			table_end = (table_end + ~PAGE_MASK) & PAGE_MASK;
-			table_start &= PAGE_MASK;
-
-			if (table_start == 0 && table_end >= reg.size) {
-				/* Cannot map this BAR */
-				RTE_LOG(DEBUG, EAL, "Skipping BAR %d\n", i);
-				continue;
-			} else {
-				memreg[0].offset = reg.offset;
-				memreg[0].size = table_start;
-				memreg[1].offset = reg.offset + table_end;
-				memreg[1].size = reg.size - table_end;
-
-				RTE_LOG(DEBUG, EAL,
-					"Trying to map BAR %d that contains the MSI-X "
-					"table. Trying offsets: "
-					"0x%04lx:0x%04lx, 0x%04lx:0x%04lx\n", i,
-					memreg[0].offset, memreg[0].size,
-					memreg[1].offset, memreg[1].size);
-			}
-		} else {
-			memreg[0].offset = reg.offset;
-			memreg[0].size = reg.size;
-		}
-
-		/* try to figure out an address */
-		if (internal_config.process_type == RTE_PROC_PRIMARY) {
-			/* try mapping somewhere close to the end of hugepages */
-			if (pci_map_addr == NULL)
-				pci_map_addr = pci_find_max_end_va();
-
-			bar_addr = pci_map_addr;
-			pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
-		} else {
-			bar_addr = maps[i].addr;
-		}
-
-		/* reserve the address using an inaccessible mapping */
-		bar_addr = mmap(bar_addr, reg.size, 0, MAP_PRIVATE |
-				MAP_ANONYMOUS, -1, 0);
-		if (bar_addr != MAP_FAILED) {
-			void *map_addr = NULL;
-			if (memreg[0].size) {
-				/* actual map of first part */
-				map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
-							    memreg[0].offset,
-							    memreg[0].size,
-							    MAP_FIXED);
-			}
-
-			/* if there's a second part, try to map it */
-			if (map_addr != MAP_FAILED
-			    && memreg[1].offset && memreg[1].size) {
-				void *second_addr = RTE_PTR_ADD(bar_addr,
-								memreg[1].offset -
-								(uintptr_t)reg.offset);
-				map_addr = pci_map_resource(second_addr,
-							    vfio_dev_fd, memreg[1].offset,
-							    memreg[1].size,
-							    MAP_FIXED);
-			}
-
-			if (map_addr == MAP_FAILED || !map_addr) {
-				munmap(bar_addr, reg.size);
-				bar_addr = MAP_FAILED;
-			}
-		}
-
-		if (bar_addr == MAP_FAILED ||
-				(internal_config.process_type == RTE_PROC_SECONDARY &&
-						bar_addr != maps[i].addr)) {
-			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n", pci_addr, i,
-					strerror(errno));
-			close(vfio_dev_fd);
-			if (internal_config.process_type == RTE_PROC_PRIMARY)
-				rte_free(vfio_res);
-			return -1;
-		}
-
-		maps[i].addr = bar_addr;
-		maps[i].offset = reg.offset;
-		maps[i].size = reg.size;
-		maps[i].path = NULL; /* vfio doesn't have per-resource paths */
-		dev->mem_resource[i].addr = bar_addr;
-	}
-
-	/* if secondary process, do not set up interrupts */
-	if (internal_config.process_type == RTE_PROC_PRIMARY) {
-		if (pci_vfio_setup_interrupts(dev, vfio_dev_fd) != 0) {
-			RTE_LOG(ERR, EAL, "  %s error setting up interrupts!\n", pci_addr);
-			close(vfio_dev_fd);
-			rte_free(vfio_res);
-			return -1;
-		}
-
-		/* set bus mastering for the device */
-		if (pci_vfio_set_bus_master(vfio_dev_fd, true)) {
-			RTE_LOG(ERR, EAL, "  %s cannot set up bus mastering!\n", pci_addr);
-			close(vfio_dev_fd);
-			rte_free(vfio_res);
-			return -1;
-		}
-
-		/* Reset the device */
-		ioctl(vfio_dev_fd, VFIO_DEVICE_RESET);
-	}
-
-	if (internal_config.process_type == RTE_PROC_PRIMARY)
-		TAILQ_INSERT_TAIL(vfio_res_list, vfio_res, next);
-
-	return 0;
-}
-
-int
-pci_vfio_unmap_resource(struct rte_pci_device *dev)
-{
-	char pci_addr[PATH_MAX] = {0};
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list;
-
-	struct pci_map *maps;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-
-	if (close(dev->intr_handle.fd) < 0) {
-		RTE_LOG(INFO, EAL, "Error when closing eventfd file descriptor for %s\n",
-			pci_addr);
-		return -1;
-	}
-
-	if (pci_vfio_set_bus_master(dev->intr_handle.vfio_dev_fd, false)) {
-		RTE_LOG(ERR, EAL, "  %s cannot unset bus mastering for PCI device!\n",
-				pci_addr);
-		return -1;
-	}
-
-	ret = vfio_release_device(pci_get_sysfs_path(), pci_addr,
-				  dev->intr_handle.vfio_dev_fd);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot release device\n", __func__);
-		return ret;
-	}
-
-	vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-	/* Get vfio_res */
-	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-		if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
-			continue;
-		break;
-	}
-	/* if we haven't found our tailq entry, something's wrong */
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
-				pci_addr);
-		return -1;
-	}
-
-	/* unmap BARs */
-	maps = vfio_res->maps;
-
-	RTE_LOG(INFO, EAL, "Releasing pci mapped resource for %s\n",
-		pci_addr);
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-
-		/*
-		 * We do not need to be aware of MSI-X table BAR mappings as
-		 * when mapping. Just using current maps array is enough
-		 */
-		if (maps[i].addr) {
-			RTE_LOG(INFO, EAL, "Calling pci_unmap_resource for %s at %p\n",
-				pci_addr, maps[i].addr);
-			pci_unmap_resource(maps[i].addr, maps[i].size);
-		}
-	}
-
-	TAILQ_REMOVE(vfio_res_list, vfio_res, next);
-
-	return 0;
-}
-
-int
-pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
-		    struct rte_pci_ioport *p)
-{
-	if (bar < VFIO_PCI_BAR0_REGION_INDEX ||
-	    bar > VFIO_PCI_BAR5_REGION_INDEX) {
-		RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar);
-		return -1;
-	}
-
-	p->dev = dev;
-	p->base = VFIO_GET_REGION_ADDR(bar);
-	return 0;
-}
-
-void
-pci_vfio_ioport_read(struct rte_pci_ioport *p,
-		     void *data, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
-
-	if (pread64(intr_handle->vfio_dev_fd, data,
-		    len, p->base + offset) <= 0)
-		RTE_LOG(ERR, EAL,
-			"Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n",
-			VFIO_GET_REGION_IDX(p->base), (int)offset);
-}
-
-void
-pci_vfio_ioport_write(struct rte_pci_ioport *p,
-		      const void *data, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
-
-	if (pwrite64(intr_handle->vfio_dev_fd, data,
-		     len, p->base + offset) <= 0)
-		RTE_LOG(ERR, EAL,
-			"Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n",
-			VFIO_GET_REGION_IDX(p->base), (int)offset);
-}
-
-int
-pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
-{
-	RTE_SET_USED(p);
-	return -1;
-}
-
-int
-pci_vfio_enable(void)
-{
-	return vfio_enable("vfio_pci");
-}
-
-int
-pci_vfio_is_enabled(void)
-{
-	return vfio_is_enabled("vfio_pci");
-}
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
deleted file mode 100644
index 7e8095c..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <pthread.h>
-
-/* sys/un.h with __USE_MISC uses strlen, which is unsafe */
-#ifdef __USE_MISC
-#define REMOVED_USE_MISC
-#undef __USE_MISC
-#endif
-#include <sys/un.h>
-/* make sure we redefine __USE_MISC only if it was previously undefined */
-#ifdef REMOVED_USE_MISC
-#define __USE_MISC
-#undef REMOVED_USE_MISC
-#endif
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-#include "eal_thread.h"
-
-/**
- * @file
- * VFIO socket for communication between primary and secondary processes.
- *
- * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
- */
-
-#ifdef VFIO_PRESENT
-
-#define SOCKET_PATH_FMT "%s/.%s_mp_socket"
-#define CMSGLEN (CMSG_LEN(sizeof(int)))
-#define FD_TO_CMSGHDR(fd, chdr) \
-		do {\
-			(chdr).cmsg_len = CMSGLEN;\
-			(chdr).cmsg_level = SOL_SOCKET;\
-			(chdr).cmsg_type = SCM_RIGHTS;\
-			memcpy((chdr).__cmsg_data, &(fd), sizeof(fd));\
-		} while (0)
-#define CMSGHDR_TO_FD(chdr, fd) \
-			memcpy(&(fd), (chdr).__cmsg_data, sizeof(fd))
-
-static pthread_t socket_thread;
-static int mp_socket_fd;
-
-
-/* get socket path (/var/run if root, $HOME otherwise) */
-static void
-get_socket_path(char *buffer, int bufsz)
-{
-	const char *dir = "/var/run";
-	const char *home_dir = getenv("HOME");
-
-	if (getuid() != 0 && home_dir != NULL)
-		dir = home_dir;
-
-	/* use current prefix as file path */
-	snprintf(buffer, bufsz, SOCKET_PATH_FMT, dir,
-			internal_config.hugefile_prefix);
-}
-
-
-
-/*
- * data flow for socket comm protocol:
- * 1. client sends SOCKET_REQ_CONTAINER or SOCKET_REQ_GROUP
- * 1a. in case of SOCKET_REQ_GROUP, client also then sends group number
- * 2. server receives message
- * 2a. in case of invalid group, SOCKET_ERR is sent back to client
- * 2b. in case of unbound group, SOCKET_NO_FD is sent back to client
- * 2c. in case of valid group, SOCKET_OK is sent and immediately followed by fd
- *
- * in case of any error, socket is closed.
- */
-
-/* send a request, return -1 on error */
-int
-vfio_mp_sync_send_request(int socket, int req)
-{
-	struct msghdr hdr;
-	struct iovec iov;
-	int buf;
-	int ret;
-
-	memset(&hdr, 0, sizeof(hdr));
-
-	buf = req;
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-
-	ret = sendmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-	return 0;
-}
-
-/* receive a request and return it */
-int
-vfio_mp_sync_receive_request(int socket)
-{
-	int buf;
-	struct msghdr hdr;
-	struct iovec iov;
-	int ret, req;
-
-	memset(&hdr, 0, sizeof(hdr));
-
-	buf = SOCKET_ERR;
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-
-	ret = recvmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-
-	req = buf;
-
-	return req;
-}
-
-/* send OK in message, fd in control message */
-int
-vfio_mp_sync_send_fd(int socket, int fd)
-{
-	int buf;
-	struct msghdr hdr;
-	struct cmsghdr *chdr;
-	char chdr_buf[CMSGLEN];
-	struct iovec iov;
-	int ret;
-
-	chdr = (struct cmsghdr *) chdr_buf;
-	memset(chdr, 0, sizeof(chdr_buf));
-	memset(&hdr, 0, sizeof(hdr));
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-	hdr.msg_control = chdr;
-	hdr.msg_controllen = CMSGLEN;
-
-	buf = SOCKET_OK;
-	FD_TO_CMSGHDR(fd, *chdr);
-
-	ret = sendmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-	return 0;
-}
-
-/* receive OK in message, fd in control message */
-int
-vfio_mp_sync_receive_fd(int socket)
-{
-	int buf;
-	struct msghdr hdr;
-	struct cmsghdr *chdr;
-	char chdr_buf[CMSGLEN];
-	struct iovec iov;
-	int ret, req, fd;
-
-	buf = SOCKET_ERR;
-
-	chdr = (struct cmsghdr *) chdr_buf;
-	memset(chdr, 0, sizeof(chdr_buf));
-	memset(&hdr, 0, sizeof(hdr));
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-	hdr.msg_control = chdr;
-	hdr.msg_controllen = CMSGLEN;
-
-	ret = recvmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-
-	req = buf;
-
-	if (req != SOCKET_OK)
-		return -1;
-
-	CMSGHDR_TO_FD(*chdr, fd);
-
-	return fd;
-}
-
-/* connect socket_fd in secondary process to the primary process's socket */
-int
-vfio_mp_sync_connect_to_primary(void)
-{
-	struct sockaddr_un addr;
-	socklen_t sockaddr_len;
-	int socket_fd;
-
-	/* set up a socket */
-	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-	if (socket_fd < 0) {
-		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
-		return -1;
-	}
-
-	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
-	addr.sun_family = AF_UNIX;
-
-	sockaddr_len = sizeof(struct sockaddr_un);
-
-	if (connect(socket_fd, (struct sockaddr *) &addr, sockaddr_len) == 0)
-		return socket_fd;
-
-	/* if connect failed */
-	close(socket_fd);
-	return -1;
-}
-
-
-
-/*
- * socket listening thread for primary process
- */
-static __attribute__((noreturn)) void *
-vfio_mp_sync_thread(void __rte_unused * arg)
-{
-	int ret, fd, vfio_data;
-
-	/* wait for requests on the socket */
-	for (;;) {
-		int conn_sock;
-		struct sockaddr_un addr;
-		socklen_t sockaddr_len = sizeof(addr);
-
-		/* this is a blocking call */
-		conn_sock = accept(mp_socket_fd, (struct sockaddr *) &addr,
-				&sockaddr_len);
-
-		/* just restart on error */
-		if (conn_sock == -1)
-			continue;
-
-		/* set socket to linger after close */
-		struct linger l;
-		l.l_onoff = 1;
-		l.l_linger = 60;
-
-		if (setsockopt(conn_sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0)
-			RTE_LOG(WARNING, EAL, "Cannot set SO_LINGER option "
-					"on listen socket (%s)\n", strerror(errno));
-
-		ret = vfio_mp_sync_receive_request(conn_sock);
-
-		switch (ret) {
-		case SOCKET_REQ_CONTAINER:
-			fd = vfio_get_container_fd();
-			if (fd < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			else
-				vfio_mp_sync_send_fd(conn_sock, fd);
-			close(fd);
-			break;
-		case SOCKET_REQ_GROUP:
-			/* wait for group number */
-			vfio_data = vfio_mp_sync_receive_request(conn_sock);
-			if (vfio_data < 0) {
-				close(conn_sock);
-				continue;
-			}
-
-			fd = vfio_get_group_fd(vfio_data);
-
-			if (fd < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			/* if VFIO group exists but isn't bound to VFIO driver */
-			else if (fd == 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
-			/* if group exists and is bound to VFIO driver */
-			else {
-				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
-				vfio_mp_sync_send_fd(conn_sock, fd);
-			}
-			break;
-		case SOCKET_CLR_GROUP:
-			/* wait for group fd */
-			vfio_data = vfio_mp_sync_receive_request(conn_sock);
-			if (vfio_data < 0) {
-				close(conn_sock);
-				continue;
-			}
-
-			ret = clear_group(vfio_data);
-
-			if (ret < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
-			else
-				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
-			break;
-		default:
-			vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			break;
-		}
-		close(conn_sock);
-	}
-}
-
-static int
-vfio_mp_sync_socket_setup(void)
-{
-	int ret, socket_fd;
-	struct sockaddr_un addr;
-	socklen_t sockaddr_len;
-
-	/* set up a socket */
-	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-	if (socket_fd < 0) {
-		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
-		return -1;
-	}
-
-	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
-	addr.sun_family = AF_UNIX;
-
-	sockaddr_len = sizeof(struct sockaddr_un);
-
-	unlink(addr.sun_path);
-
-	ret = bind(socket_fd, (struct sockaddr *) &addr, sockaddr_len);
-	if (ret) {
-		RTE_LOG(ERR, EAL, "Failed to bind socket: %s!\n", strerror(errno));
-		close(socket_fd);
-		return -1;
-	}
-
-	ret = listen(socket_fd, 50);
-	if (ret) {
-		RTE_LOG(ERR, EAL, "Failed to listen: %s!\n", strerror(errno));
-		close(socket_fd);
-		return -1;
-	}
-
-	/* save the socket in local configuration */
-	mp_socket_fd = socket_fd;
-
-	return 0;
-}
-
-/*
- * set up a local socket and tell it to listen for incoming connections
- */
-int
-vfio_mp_sync_setup(void)
-{
-	int ret;
-	char thread_name[RTE_MAX_THREAD_NAME_LEN];
-
-	if (vfio_mp_sync_socket_setup() < 0) {
-		RTE_LOG(ERR, EAL, "Failed to set up local socket!\n");
-		return -1;
-	}
-
-	ret = pthread_create(&socket_thread, NULL,
-			vfio_mp_sync_thread, NULL);
-	if (ret) {
-		RTE_LOG(ERR, EAL,
-			"Failed to create thread for communication with secondary processes!\n");
-		close(mp_socket_fd);
-		return -1;
-	}
-
-	/* Set thread_name for aid in debugging. */
-	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "vfio-sync");
-	ret = rte_thread_setname(socket_thread, thread_name);
-	if (ret)
-		RTE_LOG(DEBUG, EAL,
-			"Failed to set thread name for secondary processes!\n");
-
-	return 0;
-}
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index f866b70..0dc23bf 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -174,21 +174,6 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_pci_detach;
-	rte_pci_dump;
-	rte_pci_ioport_map;
-	rte_pci_ioport_read;
-	rte_pci_ioport_unmap;
-	rte_pci_ioport_write;
-	rte_pci_map_device;
-	rte_pci_probe;
-	rte_pci_probe_one;
-	rte_pci_read_config;
-	rte_pci_register;
-	rte_pci_scan;
-	rte_pci_unmap_device;
-	rte_pci_unregister;
-	rte_pci_write_config;
 	rte_vdev_init;
 	rte_vdev_register;
 	rte_vdev_uninit;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 99cdd54..af7af0a 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1076,8 +1076,6 @@ TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
 	} \
 } while (0)
 
-#define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
-
 /**
  * l2 tunnel configuration.
  */
diff --git a/lib/librte_pci/Makefile b/lib/librte_pci/Makefile
new file mode 100644
index 0000000..fc2fadb
--- /dev/null
+++ b/lib/librte_pci/Makefile
@@ -0,0 +1,48 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_pci.a
+
+CFLAGS := -I$(SRCDIR)/include -I$(SRCDIR) $(CFLAGS)
+CFLAGS += $(WERROR_FLAGS) -O3
+
+EXPORT_MAP := rte_pci_version.map
+
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_PCI) += rte_pci.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI)-include += include/rte_pci.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
new file mode 100644
index 0000000..3858e80
--- /dev/null
+++ b/lib/librte_pci/include/rte_pci.h
@@ -0,0 +1,279 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_PCI_H_
+#define _RTE_PCI_H_
+
+/**
+ * @file
+ *
+ * RTE PCI Library
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+
+/** Formatting string for PCI device identifier: Ex: 0000:00:01.0 */
+#define PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+#define PCI_PRI_STR_SIZE sizeof("XXXXXXXX:XX:XX.X")
+
+/** Short formatting string, without domain, for PCI device: Ex: 00:01.0 */
+#define PCI_SHORT_PRI_FMT "%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+
+/** Nb. of values in PCI device identifier format string. */
+#define PCI_FMT_NVAL 4
+
+/** Nb. of values in PCI resource format. */
+#define PCI_RESOURCE_FMT_NVAL 3
+
+/** Maximum number of PCI resources. */
+#define PCI_MAX_RESOURCE 6
+
+/**
+ * A structure describing an ID for a PCI driver. Each driver provides a
+ * table of these IDs for each device that it supports.
+ */
+struct rte_pci_id {
+	uint32_t class_id;            /**< Class ID or RTE_CLASS_ANY_ID. */
+	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
+	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
+	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
+	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
+};
+
+/**
+ * A structure describing the location of a PCI device.
+ */
+struct rte_pci_addr {
+	uint32_t domain;                /**< Device domain */
+	uint8_t bus;                    /**< Device bus */
+	uint8_t devid;                  /**< Device ID */
+	uint8_t function;               /**< Device function. */
+};
+
+/** Any PCI device identifier (vendor, device, ...) */
+#define PCI_ANY_ID (0xffff)
+#define RTE_CLASS_ANY_ID (0xffffff)
+
+/**
+ * A structure describing a PCI mapping.
+ */
+struct pci_map {
+	void *addr;
+	char *path;
+	uint64_t offset;
+	uint64_t size;
+	uint64_t phaddr;
+};
+
+/**
+ * A structure describing a mapped PCI resource.
+ * For multi-process we need to reproduce all PCI mappings in secondary
+ * processes, so save them in a tailq.
+ */
+struct mapped_pci_resource {
+	TAILQ_ENTRY(mapped_pci_resource) next;
+
+	struct rte_pci_addr pci_addr;
+	char path[PATH_MAX];
+	int nb_maps;
+	struct pci_map maps[PCI_MAX_RESOURCE];
+};
+
+/** mapped pci device list */
+TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
+
+/**< Internal use only - Macro used by pci addr parsing functions **/
+#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
+do {                                                               \
+	unsigned long val;                                      \
+	char *end;                                              \
+	errno = 0;                                              \
+	val = strtoul((in), &end, 16);                          \
+	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
+		return -EINVAL;                                 \
+	(fd) = (typeof (fd))val;                                \
+	(in) = end + 1;                                         \
+} while(0)
+
+/**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided without
+ * a domain prefix (i.e. domain returned is always 0)
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned. Domain will always be
+ *	returned as 0
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	dev_addr->domain = 0;
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+/**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided including
+ * a domain prefix.
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XXXX:XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+#undef GET_PCIADDR_FIELD
+
+/**
+ * Utility function to write a pci device name, this device name can later be
+ * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
+ * BDF helpers.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ */
+static inline void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+		char *output, size_t size)
+{
+	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+			    addr->domain, addr->bus,
+			    addr->devid, addr->function) >= 0);
+}
+
+/* Compare two PCI device addresses. */
+/**
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
+static inline int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			 const struct rte_pci_addr *addr2)
+{
+	uint64_t dev_addr, dev_addr2;
+
+	if ((addr == NULL) || (addr2 == NULL))
+		return -1;
+
+	dev_addr = ((uint64_t)addr->domain << 24) |
+		(addr->bus << 16) | (addr->devid << 8) | addr->function;
+	dev_addr2 = ((uint64_t)addr2->domain << 24) |
+		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+	if (dev_addr > dev_addr2)
+		return 1;
+	else if (dev_addr < dev_addr2)
+		return -1;
+	else
+		return 0;
+}
+
+/**
+ * Map a particular resource from a file.
+ *
+ * @param requested_addr
+ *      The starting address for the new mapping range.
+ * @param fd
+ *      The file descriptor.
+ * @param offset
+ *      The offset for the mapping range.
+ * @param size
+ *      The size for the mapping range.
+ * @param additional_flags
+ *      The additional flags for the mapping range.
+ * @return
+ *   - On success, the function returns a pointer to the mapped area.
+ *   - On error, the value MAP_FAILED is returned.
+ */
+void *pci_map_resource(void *requested_addr, int fd, off_t offset,
+		size_t size, int additional_flags);
+
+/**
+ * Unmap a particular resource.
+ *
+ * @param requested_addr
+ *      The address for the unmapping range.
+ * @param size
+ *      The size for the unmapping range.
+ */
+void pci_unmap_resource(void *requested_addr, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PCI_H_ */
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
new file mode 100644
index 0000000..9dfdd3f
--- /dev/null
+++ b/lib/librte_pci/rte_pci.c
@@ -0,0 +1,92 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+
+#include "rte_pci.h"
+
+/* map a particular resource from a file */
+void *
+pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+		 int additional_flags)
+{
+	void *mapaddr;
+
+	/* Map the PCI memory resource of device */
+	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+			MAP_SHARED | additional_flags, fd, offset);
+	if (mapaddr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
+			__func__, fd, requested_addr,
+			(unsigned long)size, (unsigned long)offset,
+			strerror(errno), mapaddr);
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
+
+	return mapaddr;
+}
+
+/* unmap a particular resource */
+void
+pci_unmap_resource(void *requested_addr, size_t size)
+{
+	if (requested_addr == NULL)
+		return;
+
+	/* Unmap the PCI memory resource of device */
+	if (munmap(requested_addr, size)) {
+		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+			__func__, requested_addr, (unsigned long)size,
+			strerror(errno));
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
+				requested_addr);
+}
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
new file mode 100644
index 0000000..64dec54
--- /dev/null
+++ b/lib/librte_pci/rte_pci_version.map
@@ -0,0 +1,8 @@
+DPDK_17.11 {
+	global:
+
+	pci_map_resource;
+	pci_unmap_resource;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index c25fdd9..f93618f 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -96,6 +96,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI)            += -lrte_pci
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
@@ -104,6 +105,8 @@ ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
 endif
 
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI_BUS)        += -lrte_bus_pci
+
 ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
 # plugins (link only if static libraries)
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 06/14] lib: include rte_bus_pci
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
                     ` (4 preceding siblings ...)
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 05/14] pci: introduce PCI lib and bus Gaetan Rivet
@ 2017-09-18  9:31   ` Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 07/14] drivers: " Gaetan Rivet
                     ` (9 subsequent siblings)
  15 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update the libraries, as structuraly unsound as it may be.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ether/rte_ethdev_pci.h          | 1 +
 lib/librte_eventdev/rte_eventdev_pmd_pci.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h
index 56b1072..722075e 100644
--- a/lib/librte_ether/rte_ethdev_pci.h
+++ b/lib/librte_ether/rte_ethdev_pci.h
@@ -36,6 +36,7 @@
 
 #include <rte_malloc.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 
 /**
diff --git a/lib/librte_eventdev/rte_eventdev_pmd_pci.h b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
index b6bd731..ade32b5 100644
--- a/lib/librte_eventdev/rte_eventdev_pmd_pci.h
+++ b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
@@ -50,6 +50,7 @@ extern "C" {
 #include <rte_eal.h>
 #include <rte_lcore.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "rte_eventdev_pmd.h"
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 07/14] drivers: include rte_bus_pci
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
                     ` (5 preceding siblings ...)
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 06/14] lib: include rte_bus_pci Gaetan Rivet
@ 2017-09-18  9:31   ` Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 08/14] test: " Gaetan Rivet
                     ` (8 subsequent siblings)
  15 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update drivers.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/bus/pci/bsd/rte_pci.c            | 1 +
 drivers/bus/pci/linux/rte_pci.c          | 1 +
 drivers/bus/pci/linux/rte_pci_uio.c      | 1 +
 drivers/bus/pci/linux/rte_pci_vfio.c     | 1 +
 drivers/bus/pci/linux/rte_vfio_mp_sync.c | 1 +
 drivers/bus/pci/private.h                | 1 +
 drivers/bus/pci/rte_pci_common.c         | 1 +
 drivers/bus/pci/rte_pci_common_uio.c     | 1 +
 drivers/crypto/qat/qat_qp.c              | 1 +
 drivers/event/octeontx/ssovf_probe.c     | 1 +
 drivers/net/ark/ark_ethdev.c             | 1 +
 drivers/net/avp/avp_ethdev.c             | 2 ++
 drivers/net/bnxt/bnxt.h                  | 1 +
 drivers/net/bonding/rte_eth_bond_args.c  | 1 +
 drivers/net/cxgbe/base/adapter.h         | 1 +
 drivers/net/cxgbe/cxgbe_ethdev.c         | 1 +
 drivers/net/e1000/em_ethdev.c            | 1 +
 drivers/net/e1000/igb_ethdev.c           | 1 +
 drivers/net/e1000/igb_pf.c               | 1 +
 drivers/net/ena/ena_ethdev.h             | 1 +
 drivers/net/enic/base/vnic_dev.h         | 4 +++-
 drivers/net/enic/enic_ethdev.c           | 1 +
 drivers/net/enic/enic_main.c             | 1 +
 drivers/net/i40e/i40e_ethdev.c           | 1 +
 drivers/net/i40e/i40e_ethdev_vf.c        | 1 +
 drivers/net/ixgbe/ixgbe_ethdev.c         | 1 +
 drivers/net/ixgbe/ixgbe_ethdev.h         | 1 +
 drivers/net/mlx5/mlx5.c                  | 1 +
 drivers/net/mlx5/mlx5_ethdev.c           | 1 +
 drivers/net/sfc/sfc.h                    | 1 +
 drivers/net/sfc/sfc_ethdev.c             | 1 +
 drivers/net/thunderx/nicvf_ethdev.c      | 1 +
 drivers/net/virtio/virtio_ethdev.c       | 1 +
 drivers/net/virtio/virtio_pci.h          | 1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c     | 1 +
 35 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/pci/bsd/rte_pci.c b/drivers/bus/pci/bsd/rte_pci.c
index 5bd0f4b..6c7ab81 100644
--- a/drivers/bus/pci/bsd/rte_pci.c
+++ b/drivers/bus/pci/bsd/rte_pci.c
@@ -57,6 +57,7 @@
 #include <rte_interrupts.h>
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_common.h>
 #include <rte_launch.h>
 #include <rte_memory.h>
diff --git a/drivers/bus/pci/linux/rte_pci.c b/drivers/bus/pci/linux/rte_pci.c
index c2ac82b..ba32d8b 100644
--- a/drivers/bus/pci/linux/rte_pci.c
+++ b/drivers/bus/pci/linux/rte_pci.c
@@ -37,6 +37,7 @@
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 #include <rte_devargs.h>
diff --git a/drivers/bus/pci/linux/rte_pci_uio.c b/drivers/bus/pci/linux/rte_pci_uio.c
index eed6d0f..1f0dacd 100644
--- a/drivers/bus/pci/linux/rte_pci_uio.c
+++ b/drivers/bus/pci/linux/rte_pci_uio.c
@@ -47,6 +47,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_common.h>
 #include <rte_malloc.h>
diff --git a/drivers/bus/pci/linux/rte_pci_vfio.c b/drivers/bus/pci/linux/rte_pci_vfio.c
index 81b67c9..ab63423 100644
--- a/drivers/bus/pci/linux/rte_pci_vfio.c
+++ b/drivers/bus/pci/linux/rte_pci_vfio.c
@@ -42,6 +42,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 
diff --git a/drivers/bus/pci/linux/rte_vfio_mp_sync.c b/drivers/bus/pci/linux/rte_vfio_mp_sync.c
index 2c1654d..d24eba1 100644
--- a/drivers/bus/pci/linux/rte_vfio_mp_sync.c
+++ b/drivers/bus/pci/linux/rte_vfio_mp_sync.c
@@ -50,6 +50,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 7ff1fc4..fdc2c81 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -37,6 +37,7 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 struct rte_pci_driver;
 struct rte_pci_device;
diff --git a/drivers/bus/pci/rte_pci_common.c b/drivers/bus/pci/rte_pci_common.c
index c37b85b..459ae42 100644
--- a/drivers/bus/pci/rte_pci_common.c
+++ b/drivers/bus/pci/rte_pci_common.c
@@ -45,6 +45,7 @@
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_per_lcore.h>
 #include <rte_memory.h>
 #include <rte_memzone.h>
diff --git a/drivers/bus/pci/rte_pci_common_uio.c b/drivers/bus/pci/rte_pci_common_uio.c
index 4365660..544c606 100644
--- a/drivers/bus/pci/rte_pci_common_uio.c
+++ b/drivers/bus/pci/rte_pci_common_uio.c
@@ -40,6 +40,7 @@
 
 #include <rte_eal.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tailq.h>
 #include <rte_log.h>
 #include <rte_malloc.h>
diff --git a/drivers/crypto/qat/qat_qp.c b/drivers/crypto/qat/qat_qp.c
index 5048d21..a22d6ef 100644
--- a/drivers/crypto/qat/qat_qp.c
+++ b/drivers/crypto/qat/qat_qp.c
@@ -37,6 +37,7 @@
 #include <rte_memzone.h>
 #include <rte_cryptodev_pmd.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_prefetch.h>
 
diff --git a/drivers/event/octeontx/ssovf_probe.c b/drivers/event/octeontx/ssovf_probe.c
index e1c0c6d..1cac4bc 100644
--- a/drivers/event/octeontx/ssovf_probe.c
+++ b/drivers/event/octeontx/ssovf_probe.c
@@ -35,6 +35,7 @@
 #include <rte_eal.h>
 #include <rte_io.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "ssovf_evdev.h"
 
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 6db362b..78a4d79 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -35,6 +35,7 @@
 #include <sys/stat.h>
 #include <dlfcn.h>
 
+#include <rte_bus_pci.h>
 #include <rte_ethdev_pci.h>
 #include <rte_kvargs.h>
 
diff --git a/drivers/net/avp/avp_ethdev.c b/drivers/net/avp/avp_ethdev.c
index c746a0e..194aadb 100644
--- a/drivers/net/avp/avp_ethdev.c
+++ b/drivers/net/avp/avp_ethdev.c
@@ -36,6 +36,7 @@
 #include <errno.h>
 #include <unistd.h>
 
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_memcpy.h>
@@ -45,6 +46,7 @@
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 405d94d..d7409a8 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -39,6 +39,7 @@
 #include <sys/queue.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_memory.h>
 #include <rte_lcore.h>
diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index bb634c6..2b7b464 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -33,6 +33,7 @@
 
 #include <rte_devargs.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 
 #include <cmdline_parse.h>
diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index 5e5f221..f2057af 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -36,6 +36,7 @@
 #ifndef __T4_ADAPTER_H__
 #define __T4_ADAPTER_H__
 
+#include <rte_bus_pci.h>
 #include <rte_mbuf.h>
 #include <rte_io.h>
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 7bca456..dc322da 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 3d4ab93..c52e5f7 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index e4f7a9f..36385cf 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/e1000/igb_pf.c b/drivers/net/e1000/igb_pf.c
index 6809d30..cd6ae2f 100644
--- a/drivers/net/e1000/igb_pf.c
+++ b/drivers/net/e1000/igb_pf.c
@@ -39,6 +39,7 @@
 #include <stdarg.h>
 #include <inttypes.h>
 
+#include <rte_bus_pci.h>
 #include <rte_interrupts.h>
 #include <rte_log.h>
 #include <rte_debug.h>
diff --git a/drivers/net/ena/ena_ethdev.h b/drivers/net/ena/ena_ethdev.h
index dc3080f..be8bc9f 100644
--- a/drivers/net/ena/ena_ethdev.h
+++ b/drivers/net/ena/ena_ethdev.h
@@ -35,6 +35,7 @@
 #define _ENA_ETHDEV_H_
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "ena_com.h"
 
diff --git a/drivers/net/enic/base/vnic_dev.h b/drivers/net/enic/base/vnic_dev.h
index 9a9e691..c9ca25b 100644
--- a/drivers/net/enic/base/vnic_dev.h
+++ b/drivers/net/enic/base/vnic_dev.h
@@ -35,8 +35,10 @@
 #ifndef _VNIC_DEV_H_
 #define _VNIC_DEV_H_
 
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+
 #include "enic_compat.h"
-#include "rte_pci.h"
 #include "vnic_resource.h"
 #include "vnic_devcmd.h"
 
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index da8fec2..681efb2 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -37,6 +37,7 @@
 
 #include <rte_dev.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_string_fns.h>
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 40dbec7..b35ad5d 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -40,6 +40,7 @@
 #include <libgen.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_memzone.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index f12aefa..88b6e50 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_eal.h>
 #include <rte_string_fns.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 73c315a..a7aff37 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -47,6 +47,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 9ca5cbc..a2d73a1 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index caa50c8..383ec71 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -41,6 +41,7 @@
 #include <rte_time.h>
 #include <rte_hash.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tm_driver.h>
 
 /* need update link, bit flag */
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b7e5046..968599e 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -58,6 +58,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_common.h>
 #include <rte_kvargs.h>
 #ifdef PEDANTIC
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index b0eb3cd..c2dc1f1 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -56,6 +56,7 @@
 #endif
 #include <rte_atomic.h>
 #include <rte_ethdev.h>
+#include <rte_bus_pci.h>
 #include <rte_mbuf.h>
 #include <rte_common.h>
 #include <rte_interrupts.h>
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 286d1ac..5944103 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -35,6 +35,7 @@
 #include <stdbool.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_kvargs.h>
 #include <rte_spinlock.h>
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 12bcd6f..74e2486 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -33,6 +33,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_errno.h>
 
 #include "efx.h"
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index edc17f1..e63dc4e 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -61,6 +61,7 @@
 #include <rte_malloc.h>
 #include <rte_random.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tailq.h>
 
 #include "base/nicvf_plat.h"
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index e320811..9a6850d 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -46,6 +46,7 @@
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_common.h>
 #include <rte_errno.h>
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 18caebd..c8261b7 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -37,6 +37,7 @@
 #include <stdint.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 
 struct virtqueue;
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 3910991..bf4900d 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 08/14] test: include rte_bus_pci
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
                     ` (6 preceding siblings ...)
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 07/14] drivers: " Gaetan Rivet
@ 2017-09-18  9:31   ` Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 09/14] app/testpmd: " Gaetan Rivet
                     ` (7 subsequent siblings)
  15 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update test applications.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 test/test/test_kni.c    | 1 +
 test/test/virtual_pmd.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/test/test/test_kni.c b/test/test/test_kni.c
index db17fdf..b2f05ec 100644
--- a/test/test/test_kni.c
+++ b/test/test/test_kni.c
@@ -42,6 +42,7 @@
 #include <rte_string_fns.h>
 #include <rte_mempool.h>
 #include <rte_ethdev.h>
+#include <rte_bus_pci.h>
 #include <rte_cycles.h>
 #include <rte_kni.h>
 
diff --git a/test/test/virtual_pmd.c b/test/test/virtual_pmd.c
index 9d46ad5..72e784a 100644
--- a/test/test/virtual_pmd.c
+++ b/test/test/virtual_pmd.c
@@ -34,6 +34,7 @@
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_memory.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 09/14] app/testpmd: include rte_bus_pci
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
                     ` (7 preceding siblings ...)
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 08/14] test: " Gaetan Rivet
@ 2017-09-18  9:31   ` Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 10/14] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
                     ` (6 subsequent siblings)
  15 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update applications.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 app/test-pmd/testpmd.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 1d1ee75..d0613b5 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -35,6 +35,7 @@
 #define _TESTPMD_H_
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_gro.h>
 
 #define RTE_PORT_ALL            (~(portid_t)0x0)
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 10/14] cryptodev: move PCI specific helpers to drivers/crypto
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
                     ` (8 preceding siblings ...)
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 09/14] app/testpmd: " Gaetan Rivet
@ 2017-09-18  9:31   ` Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 11/14] pci: avoid inlining functions Gaetan Rivet
                     ` (5 subsequent siblings)
  15 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet, Declan Doherty

Those helpers rely on the PCI bus driver implementation.
Other similar libraries relied on the bus-specifics being handled in
inlined functions, to be compiled on demand by drivers, once the proper
PCI dependency has been settled. This seems unsafe.

Move the PCI-specific helpers out of the lib directory to the
drivers/crypto directory, properly following the dependency hierarchy.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Cc: Declan Doherty <declan.doherty@intel.com>
---

This issue is seen by the vdev bus as well:

[PATCH 04/12] vdev: move to drivers/bus
http://dpdk.org/ml/archives/dev/2017-August/073740.html

 drivers/Makefile                                 |   2 +-
 drivers/crypto/Makefile                          |   4 +-
 drivers/crypto/pci/Makefile                      |  52 +++++++++
 drivers/crypto/pci/rte_cryptodev_pci.c           | 128 +++++++++++++++++++++++
 drivers/crypto/pci/rte_cryptodev_pci.h           |  94 +++++++++++++++++
 drivers/crypto/pci/rte_cryptodev_pci_version.map |   7 ++
 lib/librte_cryptodev/Makefile                    |   1 -
 lib/librte_cryptodev/rte_cryptodev_pci.h         |  92 ----------------
 lib/librte_cryptodev/rte_cryptodev_pmd.c         |  94 -----------------
 lib/librte_cryptodev/rte_cryptodev_version.map   |   2 -
 10 files changed, 285 insertions(+), 191 deletions(-)
 create mode 100644 drivers/crypto/pci/Makefile
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.c
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.h
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci_version.map
 delete mode 100644 lib/librte_cryptodev/rte_cryptodev_pci.h

diff --git a/drivers/Makefile b/drivers/Makefile
index 7fef66d..a5d3fa0 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -37,7 +37,7 @@ DEPDIRS-mempool := bus
 DIRS-y += net
 DEPDIRS-net := bus mempool
 DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
-DEPDIRS-crypto := mempool
+DEPDIRS-crypto := bus mempool
 DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += event
 DEPDIRS-event := bus
 
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 7a719b9..cfd6cb6 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_cryptodev
 
+DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
+DEPDIRS-pci = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm
 DEPDIRS-aesni_gcm = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb
@@ -42,7 +44,7 @@ DEPDIRS-armv8 = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_OPENSSL) += openssl
 DEPDIRS-openssl = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat
-DEPDIRS-qat = $(core-libs)
+DEPDIRS-qat = $(core-libs) librte_cryptodev_pci
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER) += scheduler
 DEPDIRS-scheduler = $(core-libs) librte_kvargs librte_reorder
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += snow3g
diff --git a/drivers/crypto/pci/Makefile b/drivers/crypto/pci/Makefile
new file mode 100644
index 0000000..da819f2
--- /dev/null
+++ b/drivers/crypto/pci/Makefile
@@ -0,0 +1,52 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A. All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND S.A. nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_cryptodev_pci.a
+
+# library version
+LIBABIVER := 1
+
+# build flags
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# library source files
+SRCS-y += rte_cryptodev_pci.c
+
+# export include files
+SYMLINK-y-include += rte_cryptodev_pci.h
+
+# versioning export map
+EXPORT_MAP := rte_cryptodev_pci_version.map
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/crypto/pci/rte_cryptodev_pci.c b/drivers/crypto/pci/rte_cryptodev_pci.c
new file mode 100644
index 0000000..a2a1366
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci.c
@@ -0,0 +1,128 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of the copyright holder nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_malloc.h>
+
+#include "rte_cryptodev_pci.h"
+
+int
+rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
+			size_t private_data_size,
+			cryptodev_pci_init_t dev_init)
+{
+	struct rte_cryptodev *cryptodev;
+
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+
+	int retval;
+
+	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name, rte_socket_id());
+	if (cryptodev == NULL)
+		return -ENOMEM;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc_socket(
+						"cryptodev private structure",
+						private_data_size,
+						RTE_CACHE_LINE_SIZE,
+						rte_socket_id());
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private "
+					"device data");
+	}
+
+	cryptodev->device = &pci_dev->device;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	/* Invoke PMD device initialization function */
+	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
+	retval = dev_init(cryptodev);
+	if (retval == 0)
+		return 0;
+
+	CDEV_LOG_ERR("driver %s: crypto_dev_init(vendor_id=0x%x device_id=0x%x)"
+			" failed", pci_dev->device.driver->name,
+			(unsigned int) pci_dev->id.vendor_id,
+			(unsigned int) pci_dev->id.device_id);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	return -ENXIO;
+}
+
+int
+rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
+		cryptodev_pci_uninit_t dev_uninit)
+{
+	struct rte_cryptodev *cryptodev;
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+	int ret;
+
+	if (pci_dev == NULL)
+		return -EINVAL;
+
+	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
+	if (cryptodev == NULL)
+		return -ENODEV;
+
+	/* Invoke PMD device uninit function */
+	if (dev_uninit) {
+		ret = dev_uninit(cryptodev);
+		if (ret)
+			return ret;
+	}
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->device = NULL;
+	cryptodev->data = NULL;
+
+	return 0;
+}
diff --git a/drivers/crypto/pci/rte_cryptodev_pci.h b/drivers/crypto/pci/rte_cryptodev_pci.h
new file mode 100644
index 0000000..97b6f1e
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci.h
@@ -0,0 +1,94 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of the copyright holder nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_CRYPTODEV_PCI_H_
+#define _RTE_CRYPTODEV_PCI_H_
+
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
+
+/**
+ * Initialisation function of a crypto driver invoked for each matching
+ * crypto PCI device detected during the PCI probing phase.
+ *
+ * @param	dev	The dev pointer is the address of the *rte_cryptodev*
+ *			structure associated with the matching device and which
+ *			has been [automatically] allocated in the
+ *			*rte_crypto_devices* array.
+ *
+ * @return
+ *   - 0: Success, the device is properly initialised by the driver.
+ *        In particular, the driver MUST have set up the *dev_ops* pointer
+ *        of the *dev* structure.
+ *   - <0: Error code of the device initialisation failure.
+ */
+typedef int (*cryptodev_pci_init_t)(struct rte_cryptodev *dev);
+
+/**
+ * Finalisation function of a driver invoked for each matching
+ * PCI device detected during the PCI closing phase.
+ *
+ * @param	dev	The dev pointer is the address of the *rte_cryptodev*
+ *			structure associated with the matching device and which
+ *			has been [automatically] allocated in the
+ *			*rte_crypto_devices* array.
+ *
+ *  * @return
+ *   - 0: Success, the device is properly finalised by the driver.
+ *        In particular, the driver MUST free the *dev_ops* pointer
+ *        of the *dev* structure.
+ *   - <0: Error code of the device initialisation failure.
+ */
+typedef int (*cryptodev_pci_uninit_t)(struct rte_cryptodev *dev);
+
+/**
+ * @internal
+ * Wrapper for use by pci drivers as a .probe function to attach to a crypto
+ * interface.
+ */
+int
+rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
+			size_t private_data_size,
+			cryptodev_pci_init_t dev_init);
+
+/**
+ * @internal
+ * Wrapper for use by pci drivers as a .remove function to detach a crypto
+ * interface.
+ */
+int
+rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
+		cryptodev_pci_uninit_t dev_uninit);
+
+#endif /* _RTE_CRYPTODEV_PCI_H_ */
diff --git a/drivers/crypto/pci/rte_cryptodev_pci_version.map b/drivers/crypto/pci/rte_cryptodev_pci_version.map
new file mode 100644
index 0000000..0510fef
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci_version.map
@@ -0,0 +1,7 @@
+DPDK_17.11 {
+	global:
+
+	rte_cryptodev_pci_generic_probe;
+	rte_cryptodev_pci_generic_remove;
+
+};
diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index 6ac331b..bd94cf7 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -49,7 +49,6 @@ SYMLINK-y-include += rte_crypto_sym.h
 SYMLINK-y-include += rte_cryptodev.h
 SYMLINK-y-include += rte_cryptodev_pmd.h
 SYMLINK-y-include += rte_cryptodev_vdev.h
-SYMLINK-y-include += rte_cryptodev_pci.h
 
 # versioning export map
 EXPORT_MAP := rte_cryptodev_version.map
diff --git a/lib/librte_cryptodev/rte_cryptodev_pci.h b/lib/librte_cryptodev/rte_cryptodev_pci.h
deleted file mode 100644
index 67eda96..0000000
--- a/lib/librte_cryptodev/rte_cryptodev_pci.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2017 Intel Corporation. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of the copyright holder nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_CRYPTODEV_PCI_H_
-#define _RTE_CRYPTODEV_PCI_H_
-
-#include <rte_pci.h>
-#include "rte_cryptodev.h"
-
-/**
- * Initialisation function of a crypto driver invoked for each matching
- * crypto PCI device detected during the PCI probing phase.
- *
- * @param	dev	The dev pointer is the address of the *rte_cryptodev*
- *			structure associated with the matching device and which
- *			has been [automatically] allocated in the
- *			*rte_crypto_devices* array.
- *
- * @return
- *   - 0: Success, the device is properly initialised by the driver.
- *        In particular, the driver MUST have set up the *dev_ops* pointer
- *        of the *dev* structure.
- *   - <0: Error code of the device initialisation failure.
- */
-typedef int (*cryptodev_pci_init_t)(struct rte_cryptodev *dev);
-
-/**
- * Finalisation function of a driver invoked for each matching
- * PCI device detected during the PCI closing phase.
- *
- * @param	dev	The dev pointer is the address of the *rte_cryptodev*
- *			structure associated with the matching device and which
- *			has been [automatically] allocated in the
- *			*rte_crypto_devices* array.
- *
- *  * @return
- *   - 0: Success, the device is properly finalised by the driver.
- *        In particular, the driver MUST free the *dev_ops* pointer
- *        of the *dev* structure.
- *   - <0: Error code of the device initialisation failure.
- */
-typedef int (*cryptodev_pci_uninit_t)(struct rte_cryptodev *dev);
-
-/**
- * @internal
- * Wrapper for use by pci drivers as a .probe function to attach to a crypto
- * interface.
- */
-int
-rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
-			size_t private_data_size,
-			cryptodev_pci_init_t dev_init);
-
-/**
- * @internal
- * Wrapper for use by pci drivers as a .remove function to detach a crypto
- * interface.
- */
-int
-rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
-		cryptodev_pci_uninit_t dev_uninit);
-
-#endif /* _RTE_CRYPTODEV_PCI_H_ */
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.c b/lib/librte_cryptodev/rte_cryptodev_pmd.c
index a57faad..ec5c33b 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.c
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.c
@@ -33,7 +33,6 @@
 #include <rte_malloc.h>
 
 #include "rte_cryptodev_vdev.h"
-#include "rte_cryptodev_pci.h"
 #include "rte_cryptodev_pmd.h"
 
 /**
@@ -154,96 +153,3 @@ rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
 	rte_kvargs_free(kvlist);
 	return ret;
 }
-
-int
-rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
-			size_t private_data_size,
-			cryptodev_pci_init_t dev_init)
-{
-	struct rte_cryptodev *cryptodev;
-
-	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
-
-	int retval;
-
-	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
-			sizeof(cryptodev_name));
-
-	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name, rte_socket_id());
-	if (cryptodev == NULL)
-		return -ENOMEM;
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-		cryptodev->data->dev_private =
-				rte_zmalloc_socket(
-						"cryptodev private structure",
-						private_data_size,
-						RTE_CACHE_LINE_SIZE,
-						rte_socket_id());
-
-		if (cryptodev->data->dev_private == NULL)
-			rte_panic("Cannot allocate memzone for private "
-					"device data");
-	}
-
-	cryptodev->device = &pci_dev->device;
-
-	/* init user callbacks */
-	TAILQ_INIT(&(cryptodev->link_intr_cbs));
-
-	/* Invoke PMD device initialization function */
-	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
-	retval = dev_init(cryptodev);
-	if (retval == 0)
-		return 0;
-
-	CDEV_LOG_ERR("driver %s: crypto_dev_init(vendor_id=0x%x device_id=0x%x)"
-			" failed", pci_dev->device.driver->name,
-			(unsigned int) pci_dev->id.vendor_id,
-			(unsigned int) pci_dev->id.device_id);
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-		rte_free(cryptodev->data->dev_private);
-
-	/* free crypto device */
-	rte_cryptodev_pmd_release_device(cryptodev);
-
-	return -ENXIO;
-}
-
-int
-rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
-		cryptodev_pci_uninit_t dev_uninit)
-{
-	struct rte_cryptodev *cryptodev;
-	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
-	int ret;
-
-	if (pci_dev == NULL)
-		return -EINVAL;
-
-	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
-			sizeof(cryptodev_name));
-
-	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
-	if (cryptodev == NULL)
-		return -ENODEV;
-
-	/* Invoke PMD device uninit function */
-	if (dev_uninit) {
-		ret = dev_uninit(cryptodev);
-		if (ret)
-			return ret;
-	}
-
-	/* free crypto device */
-	rte_cryptodev_pmd_release_device(cryptodev);
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-		rte_free(cryptodev->data->dev_private);
-
-	cryptodev->device = NULL;
-	cryptodev->data = NULL;
-
-	return 0;
-}
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index e9ba88a..496253d 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -68,8 +68,6 @@ DPDK_17.08 {
 	rte_cryptodev_get_aead_algo_enum;
 	rte_cryptodev_get_header_session_size;
 	rte_cryptodev_get_private_session_size;
-	rte_cryptodev_pci_generic_probe;
-	rte_cryptodev_pci_generic_remove;
 	rte_cryptodev_sym_capability_check_aead;
 	rte_cryptodev_sym_session_init;
 	rte_cryptodev_sym_session_clear;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 11/14] pci: avoid inlining functions
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
                     ` (9 preceding siblings ...)
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 10/14] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
@ 2017-09-18  9:31   ` Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 12/14] pci: avoid over-complicated macro Gaetan Rivet
                     ` (4 subsequent siblings)
  15 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Parsing operations should not happen in performance critical sections.
Headers should not propose implementations unless duly required.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_pci/include/rte_pci.h   | 69 ++++----------------------------------
 lib/librte_pci/rte_pci.c           | 65 +++++++++++++++++++++++++++++++++++
 lib/librte_pci/rte_pci_version.map |  4 +++
 3 files changed, 75 insertions(+), 63 deletions(-)

diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
index 3858e80..09a609a 100644
--- a/lib/librte_pci/include/rte_pci.h
+++ b/lib/librte_pci/include/rte_pci.h
@@ -126,19 +126,6 @@ struct mapped_pci_resource {
 /** mapped pci device list */
 TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 
-/**< Internal use only - Macro used by pci addr parsing functions **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
-do {                                                               \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
-
 /**
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided without
@@ -152,15 +139,7 @@ do {                                                               \
  * @return
  *  0 on success, negative on error.
  */
-static inline int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
+int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to produce a PCI Bus-Device-Function value
@@ -174,16 +153,7 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
  * @return
  *  0 on success, negative on error.
  */
-static inline int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-#undef GET_PCIADDR_FIELD
+int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to write a pci device name, this device name can later be
@@ -197,17 +167,9 @@ eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
  * @param size
  *	The output buffer size
  */
-static inline void
-rte_pci_device_name(const struct rte_pci_addr *addr,
-		char *output, size_t size)
-{
-	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
-	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
-			    addr->domain, addr->bus,
-			    addr->devid, addr->function) >= 0);
-}
+void rte_pci_device_name(const struct rte_pci_addr *addr,
+			 char *output, size_t size);
 
-/* Compare two PCI device addresses. */
 /**
  * Utility function to compare two PCI device addresses.
  *
@@ -220,27 +182,8 @@ rte_pci_device_name(const struct rte_pci_addr *addr,
  *	Positive on addr is greater than addr2.
  *	Negative on addr is less than addr2, or error.
  */
-static inline int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			 const struct rte_pci_addr *addr2)
-{
-	uint64_t dev_addr, dev_addr2;
-
-	if ((addr == NULL) || (addr2 == NULL))
-		return -1;
-
-	dev_addr = ((uint64_t)addr->domain << 24) |
-		(addr->bus << 16) | (addr->devid << 8) | addr->function;
-	dev_addr2 = ((uint64_t)addr2->domain << 24) |
-		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
-
-	if (dev_addr > dev_addr2)
-		return 1;
-	else if (dev_addr < dev_addr2)
-		return -1;
-	else
-		return 0;
-}
+int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			     const struct rte_pci_addr *addr2);
 
 /**
  * Map a particular resource from a file.
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index 9dfdd3f..8584b55 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -53,6 +53,71 @@
 
 #include "rte_pci.h"
 
+/* Macro used by pci addr parsing functions. **/
+#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                     \
+do {                                                            \
+	unsigned long val;                                      \
+	char *end;                                              \
+	errno = 0;                                              \
+	val = strtoul((in), &end, 16);                          \
+	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
+		return -EINVAL;                                 \
+	(fd) = (typeof (fd))val;                                \
+	(in) = end + 1;                                         \
+} while(0)
+
+int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	dev_addr->domain = 0;
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+		    char *output, size_t size)
+{
+	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+			    addr->domain, addr->bus,
+			    addr->devid, addr->function) >= 0);
+}
+
+int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			 const struct rte_pci_addr *addr2)
+{
+	uint64_t dev_addr, dev_addr2;
+
+	if ((addr == NULL) || (addr2 == NULL))
+		return -1;
+
+	dev_addr = ((uint64_t)addr->domain << 24) |
+		(addr->bus << 16) | (addr->devid << 8) | addr->function;
+	dev_addr2 = ((uint64_t)addr2->domain << 24) |
+		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+	if (dev_addr > dev_addr2)
+		return 1;
+	else if (dev_addr < dev_addr2)
+		return -1;
+	else
+		return 0;
+}
+
 /* map a particular resource from a file */
 void *
 pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index 64dec54..a940259 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -1,8 +1,12 @@
 DPDK_17.11 {
 	global:
 
+	eal_parse_pci_BDF;
+	eal_parse_pci_DomBDF;
 	pci_map_resource;
 	pci_unmap_resource;
+	rte_eal_compare_pci_addr;
+	rte_pci_device_name;
 
 	local: *;
 };
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 12/14] pci: avoid over-complicated macro
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
                     ` (10 preceding siblings ...)
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 11/14] pci: avoid inlining functions Gaetan Rivet
@ 2017-09-18  9:31   ` Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 13/14] pci: deprecate misnamed functions Gaetan Rivet
                     ` (3 subsequent siblings)
  15 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Using a macro helps writing the code to the detriment of the reader in
this case. This is backward. Write once, read many.

The few LOCs gained is not worth the opacity of the implementation.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_pci/rte_pci.c | 65 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 46 insertions(+), 19 deletions(-)

diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index 8584b55..cbb5359 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -53,36 +53,63 @@
 
 #include "rte_pci.h"
 
-/* Macro used by pci addr parsing functions. **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                     \
-do {                                                            \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
+static inline const char *
+get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
+{
+	unsigned long val;
+	uint8_t *u8 = _u8;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != dlm || val > UINT8_MAX) {
+		errno = errno ? errno : EINVAL;
+		return NULL;
+	}
+	*u8 = (uint8_t)val;
+	return end + 1;
+}
 
 int
 eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	const char *in = input;
+
 	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
 	return 0;
 }
 
 int
 eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
 {
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	const char *in = input;
+	unsigned long val;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != ':' || val > UINT16_MAX)
+		return -EINVAL;
+	dev_addr->domain = (uint16_t)val;
+	in = end + 1;
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
 	return 0;
 }
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 13/14] pci: deprecate misnamed functions
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
                     ` (11 preceding siblings ...)
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 12/14] pci: avoid over-complicated macro Gaetan Rivet
@ 2017-09-18  9:31   ` Gaetan Rivet
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 14/14] doc: add notes on EAL PCI API update Gaetan Rivet
                     ` (2 subsequent siblings)
  15 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Rename misnamed functions and describe the change in a deprecation
notice.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst | 10 ++++++
 lib/librte_pci/include/rte_pci.h     | 63 ++++++++++++++++++++++++++++++++++++
 lib/librte_pci/rte_pci.c             | 26 +++++++++++++++
 lib/librte_pci/rte_pci_version.map   |  4 +++
 4 files changed, 103 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 3362f33..1828e57 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -120,3 +120,13 @@ Deprecation Notices
   The non-"do-sig" versions of the hash tables will be removed
   (including the ``signature_offset`` parameter)
   and the "do-sig" versions renamed accordingly.
+
+* pci: Several exposed functions are misnamed.
+  The following functions are deprecated starting from v17.11 and are replaced:
+
+  - ``eal_parse_pci_BDF`` replaced by ``pci_parse_BDF``
+  - ``eal_parse_pci_DomBDF`` replaced by ``pci_parse_DomBDF``
+  - ``rte_eal_compare_pci_addr`` replaced by ``pci_addr_cmp``
+  - ``rte_pci_device_name`` replaced by ``pci_device_name``
+
+  The functions are only renamed. Their behavior is not affected.
diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
index 09a609a..224cea0 100644
--- a/lib/librte_pci/include/rte_pci.h
+++ b/lib/librte_pci/include/rte_pci.h
@@ -127,6 +127,7 @@ struct mapped_pci_resource {
 TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 
 /**
+ * @deprecated
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided without
  * a domain prefix (i.e. domain returned is always 0)
@@ -143,6 +144,22 @@ int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided without
+ * a domain prefix (i.e. domain returned is always 0)
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned. Domain will always be
+ *	returned as 0
+ * @return
+ *  0 on success, negative on error.
+ */
+int pci_parse_BDF(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
+ * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided including
  * a domain prefix.
  *
@@ -156,6 +173,21 @@ int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided including
+ * a domain prefix.
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XXXX:XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned
+ * @return
+ *  0 on success, negative on error.
+ */
+int pci_parse_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
  * Utility function to write a pci device name, this device name can later be
  * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
  * BDF helpers.
@@ -171,6 +203,22 @@ void rte_pci_device_name(const struct rte_pci_addr *addr,
 			 char *output, size_t size);
 
 /**
+ * Utility function to write a pci device name, this device name can later be
+ * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
+ * BDF helpers.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ */
+void pci_device_name(const struct rte_pci_addr *addr,
+		     char *output, size_t size);
+
+/**
+ * @deprecated
  * Utility function to compare two PCI device addresses.
  *
  * @param addr
@@ -186,6 +234,21 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 			     const struct rte_pci_addr *addr2);
 
 /**
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
+int pci_addr_cmp(const struct rte_pci_addr *addr,
+		 const struct rte_pci_addr *addr2);
+
+/**
  * Map a particular resource from a file.
  *
  * @param requested_addr
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index cbb5359..54ce10d 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -73,6 +73,12 @@ get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
 int
 eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	return pci_parse_BDF(input, dev_addr);
+}
+
+int
+pci_parse_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
 	const char *in = input;
 
 	dev_addr->domain = 0;
@@ -91,6 +97,12 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 int
 eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	return pci_parse_DomBDF(input, dev_addr);
+}
+
+int
+pci_parse_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
 	const char *in = input;
 	unsigned long val;
 	char *end;
@@ -117,6 +129,13 @@ void
 rte_pci_device_name(const struct rte_pci_addr *addr,
 		    char *output, size_t size)
 {
+	pci_device_name(addr, output, size);
+}
+
+void
+pci_device_name(const struct rte_pci_addr *addr,
+		char *output, size_t size)
+{
 	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
 	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
 			    addr->domain, addr->bus,
@@ -127,6 +146,13 @@ int
 rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 			 const struct rte_pci_addr *addr2)
 {
+	return pci_addr_cmp(addr, addr2);
+}
+
+int
+pci_addr_cmp(const struct rte_pci_addr *addr,
+	     const struct rte_pci_addr *addr2)
+{
 	uint64_t dev_addr, dev_addr2;
 
 	if ((addr == NULL) || (addr2 == NULL))
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index a940259..541769f 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -3,7 +3,11 @@ DPDK_17.11 {
 
 	eal_parse_pci_BDF;
 	eal_parse_pci_DomBDF;
+	pci_addr_cmp;
+	pci_device_name;
 	pci_map_resource;
+	pci_parse_BDF;
+	pci_parse_DomBDF;
 	pci_unmap_resource;
 	rte_eal_compare_pci_addr;
 	rte_pci_device_name;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v2 14/14] doc: add notes on EAL PCI API update
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
                     ` (12 preceding siblings ...)
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 13/14] pci: deprecate misnamed functions Gaetan Rivet
@ 2017-09-18  9:31   ` Gaetan Rivet
  2017-09-18 11:22     ` Mcnamara, John
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
  2017-10-11 14:19   ` [dpdk-dev] [PATCH v2 00/14] " Doherty, Declan
  15 siblings, 1 reply; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-18  9:31 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Add a section related to EAL API changes to 17.11 release notes.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 doc/guides/rel_notes/release_17_11.rst | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 8bf91bd..d5546ba 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -130,6 +130,34 @@ API Changes
   * Rework start and stop APIs into ``rte_service_runstate_set``
   * Added API to set runstate of service implementation to indicate readyness
 
+* **PCI bus API moved outside of the EAL**
+
+  The PCI bus previously implemented within the EAL has been moved.
+  A first part has been added as an RTE library providing PCI helpers to
+  parse device locations or other such utilities.
+  A second part consisting in the actual bus driver has been moved to its
+  proper subdirectory, without changing its functionalities.
+
+  As such, several PCI-related functions are not proposed by the EAL anymore:
+
+  * rte_pci_detach
+  * rte_pci_dump
+  * rte_pci_ioport_map
+  * rte_pci_ioport_read
+  * rte_pci_ioport_unmap
+  * rte_pci_ioport_write
+  * rte_pci_map_device
+  * rte_pci_probe
+  * rte_pci_probe_one
+  * rte_pci_read_config
+  * rte_pci_register
+  * rte_pci_scan
+  * rte_pci_unmap_device
+  * rte_pci_unregister
+  * rte_pci_write_config
+
+  These functions are made available either as part of ``librte_pci`` or
+  ``librte_bus_pci``.
 
 ABI Changes
 -----------
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v2 01/14] eal: expose rte_eal_using_phys_addrs
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 01/14] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
@ 2017-09-18 10:47     ` Shreyansh Jain
  2017-09-18 11:37       ` Gaëtan Rivet
  0 siblings, 1 reply; 156+ messages in thread
From: Shreyansh Jain @ 2017-09-18 10:47 UTC (permalink / raw)
  To: Gaetan Rivet; +Cc: dev

Hello Gaetan,

On Monday 18 September 2017 03:01 PM, Gaetan Rivet wrote:
> This function was previously private to the EAL layer.
> Other subsystems requires it, such as the PCI bus.
> 
> In order not to force other components to include stdbool, which is
> incompatible with several NIC drivers, the return type has
> been changed from bool to int.
> 
> Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> ---

[...]

> diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
> index 5279128..af8719b 100644
> --- a/lib/librte_eal/linuxapp/eal/eal_memory.c
> +++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
> @@ -1542,7 +1542,7 @@ rte_eal_hugepage_attach(void)
>   	return -1;
>   }
>   
> -bool
> +int
>   rte_eal_using_phys_addrs(void)
>   {
>   	return phys_addrs_available;
> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> index 8c08b8d..f866b70 100644
> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> @@ -205,6 +205,7 @@ DPDK_17.08 {

This symbol should be added to 17.11, isn't it?

>   	rte_bus_find;
>   	rte_bus_find_by_device;
>   	rte_bus_find_by_name;
> +	rte_eal_using_phys_addrs;
>   	rte_log_get_level;
>   
>   } DPDK_17.05;
> 
-
Shreyansh

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v2 14/14] doc: add notes on EAL PCI API update
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 14/14] doc: add notes on EAL PCI API update Gaetan Rivet
@ 2017-09-18 11:22     ` Mcnamara, John
  0 siblings, 0 replies; 156+ messages in thread
From: Mcnamara, John @ 2017-09-18 11:22 UTC (permalink / raw)
  To: Gaetan Rivet, dev



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Gaetan Rivet
> Sent: Monday, September 18, 2017 10:32 AM
> To: dev@dpdk.org
> Cc: Gaetan Rivet <gaetan.rivet@6wind.com>
> Subject: [dpdk-dev] [PATCH v2 14/14] doc: add notes on EAL PCI API update
> 
> Add a section related to EAL API changes to 17.11 release notes.
> 
> Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>


Acked-by: John McNamara <john.mcnamara@intel.com>

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v2 01/14] eal: expose rte_eal_using_phys_addrs
  2017-09-18 10:47     ` Shreyansh Jain
@ 2017-09-18 11:37       ` Gaëtan Rivet
  0 siblings, 0 replies; 156+ messages in thread
From: Gaëtan Rivet @ 2017-09-18 11:37 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev

On Mon, Sep 18, 2017 at 04:17:08PM +0530, Shreyansh Jain wrote:
> Hello Gaetan,
> 
> On Monday 18 September 2017 03:01 PM, Gaetan Rivet wrote:
> >This function was previously private to the EAL layer.
> >Other subsystems requires it, such as the PCI bus.
> >
> >In order not to force other components to include stdbool, which is
> >incompatible with several NIC drivers, the return type has
> >been changed from bool to int.
> >
> >Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> >---
> 
> [...]
> 
> >diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
> >index 5279128..af8719b 100644
> >--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
> >+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
> >@@ -1542,7 +1542,7 @@ rte_eal_hugepage_attach(void)
> >  	return -1;
> >  }
> >-bool
> >+int
> >  rte_eal_using_phys_addrs(void)
> >  {
> >  	return phys_addrs_available;
> >diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> >index 8c08b8d..f866b70 100644
> >--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> >+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> >@@ -205,6 +205,7 @@ DPDK_17.08 {
> 
> This symbol should be added to 17.11, isn't it?
> 

Ah, yes indeed

> >  	rte_bus_find;
> >  	rte_bus_find_by_device;
> >  	rte_bus_find_by_name;
> >+	rte_eal_using_phys_addrs;
> >  	rte_log_get_level;
> >  } DPDK_17.05;
> >
> -
> Shreyansh

-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v2 05/14] pci: introduce PCI lib and bus
  2017-09-18 11:53     ` Shreyansh Jain
@ 2017-09-18 11:51       ` Gaëtan Rivet
  2017-09-18 12:18         ` Shreyansh Jain
  0 siblings, 1 reply; 156+ messages in thread
From: Gaëtan Rivet @ 2017-09-18 11:51 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev

Hey,

On Mon, Sep 18, 2017 at 05:23:23PM +0530, Shreyansh Jain wrote:
> Hello Gaetan,
> 
> On Monday 18 September 2017 03:01 PM, Gaetan Rivet wrote:
> >The PCI lib defines the types and methods allowing to use PCI elements.
> >
> >The PCI bus implements a bus driver for PCI devices by constructing
> >rte_bus elements using the PCI lib.
> >
> >Move the relevant code out of the EAL to their expected place.
> >
> >Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> >---
> >  config/common_base                              |  10 +
> >  drivers/bus/Makefile                            |   2 +
> >  drivers/bus/pci/Makefile                        |  59 ++
> >  drivers/bus/pci/bsd/Makefile                    |  32 ++
> >  drivers/bus/pci/bsd/rte_pci.c                   | 670 ++++++++++++++++++++++
> >  drivers/bus/pci/include/rte_bus_pci.h           | 387 +++++++++++++
> >  drivers/bus/pci/linux/Makefile                  |  37 ++
> >  drivers/bus/pci/linux/rte_pci.c                 | 722 ++++++++++++++++++++++++
> >  drivers/bus/pci/linux/rte_pci_init.h            |  97 ++++
> >  drivers/bus/pci/linux/rte_pci_uio.c             | 567 +++++++++++++++++++
> >  drivers/bus/pci/linux/rte_pci_vfio.c            | 674 ++++++++++++++++++++++
> >  drivers/bus/pci/linux/rte_vfio_mp_sync.c        | 424 ++++++++++++++
> >  drivers/bus/pci/private.h                       | 173 ++++++
> >  drivers/bus/pci/rte_bus_pci_version.map         |  21 +
> >  drivers/bus/pci/rte_pci_common.c                | 542 ++++++++++++++++++
> >  drivers/bus/pci/rte_pci_common_uio.c            | 234 ++++++++
> >  lib/Makefile                                    |   2 +
> >  lib/librte_eal/bsdapp/eal/Makefile              |   3 -
> >  lib/librte_eal/bsdapp/eal/eal_pci.c             | 670 ----------------------
> >  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  15 -
> >  lib/librte_eal/common/Makefile                  |   2 +-
> >  lib/librte_eal/common/eal_common_pci.c          | 580 -------------------
> >  lib/librte_eal/common/eal_common_pci_uio.c      | 233 --------
> >  lib/librte_eal/common/include/rte_pci.h         | 598 --------------------
> >  lib/librte_eal/linuxapp/eal/Makefile            |  10 -
> >  lib/librte_eal/linuxapp/eal/eal_pci.c           | 722 ------------------------
> >  lib/librte_eal/linuxapp/eal/eal_pci_init.h      |  97 ----
> >  lib/librte_eal/linuxapp/eal/eal_pci_uio.c       | 567 -------------------
> >  lib/librte_eal/linuxapp/eal/eal_pci_vfio.c      | 674 ----------------------
> >  lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c  | 424 --------------
> >  lib/librte_eal/linuxapp/eal/rte_eal_version.map |  15 -
> >  lib/librte_ether/rte_ethdev.h                   |   2 -
> >  lib/librte_pci/Makefile                         |  48 ++
> >  lib/librte_pci/include/rte_pci.h                | 279 +++++++++
> >  lib/librte_pci/rte_pci.c                        |  92 +++
> >  lib/librte_pci/rte_pci_version.map              |   8 +
> >  mk/rte.app.mk                                   |   3 +
> >  37 files changed, 5084 insertions(+), 4611 deletions(-)
> >  create mode 100644 drivers/bus/pci/Makefile
> >  create mode 100644 drivers/bus/pci/bsd/Makefile
> >  create mode 100644 drivers/bus/pci/bsd/rte_pci.c
> >  create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
> >  create mode 100644 drivers/bus/pci/linux/Makefile
> >  create mode 100644 drivers/bus/pci/linux/rte_pci.c
> >  create mode 100644 drivers/bus/pci/linux/rte_pci_init.h
> >  create mode 100644 drivers/bus/pci/linux/rte_pci_uio.c
> >  create mode 100644 drivers/bus/pci/linux/rte_pci_vfio.c
> >  create mode 100644 drivers/bus/pci/linux/rte_vfio_mp_sync.c
> >  create mode 100644 drivers/bus/pci/private.h
> >  create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
> >  create mode 100644 drivers/bus/pci/rte_pci_common.c
> >  create mode 100644 drivers/bus/pci/rte_pci_common_uio.c
> >  delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
> >  delete mode 100644 lib/librte_eal/common/eal_common_pci.c
> >  delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
> >  delete mode 100644 lib/librte_eal/common/include/rte_pci.h
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
> >  create mode 100644 lib/librte_pci/Makefile
> >  create mode 100644 lib/librte_pci/include/rte_pci.h
> >  create mode 100644 lib/librte_pci/rte_pci.c
> >  create mode 100644 lib/librte_pci/rte_pci_version.map
> >
> 
> <lot of snip here...>
> 
> >+#endif /* _PCI_PRIVATE_H_ */
> >diff --git a/drivers/bus/pci/rte_bus_pci_version.map b/drivers/bus/pci/rte_bus_pci_version.map
> >new file mode 100644
> >index 0000000..eca49e9
> >--- /dev/null
> >+++ b/drivers/bus/pci/rte_bus_pci_version.map
> >@@ -0,0 +1,21 @@
> >+DPDK_17.08 {
> 
> You might want to bump this to 17.11.
> 

Thanks, fixing this.

> >+	global:
> >+
> >+	rte_pci_detach;
> >+	rte_pci_dump;
> >+	rte_pci_ioport_map;
> >+	rte_pci_ioport_read;
> >+	rte_pci_ioport_unmap;
> >+	rte_pci_ioport_write;
> >+	rte_pci_map_device;
> >+	rte_pci_probe;
> >+	rte_pci_probe_one;
> >+	rte_pci_read_config;
> >+	rte_pci_register;
> >+	rte_pci_scan;
> >+	rte_pci_unmap_device;
> >+	rte_pci_unregister;
> >+	rte_pci_write_config;
> >+
> >+	local: *;
> >+};
> 
> This is huuuge patch :( and I am not yet through it (most of it is movement
> so I doubt anything major would be problem here).
> Just the above comment in case you are spinning a new series.
> 
> 

Thanks for reading the patch.

Yes, most of it is moving the code as-is to a new location.
I tried to reduce it, but at some point it does not really make sense
anymore.

I think the important thing to look for here is the build system,
dependency graph and the division of the PCI API between the lib and the
bus driver.

I divided it along the lines of the rte_pci_device being defined or not.
Anything using an rte_pci_device going to the bus and everything
else going to the lib.

I'm mostly worried about this divide. Having the rte_pci_device defined
seems mostly of the responsibility of the bus driver, in my opinion. I'd
like to hear others'.

-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v2 05/14] pci: introduce PCI lib and bus
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 05/14] pci: introduce PCI lib and bus Gaetan Rivet
@ 2017-09-18 11:53     ` Shreyansh Jain
  2017-09-18 11:51       ` Gaëtan Rivet
  0 siblings, 1 reply; 156+ messages in thread
From: Shreyansh Jain @ 2017-09-18 11:53 UTC (permalink / raw)
  To: Gaetan Rivet; +Cc: dev

Hello Gaetan,

On Monday 18 September 2017 03:01 PM, Gaetan Rivet wrote:
> The PCI lib defines the types and methods allowing to use PCI elements.
> 
> The PCI bus implements a bus driver for PCI devices by constructing
> rte_bus elements using the PCI lib.
> 
> Move the relevant code out of the EAL to their expected place.
> 
> Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> ---
>   config/common_base                              |  10 +
>   drivers/bus/Makefile                            |   2 +
>   drivers/bus/pci/Makefile                        |  59 ++
>   drivers/bus/pci/bsd/Makefile                    |  32 ++
>   drivers/bus/pci/bsd/rte_pci.c                   | 670 ++++++++++++++++++++++
>   drivers/bus/pci/include/rte_bus_pci.h           | 387 +++++++++++++
>   drivers/bus/pci/linux/Makefile                  |  37 ++
>   drivers/bus/pci/linux/rte_pci.c                 | 722 ++++++++++++++++++++++++
>   drivers/bus/pci/linux/rte_pci_init.h            |  97 ++++
>   drivers/bus/pci/linux/rte_pci_uio.c             | 567 +++++++++++++++++++
>   drivers/bus/pci/linux/rte_pci_vfio.c            | 674 ++++++++++++++++++++++
>   drivers/bus/pci/linux/rte_vfio_mp_sync.c        | 424 ++++++++++++++
>   drivers/bus/pci/private.h                       | 173 ++++++
>   drivers/bus/pci/rte_bus_pci_version.map         |  21 +
>   drivers/bus/pci/rte_pci_common.c                | 542 ++++++++++++++++++
>   drivers/bus/pci/rte_pci_common_uio.c            | 234 ++++++++
>   lib/Makefile                                    |   2 +
>   lib/librte_eal/bsdapp/eal/Makefile              |   3 -
>   lib/librte_eal/bsdapp/eal/eal_pci.c             | 670 ----------------------
>   lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  15 -
>   lib/librte_eal/common/Makefile                  |   2 +-
>   lib/librte_eal/common/eal_common_pci.c          | 580 -------------------
>   lib/librte_eal/common/eal_common_pci_uio.c      | 233 --------
>   lib/librte_eal/common/include/rte_pci.h         | 598 --------------------
>   lib/librte_eal/linuxapp/eal/Makefile            |  10 -
>   lib/librte_eal/linuxapp/eal/eal_pci.c           | 722 ------------------------
>   lib/librte_eal/linuxapp/eal/eal_pci_init.h      |  97 ----
>   lib/librte_eal/linuxapp/eal/eal_pci_uio.c       | 567 -------------------
>   lib/librte_eal/linuxapp/eal/eal_pci_vfio.c      | 674 ----------------------
>   lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c  | 424 --------------
>   lib/librte_eal/linuxapp/eal/rte_eal_version.map |  15 -
>   lib/librte_ether/rte_ethdev.h                   |   2 -
>   lib/librte_pci/Makefile                         |  48 ++
>   lib/librte_pci/include/rte_pci.h                | 279 +++++++++
>   lib/librte_pci/rte_pci.c                        |  92 +++
>   lib/librte_pci/rte_pci_version.map              |   8 +
>   mk/rte.app.mk                                   |   3 +
>   37 files changed, 5084 insertions(+), 4611 deletions(-)
>   create mode 100644 drivers/bus/pci/Makefile
>   create mode 100644 drivers/bus/pci/bsd/Makefile
>   create mode 100644 drivers/bus/pci/bsd/rte_pci.c
>   create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
>   create mode 100644 drivers/bus/pci/linux/Makefile
>   create mode 100644 drivers/bus/pci/linux/rte_pci.c
>   create mode 100644 drivers/bus/pci/linux/rte_pci_init.h
>   create mode 100644 drivers/bus/pci/linux/rte_pci_uio.c
>   create mode 100644 drivers/bus/pci/linux/rte_pci_vfio.c
>   create mode 100644 drivers/bus/pci/linux/rte_vfio_mp_sync.c
>   create mode 100644 drivers/bus/pci/private.h
>   create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
>   create mode 100644 drivers/bus/pci/rte_pci_common.c
>   create mode 100644 drivers/bus/pci/rte_pci_common_uio.c
>   delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
>   delete mode 100644 lib/librte_eal/common/eal_common_pci.c
>   delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
>   delete mode 100644 lib/librte_eal/common/include/rte_pci.h
>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
>   create mode 100644 lib/librte_pci/Makefile
>   create mode 100644 lib/librte_pci/include/rte_pci.h
>   create mode 100644 lib/librte_pci/rte_pci.c
>   create mode 100644 lib/librte_pci/rte_pci_version.map
> 

<lot of snip here...>

> +#endif /* _PCI_PRIVATE_H_ */
> diff --git a/drivers/bus/pci/rte_bus_pci_version.map b/drivers/bus/pci/rte_bus_pci_version.map
> new file mode 100644
> index 0000000..eca49e9
> --- /dev/null
> +++ b/drivers/bus/pci/rte_bus_pci_version.map
> @@ -0,0 +1,21 @@
> +DPDK_17.08 {

You might want to bump this to 17.11.

> +	global:
> +
> +	rte_pci_detach;
> +	rte_pci_dump;
> +	rte_pci_ioport_map;
> +	rte_pci_ioport_read;
> +	rte_pci_ioport_unmap;
> +	rte_pci_ioport_write;
> +	rte_pci_map_device;
> +	rte_pci_probe;
> +	rte_pci_probe_one;
> +	rte_pci_read_config;
> +	rte_pci_register;
> +	rte_pci_scan;
> +	rte_pci_unmap_device;
> +	rte_pci_unregister;
> +	rte_pci_write_config;
> +
> +	local: *;
> +};

This is huuuge patch :( and I am not yet through it (most of it is 
movement so I doubt anything major would be problem here).
Just the above comment in case you are spinning a new series.

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v2 05/14] pci: introduce PCI lib and bus
  2017-09-18 11:51       ` Gaëtan Rivet
@ 2017-09-18 12:18         ` Shreyansh Jain
  0 siblings, 0 replies; 156+ messages in thread
From: Shreyansh Jain @ 2017-09-18 12:18 UTC (permalink / raw)
  To: Gaëtan Rivet; +Cc: dev

On Monday 18 September 2017 05:21 PM, Gaëtan Rivet wrote:
> Hey,
> 
> On Mon, Sep 18, 2017 at 05:23:23PM +0530, Shreyansh Jain wrote:
>> Hello Gaetan,
>>
>> On Monday 18 September 2017 03:01 PM, Gaetan Rivet wrote:
>>> The PCI lib defines the types and methods allowing to use PCI elements.
>>>
>>> The PCI bus implements a bus driver for PCI devices by constructing
>>> rte_bus elements using the PCI lib.
>>>
>>> Move the relevant code out of the EAL to their expected place.
>>>
>>> Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
>>> ---
>>>   config/common_base                              |  10 +
>>>   drivers/bus/Makefile                            |   2 +
>>>   drivers/bus/pci/Makefile                        |  59 ++
>>>   drivers/bus/pci/bsd/Makefile                    |  32 ++
>>>   drivers/bus/pci/bsd/rte_pci.c                   | 670 ++++++++++++++++++++++
>>>   drivers/bus/pci/include/rte_bus_pci.h           | 387 +++++++++++++
>>>   drivers/bus/pci/linux/Makefile                  |  37 ++
>>>   drivers/bus/pci/linux/rte_pci.c                 | 722 ++++++++++++++++++++++++
>>>   drivers/bus/pci/linux/rte_pci_init.h            |  97 ++++
>>>   drivers/bus/pci/linux/rte_pci_uio.c             | 567 +++++++++++++++++++
>>>   drivers/bus/pci/linux/rte_pci_vfio.c            | 674 ++++++++++++++++++++++
>>>   drivers/bus/pci/linux/rte_vfio_mp_sync.c        | 424 ++++++++++++++
>>>   drivers/bus/pci/private.h                       | 173 ++++++
>>>   drivers/bus/pci/rte_bus_pci_version.map         |  21 +
>>>   drivers/bus/pci/rte_pci_common.c                | 542 ++++++++++++++++++
>>>   drivers/bus/pci/rte_pci_common_uio.c            | 234 ++++++++
>>>   lib/Makefile                                    |   2 +
>>>   lib/librte_eal/bsdapp/eal/Makefile              |   3 -
>>>   lib/librte_eal/bsdapp/eal/eal_pci.c             | 670 ----------------------
>>>   lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  15 -
>>>   lib/librte_eal/common/Makefile                  |   2 +-
>>>   lib/librte_eal/common/eal_common_pci.c          | 580 -------------------
>>>   lib/librte_eal/common/eal_common_pci_uio.c      | 233 --------
>>>   lib/librte_eal/common/include/rte_pci.h         | 598 --------------------
>>>   lib/librte_eal/linuxapp/eal/Makefile            |  10 -
>>>   lib/librte_eal/linuxapp/eal/eal_pci.c           | 722 ------------------------
>>>   lib/librte_eal/linuxapp/eal/eal_pci_init.h      |  97 ----
>>>   lib/librte_eal/linuxapp/eal/eal_pci_uio.c       | 567 -------------------
>>>   lib/librte_eal/linuxapp/eal/eal_pci_vfio.c      | 674 ----------------------
>>>   lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c  | 424 --------------
>>>   lib/librte_eal/linuxapp/eal/rte_eal_version.map |  15 -
>>>   lib/librte_ether/rte_ethdev.h                   |   2 -
>>>   lib/librte_pci/Makefile                         |  48 ++
>>>   lib/librte_pci/include/rte_pci.h                | 279 +++++++++
>>>   lib/librte_pci/rte_pci.c                        |  92 +++
>>>   lib/librte_pci/rte_pci_version.map              |   8 +
>>>   mk/rte.app.mk                                   |   3 +
>>>   37 files changed, 5084 insertions(+), 4611 deletions(-)
>>>   create mode 100644 drivers/bus/pci/Makefile
>>>   create mode 100644 drivers/bus/pci/bsd/Makefile
>>>   create mode 100644 drivers/bus/pci/bsd/rte_pci.c
>>>   create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
>>>   create mode 100644 drivers/bus/pci/linux/Makefile
>>>   create mode 100644 drivers/bus/pci/linux/rte_pci.c
>>>   create mode 100644 drivers/bus/pci/linux/rte_pci_init.h
>>>   create mode 100644 drivers/bus/pci/linux/rte_pci_uio.c
>>>   create mode 100644 drivers/bus/pci/linux/rte_pci_vfio.c
>>>   create mode 100644 drivers/bus/pci/linux/rte_vfio_mp_sync.c
>>>   create mode 100644 drivers/bus/pci/private.h
>>>   create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
>>>   create mode 100644 drivers/bus/pci/rte_pci_common.c
>>>   create mode 100644 drivers/bus/pci/rte_pci_common_uio.c
>>>   delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
>>>   delete mode 100644 lib/librte_eal/common/eal_common_pci.c
>>>   delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
>>>   delete mode 100644 lib/librte_eal/common/include/rte_pci.h
>>>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
>>>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
>>>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
>>>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
>>>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
>>>   create mode 100644 lib/librte_pci/Makefile
>>>   create mode 100644 lib/librte_pci/include/rte_pci.h
>>>   create mode 100644 lib/librte_pci/rte_pci.c
>>>   create mode 100644 lib/librte_pci/rte_pci_version.map
>>>
>>
>> <lot of snip here...>
>>
>>> +#endif /* _PCI_PRIVATE_H_ */
>>> diff --git a/drivers/bus/pci/rte_bus_pci_version.map b/drivers/bus/pci/rte_bus_pci_version.map
>>> new file mode 100644
>>> index 0000000..eca49e9
>>> --- /dev/null
>>> +++ b/drivers/bus/pci/rte_bus_pci_version.map
>>> @@ -0,0 +1,21 @@
>>> +DPDK_17.08 {
>>
>> You might want to bump this to 17.11.
>>
> 
> Thanks, fixing this.
> 
>>> +	global:
>>> +
>>> +	rte_pci_detach;
>>> +	rte_pci_dump;
>>> +	rte_pci_ioport_map;
>>> +	rte_pci_ioport_read;
>>> +	rte_pci_ioport_unmap;
>>> +	rte_pci_ioport_write;
>>> +	rte_pci_map_device;
>>> +	rte_pci_probe;
>>> +	rte_pci_probe_one;
>>> +	rte_pci_read_config;
>>> +	rte_pci_register;
>>> +	rte_pci_scan;
>>> +	rte_pci_unmap_device;
>>> +	rte_pci_unregister;
>>> +	rte_pci_write_config;
>>> +
>>> +	local: *;
>>> +};
>>
>> This is huuuge patch :( and I am not yet through it (most of it is movement
>> so I doubt anything major would be problem here).
>> Just the above comment in case you are spinning a new series.
>>
>>
> 
> Thanks for reading the patch.
> 
> Yes, most of it is moving the code as-is to a new location.
> I tried to reduce it, but at some point it does not really make sense
> anymore.

Agree. It is difficult to manage such large movement with a compile-able 
patch series. I think compilation success takes priority over size in 
such cases so as not to break bisect.

Here, I found that "eal: remove references to PCI" onwards, the 
compilation was breaking. You have already mentioned about this in the 
cover letter, it seems.

> 
> I think the important thing to look for here is the build system,
> dependency graph and the division of the PCI API between the lib and the
> bus driver.

Agree. I am trying to look through this.

> 
> I divided it along the lines of the rte_pci_device being defined or not.
> Anything using an rte_pci_device going to the bus and everything
> else going to the lib.

Yes, I agree with this in principle.
rte_xxx_device and rte_xxx_driver originate from the xxx_bus. Bus should 
be responsible for defining (scan) xxx_devices and attaching (probe) to 
xxx_driver. Which in turn means that all APIs dealing with xxx_device 
and xxx_driver should be pivoted in the Bus layer.

Though, I think here the complexity is also of crypto devices. You have 
already reached out to Declan through cover letter - probably his (and 
other crypto experts) opinion would matter here.

My opinion would be to have

> 
> I'm mostly worried about this divide. Having the rte_pci_device defined
> seems mostly of the responsibility of the bus driver, in my opinion. I'd
> like to hear others'.
> 

+1 from side for this principle for divide.

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
                     ` (13 preceding siblings ...)
  2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 14/14] doc: add notes on EAL PCI API update Gaetan Rivet
@ 2017-09-25 15:23   ` Gaetan Rivet
  2017-09-25 15:23     ` [dpdk-dev] [PATCH v3 01/13] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
                       ` (13 more replies)
  2017-10-11 14:19   ` [dpdk-dev] [PATCH v2 00/14] " Doherty, Declan
  15 siblings, 14 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-25 15:23 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Hi all,

Here is a new version of the PCI bus move out of the EAL.

The EAL PCI implementation is divided in two parts:

  - librte_pci: library offering helpers to handle PCI objects
  - librte_bus_pci: bus driver for PCI devices

This allows other libraries / tools to use PCI elements (location, mappings,
parsing operations, etc) without forcing a dependency on a bus driver.

The latter should not have to export helpers that others might need. It
is focused on defining the rte_pci_device, rte_pci_driver objects and
their handling.

The cryptodev library has hard dependencies on rte_pci_devices (used by
generic probe function). Other similar libs (ether and eventdev) avoided
the issue by inlining such functions and expecting users to include the
relevant headers once the PCI bus has already been built.

@Declan:
I proposed a solution that would avoid inlining those functions,
which does not feel right. Let me know what you think of it or if you
think of a better solution. I think it would be best to have cryptodev
completely independent from PCI / vdev as far as the lib in concerned
(the vdev bus will move as well).

v2:

  + Made rte_eal_using_phys_addrs common to both linux and bsd interfaces.
  + Added documentation of EAL API changes in release note.
  + Fixed a few rebase-related mistakes.
  + Fixed parallel build race condition reported by Luca Boccassi.
  + Grouped together commits breaking compilation:

    -> pci: introduce PCI lib and bus
    -> lib: include rte_bus_pci
    -> drivers: include rte_bus_pci
    -> test: include rte_bus_pci
    -> app/testpmd: include rte_bus_pci
    -> cryptodev: move PCI specific helpers to drivers/crypto

  Until all of them have been applied, compilation is broken.
  I am currently wondering whether merging some of them might
  be sensible.

  + Not included in this series:

    Several filesystem-related functions are currently
    private to the EAL and directly linked. This is not good,
    but the solution seems to be to have a new lib offering an FS abstraction.
    This seems an overreach for this patchset and should probably come in a
    second step.

v3:

  + Fixed .map versioning
  + merged one commit breaking the build into the main commit moving
    code around.

    Other such commits are still present, as they only break specific subsystems
    (lib, drivers, apps, cryptodev). Merging them all within the one main commit
    does not seem right.

    As such, build is still broken from

       * pci: introduce PCI lib and bus

    until

       * cryptodev: move PCI specific helpers to drivers/crypto

Gaetan Rivet (13):
  eal: expose rte_eal_using_phys_addrs
  ethdev: remove useless PCI dependency
  bus: properly include rte_debug
  pci: introduce PCI lib and bus
  lib: include rte_bus_pci
  drivers: include rte_bus_pci
  test: include rte_bus_pci
  app/testpmd: include rte_bus_pci
  cryptodev: move PCI specific helpers to drivers/crypto
  pci: avoid inlining functions
  pci: avoid over-complicated macro
  pci: deprecate misnamed functions
  doc: add notes on EAL PCI API update

 app/test-pmd/testpmd.h                           |   1 +
 config/common_base                               |  10 +
 doc/guides/rel_notes/deprecation.rst             |  10 +
 doc/guides/rel_notes/release_17_11.rst           |  28 +
 drivers/Makefile                                 |   2 +-
 drivers/bus/Makefile                             |   2 +
 drivers/bus/pci/Makefile                         |  59 ++
 drivers/bus/pci/bsd/Makefile                     |  32 +
 drivers/bus/pci/bsd/rte_pci.c                    | 671 +++++++++++++++++++++
 drivers/bus/pci/include/rte_bus_pci.h            | 387 ++++++++++++
 drivers/bus/pci/linux/Makefile                   |  37 ++
 drivers/bus/pci/linux/rte_pci.c                  | 723 +++++++++++++++++++++++
 drivers/bus/pci/linux/rte_pci_init.h             |  97 +++
 drivers/bus/pci/linux/rte_pci_uio.c              | 568 ++++++++++++++++++
 drivers/bus/pci/linux/rte_pci_vfio.c             | 675 +++++++++++++++++++++
 drivers/bus/pci/linux/rte_vfio_mp_sync.c         | 425 +++++++++++++
 drivers/bus/pci/private.h                        | 174 ++++++
 drivers/bus/pci/rte_bus_pci_version.map          |  21 +
 drivers/bus/pci/rte_pci_common.c                 | 543 +++++++++++++++++
 drivers/bus/pci/rte_pci_common_uio.c             | 235 ++++++++
 drivers/crypto/Makefile                          |   4 +-
 drivers/crypto/pci/Makefile                      |  52 ++
 drivers/crypto/pci/rte_cryptodev_pci.c           | 128 ++++
 drivers/crypto/pci/rte_cryptodev_pci.h           |  94 +++
 drivers/crypto/pci/rte_cryptodev_pci_version.map |   7 +
 drivers/crypto/qat/qat_qp.c                      |   1 +
 drivers/event/octeontx/ssovf_probe.c             |   1 +
 drivers/net/ark/ark_ethdev.c                     |   1 +
 drivers/net/avp/avp_ethdev.c                     |   2 +
 drivers/net/bnxt/bnxt.h                          |   1 +
 drivers/net/bonding/rte_eth_bond_args.c          |   1 +
 drivers/net/cxgbe/base/adapter.h                 |   1 +
 drivers/net/cxgbe/cxgbe_ethdev.c                 |   1 +
 drivers/net/e1000/em_ethdev.c                    |   1 +
 drivers/net/e1000/igb_ethdev.c                   |   1 +
 drivers/net/e1000/igb_pf.c                       |   1 +
 drivers/net/ena/ena_ethdev.h                     |   1 +
 drivers/net/enic/base/vnic_dev.h                 |   4 +-
 drivers/net/enic/enic_ethdev.c                   |   1 +
 drivers/net/enic/enic_main.c                     |   1 +
 drivers/net/i40e/i40e_ethdev.c                   |   1 +
 drivers/net/i40e/i40e_ethdev_vf.c                |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c                 |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.h                 |   1 +
 drivers/net/mlx5/mlx5.c                          |   1 +
 drivers/net/mlx5/mlx5_ethdev.c                   |   1 +
 drivers/net/sfc/sfc.h                            |   1 +
 drivers/net/sfc/sfc_ethdev.c                     |   1 +
 drivers/net/thunderx/nicvf_ethdev.c              |   1 +
 drivers/net/virtio/virtio_ethdev.c               |   1 +
 drivers/net/virtio/virtio_pci.h                  |   1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c             |   1 +
 lib/Makefile                                     |   2 +
 lib/librte_cryptodev/Makefile                    |   1 -
 lib/librte_cryptodev/rte_cryptodev_pci.h         |  92 ---
 lib/librte_cryptodev/rte_cryptodev_pmd.c         |  94 ---
 lib/librte_cryptodev/rte_cryptodev_version.map   |   2 -
 lib/librte_eal/bsdapp/eal/Makefile               |   3 -
 lib/librte_eal/bsdapp/eal/eal.c                  |   1 -
 lib/librte_eal/bsdapp/eal/eal_memory.c           |   6 +
 lib/librte_eal/bsdapp/eal/eal_pci.c              | 670 ---------------------
 lib/librte_eal/bsdapp/eal/rte_eal_version.map    |  24 +-
 lib/librte_eal/common/Makefile                   |   2 +-
 lib/librte_eal/common/eal_common_bus.c           |   1 +
 lib/librte_eal/common/eal_common_pci.c           | 580 ------------------
 lib/librte_eal/common/eal_common_pci_uio.c       | 233 --------
 lib/librte_eal/common/eal_private.h              | 143 -----
 lib/librte_eal/common/include/rte_memory.h       |  11 +
 lib/librte_eal/common/include/rte_pci.h          | 598 -------------------
 lib/librte_eal/linuxapp/eal/Makefile             |  10 -
 lib/librte_eal/linuxapp/eal/eal.c                |   1 -
 lib/librte_eal/linuxapp/eal/eal_interrupts.c     |   1 -
 lib/librte_eal/linuxapp/eal/eal_memory.c         |   2 +-
 lib/librte_eal/linuxapp/eal/eal_pci.c            | 722 ----------------------
 lib/librte_eal/linuxapp/eal/eal_pci_init.h       |  97 ---
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c        | 567 ------------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c       | 674 ---------------------
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c   | 424 -------------
 lib/librte_eal/linuxapp/eal/rte_eal_version.map  |  24 +-
 lib/librte_ether/rte_ethdev.c                    |   1 -
 lib/librte_ether/rte_ethdev.h                    |   2 -
 lib/librte_ether/rte_ethdev_pci.h                |   1 +
 lib/librte_eventdev/rte_eventdev_pmd_pci.h       |   1 +
 lib/librte_pci/Makefile                          |  48 ++
 lib/librte_pci/include/rte_pci.h                 | 285 +++++++++
 lib/librte_pci/rte_pci.c                         | 210 +++++++
 lib/librte_pci/rte_pci_version.map               |  16 +
 mk/rte.app.mk                                    |   3 +
 test/test/test_kni.c                             |   1 +
 test/test/virtual_pmd.c                          |   1 +
 90 files changed, 5617 insertions(+), 4953 deletions(-)
 create mode 100644 drivers/bus/pci/Makefile
 create mode 100644 drivers/bus/pci/bsd/Makefile
 create mode 100644 drivers/bus/pci/bsd/rte_pci.c
 create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
 create mode 100644 drivers/bus/pci/linux/Makefile
 create mode 100644 drivers/bus/pci/linux/rte_pci.c
 create mode 100644 drivers/bus/pci/linux/rte_pci_init.h
 create mode 100644 drivers/bus/pci/linux/rte_pci_uio.c
 create mode 100644 drivers/bus/pci/linux/rte_pci_vfio.c
 create mode 100644 drivers/bus/pci/linux/rte_vfio_mp_sync.c
 create mode 100644 drivers/bus/pci/private.h
 create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
 create mode 100644 drivers/bus/pci/rte_pci_common.c
 create mode 100644 drivers/bus/pci/rte_pci_common_uio.c
 create mode 100644 drivers/crypto/pci/Makefile
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.c
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.h
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci_version.map
 delete mode 100644 lib/librte_cryptodev/rte_cryptodev_pci.h
 delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
 delete mode 100644 lib/librte_eal/common/include/rte_pci.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
 create mode 100644 lib/librte_pci/Makefile
 create mode 100644 lib/librte_pci/include/rte_pci.h
 create mode 100644 lib/librte_pci/rte_pci.c
 create mode 100644 lib/librte_pci/rte_pci_version.map

-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v3 01/13] eal: expose rte_eal_using_phys_addrs
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
@ 2017-09-25 15:23     ` Gaetan Rivet
  2017-09-25 15:23     ` [dpdk-dev] [PATCH v3 02/13] ethdev: remove useless PCI dependency Gaetan Rivet
                       ` (12 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-25 15:23 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

This function was previously private to the EAL layer.
Other subsystems requires it, such as the PCI bus.

In order not to force other components to include stdbool, which is
incompatible with several NIC drivers, the return type has
been changed from bool to int.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/bsdapp/eal/eal_memory.c          |  6 ++++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  9 ++++++++-
 lib/librte_eal/common/eal_private.h             | 11 -----------
 lib/librte_eal/common/include/rte_memory.h      | 11 +++++++++++
 lib/librte_eal/linuxapp/eal/eal_memory.c        |  2 +-
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  9 ++++++++-
 6 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal_memory.c b/lib/librte_eal/bsdapp/eal/eal_memory.c
index 3614da8..65c96b0 100644
--- a/lib/librte_eal/bsdapp/eal/eal_memory.c
+++ b/lib/librte_eal/bsdapp/eal/eal_memory.c
@@ -192,3 +192,9 @@ rte_eal_hugepage_attach(void)
 		close(fd_hugepage);
 	return -1;
 }
+
+int
+rte_eal_using_phys_addrs(void)
+{
+	return 0;
+}
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 47a09ea..2065c53 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -204,6 +204,13 @@ DPDK_17.08 {
 
 } DPDK_17.05;
 
+DPDK_17.11 {
+	global;
+
+	rte_eal_using_phys_addrs;
+
+} DPDK_17.08;
+
 EXPERIMENTAL {
 	global:
 
@@ -237,4 +244,4 @@ EXPERIMENTAL {
 	rte_service_set_stats_enable;
 	rte_service_start_with_defaults;
 
-} DPDK_17.08;
+} DPDK_17.11;
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 597d82e..10a7078 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -333,17 +333,6 @@ int rte_eal_hugepage_init(void);
 int rte_eal_hugepage_attach(void);
 
 /**
- * Returns true if the system is able to obtain
- * physical addresses. Return false if using DMA
- * addresses through an IOMMU.
- *
- * Drivers based on uio will not load unless physical
- * addresses are obtainable. It is only possible to get
- * physical addresses when running as a privileged user.
- */
-bool rte_eal_using_phys_addrs(void);
-
-/**
  * Find a bus capable of identifying a device.
  *
  * @param str
diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h
index 4aa5d1f..5568931 100644
--- a/lib/librte_eal/common/include/rte_memory.h
+++ b/lib/librte_eal/common/include/rte_memory.h
@@ -195,6 +195,17 @@ unsigned rte_memory_get_nchannel(void);
  */
 unsigned rte_memory_get_nrank(void);
 
+/**
+ * Drivers based on uio will not load unless physical
+ * addresses are obtainable. It is only possible to get
+ * physical addresses when running as a privileged user.
+ *
+ * @return
+ *   1 if the system is able to obtain physical addresses.
+ *   0 if using DMA addresses through an IOMMU.
+ */
+int rte_eal_using_phys_addrs(void);
+
 #ifdef RTE_LIBRTE_XEN_DOM0
 
 /**< Internal use only - should DOM0 memory mapping be used */
diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
index 5279128..af8719b 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -1542,7 +1542,7 @@ rte_eal_hugepage_attach(void)
 	return -1;
 }
 
-bool
+int
 rte_eal_using_phys_addrs(void)
 {
 	return phys_addrs_available;
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 8c08b8d..18bce25 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -209,6 +209,13 @@ DPDK_17.08 {
 
 } DPDK_17.05;
 
+DPDK_17.11 {
+	global;
+
+	rte_eal_using_phys_addrs;
+
+} DPDK_17.08;
+
 EXPERIMENTAL {
 	global:
 
@@ -242,4 +249,4 @@ EXPERIMENTAL {
 	rte_service_set_stats_enable;
 	rte_service_start_with_defaults;
 
-} DPDK_17.08;
+} DPDK_17.11;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v3 02/13] ethdev: remove useless PCI dependency
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
  2017-09-25 15:23     ` [dpdk-dev] [PATCH v3 01/13] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
@ 2017-09-25 15:23     ` Gaetan Rivet
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 03/13] bus: properly include rte_debug Gaetan Rivet
                       ` (11 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-25 15:23 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ether/rte_ethdev.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 1849a3b..5092b82 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -47,7 +47,6 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_interrupts.h>
-#include <rte_pci.h>
 #include <rte_memory.h>
 #include <rte_memcpy.h>
 #include <rte_memzone.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v3 03/13] bus: properly include rte_debug
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
  2017-09-25 15:23     ` [dpdk-dev] [PATCH v3 01/13] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
  2017-09-25 15:23     ` [dpdk-dev] [PATCH v3 02/13] ethdev: remove useless PCI dependency Gaetan Rivet
@ 2017-09-25 15:24     ` Gaetan Rivet
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 04/13] pci: introduce PCI lib and bus Gaetan Rivet
                       ` (10 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-25 15:24 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_bus.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
index 08bec2d..9d1be8a 100644
--- a/lib/librte_eal/common/eal_common_bus.c
+++ b/lib/librte_eal/common/eal_common_bus.c
@@ -35,6 +35,7 @@
 #include <sys/queue.h>
 
 #include <rte_bus.h>
+#include <rte_debug.h>
 
 #include "eal_private.h"
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v3 04/13] pci: introduce PCI lib and bus
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
                       ` (2 preceding siblings ...)
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 03/13] bus: properly include rte_debug Gaetan Rivet
@ 2017-09-25 15:24     ` Gaetan Rivet
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 05/13] lib: include rte_bus_pci Gaetan Rivet
                       ` (9 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-25 15:24 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

The PCI lib defines the types and methods allowing to use PCI elements.

The PCI bus implements a bus driver for PCI devices by constructing
rte_bus elements using the PCI lib.

Move the relevant code out of the EAL to its expected place.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 config/common_base                              |  10 +
 drivers/bus/Makefile                            |   2 +
 drivers/bus/pci/Makefile                        |  59 ++
 drivers/bus/pci/bsd/Makefile                    |  32 ++
 drivers/bus/pci/bsd/rte_pci.c                   | 670 ++++++++++++++++++++++
 drivers/bus/pci/include/rte_bus_pci.h           | 387 +++++++++++++
 drivers/bus/pci/linux/Makefile                  |  37 ++
 drivers/bus/pci/linux/rte_pci.c                 | 722 ++++++++++++++++++++++++
 drivers/bus/pci/linux/rte_pci_init.h            |  97 ++++
 drivers/bus/pci/linux/rte_pci_uio.c             | 567 +++++++++++++++++++
 drivers/bus/pci/linux/rte_pci_vfio.c            | 674 ++++++++++++++++++++++
 drivers/bus/pci/linux/rte_vfio_mp_sync.c        | 424 ++++++++++++++
 drivers/bus/pci/private.h                       | 173 ++++++
 drivers/bus/pci/rte_bus_pci_version.map         |  21 +
 drivers/bus/pci/rte_pci_common.c                | 542 ++++++++++++++++++
 drivers/bus/pci/rte_pci_common_uio.c            | 234 ++++++++
 lib/Makefile                                    |   2 +
 lib/librte_eal/bsdapp/eal/Makefile              |   3 -
 lib/librte_eal/bsdapp/eal/eal.c                 |   1 -
 lib/librte_eal/bsdapp/eal/eal_pci.c             | 670 ----------------------
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  15 -
 lib/librte_eal/common/Makefile                  |   2 +-
 lib/librte_eal/common/eal_common_pci.c          | 580 -------------------
 lib/librte_eal/common/eal_common_pci_uio.c      | 233 --------
 lib/librte_eal/common/eal_private.h             | 132 -----
 lib/librte_eal/common/include/rte_pci.h         | 598 --------------------
 lib/librte_eal/linuxapp/eal/Makefile            |  10 -
 lib/librte_eal/linuxapp/eal/eal.c               |   1 -
 lib/librte_eal/linuxapp/eal/eal_interrupts.c    |   1 -
 lib/librte_eal/linuxapp/eal/eal_pci.c           | 722 ------------------------
 lib/librte_eal/linuxapp/eal/eal_pci_init.h      |  97 ----
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c       | 567 -------------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c      | 674 ----------------------
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c  | 424 --------------
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  15 -
 lib/librte_ether/rte_ethdev.h                   |   2 -
 lib/librte_pci/Makefile                         |  48 ++
 lib/librte_pci/include/rte_pci.h                | 279 +++++++++
 lib/librte_pci/rte_pci.c                        |  92 +++
 lib/librte_pci/rte_pci_version.map              |   8 +
 mk/rte.app.mk                                   |   3 +
 41 files changed, 5084 insertions(+), 4746 deletions(-)
 create mode 100644 drivers/bus/pci/Makefile
 create mode 100644 drivers/bus/pci/bsd/Makefile
 create mode 100644 drivers/bus/pci/bsd/rte_pci.c
 create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
 create mode 100644 drivers/bus/pci/linux/Makefile
 create mode 100644 drivers/bus/pci/linux/rte_pci.c
 create mode 100644 drivers/bus/pci/linux/rte_pci_init.h
 create mode 100644 drivers/bus/pci/linux/rte_pci_uio.c
 create mode 100644 drivers/bus/pci/linux/rte_pci_vfio.c
 create mode 100644 drivers/bus/pci/linux/rte_vfio_mp_sync.c
 create mode 100644 drivers/bus/pci/private.h
 create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
 create mode 100644 drivers/bus/pci/rte_pci_common.c
 create mode 100644 drivers/bus/pci/rte_pci_common_uio.c
 delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
 delete mode 100644 lib/librte_eal/common/include/rte_pci.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
 create mode 100644 lib/librte_pci/Makefile
 create mode 100644 lib/librte_pci/include/rte_pci.h
 create mode 100644 lib/librte_pci/rte_pci.c
 create mode 100644 lib/librte_pci/rte_pci_version.map

diff --git a/config/common_base b/config/common_base
index 12f6be9..ec32d6a 100644
--- a/config/common_base
+++ b/config/common_base
@@ -122,6 +122,11 @@ CONFIG_RTE_EAL_PMD_PATH=""
 CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
 
 #
+# Compile the PCI library
+#
+CONFIG_RTE_LIBRTE_PCI=y
+
+#
 # Compile the argument parser library
 #
 CONFIG_RTE_LIBRTE_KVARGS=y
@@ -147,6 +152,11 @@ CONFIG_RTE_ETHDEV_PROFILE_ITT_WASTED_RX_ITERATIONS=n
 CONFIG_RTE_ETHDEV_TX_PREPARE_NOOP=n
 
 #
+# Compile PCI bus driver
+#
+CONFIG_RTE_LIBRTE_PCI_BUS=y
+
+#
 # Compile burst-oriented Amazon ENA PMD driver
 #
 CONFIG_RTE_LIBRTE_ENA_PMD=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 0224214..4b5bafe 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -34,5 +34,7 @@ core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_ether
 
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DEPDIRS-fslmc = $(core-libs)
+DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
+DEPDIRS-pci = $(core-libs)
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/pci/Makefile b/drivers/bus/pci/Makefile
new file mode 100644
index 0000000..7365925
--- /dev/null
+++ b/drivers/bus/pci/Makefile
@@ -0,0 +1,59 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+LIB = librte_bus_pci.a
+LIBABIVER := 1
+EXPORT_MAP := rte_bus_pci_version.map
+
+CFLAGS := -I$(SRCDIR)/include -I$(SRCDIR) $(CFLAGS)
+CFLAGS += -O3 $(WERROR_FLAGS)
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),)
+SYSTEM := linux
+endif
+ifneq ($(CONFIG_RTE_EXEC_ENV_BSDAPP),)
+SYSTEM := bsd
+endif
+
+CFLAGS += -I$(RTE_SDK)/drivers/bus/pci/$(SYSTEM)
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/$(SYSTEM)app/eal
+
+include $(RTE_SDK)/drivers/bus/pci/$(SYSTEM)/Makefile
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) := $(addprefix $(SYSTEM)/,$(SRCS))
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += rte_pci_common.c
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += rte_pci_common_uio.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI_BUS)-include += include/rte_bus_pci.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/pci/bsd/Makefile b/drivers/bus/pci/bsd/Makefile
new file mode 100644
index 0000000..77cf539
--- /dev/null
+++ b/drivers/bus/pci/bsd/Makefile
@@ -0,0 +1,32 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += rte_pci.c
diff --git a/drivers/bus/pci/bsd/rte_pci.c b/drivers/bus/pci/bsd/rte_pci.c
new file mode 100644
index 0000000..5bd0f4b
--- /dev/null
+++ b/drivers/bus/pci/bsd/rte_pci.c
@@ -0,0 +1,670 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/pciio.h>
+#include <dev/pci/pcireg.h>
+
+#if defined(RTE_ARCH_X86)
+#include <machine/cpufunc.h>
+#endif
+
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_common.h>
+#include <rte_launch.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+#include <rte_debug.h>
+#include <rte_devargs.h>
+
+#include "eal_filesystem.h"
+#include "private.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in
+ * sysfs. Moreover, when a registered driver matches a device, the
+ * kernel driver currently using it is unloaded and replaced by
+ * igb_uio module, which is a very minimal userland driver for Intel
+ * network card, only providing access to PCI BAR to applications, and
+ * enabling bus master.
+ */
+
+extern struct rte_pci_bus rte_pci_bus;
+
+/* Map pci device */
+int
+rte_pci_map_device(struct rte_pci_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources */
+	switch (dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		/* map resources for devices that use uio */
+		ret = pci_uio_map_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+/* Unmap pci device */
+void
+rte_pci_unmap_device(struct rte_pci_device *dev)
+{
+	/* try unmapping the NIC resources */
+	switch (dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		/* unmap resources for devices that use uio */
+		pci_uio_unmap_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+void
+pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res)
+{
+	rte_free(uio_res);
+
+	if (dev->intr_handle.fd) {
+		close(dev->intr_handle.fd);
+		dev->intr_handle.fd = -1;
+		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	}
+}
+
+int
+pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res)
+{
+	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+
+	snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
+			dev->addr.bus, dev->addr.devid, dev->addr.function);
+
+	if (access(devname, O_RDWR) < 0) {
+		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+		return 1;
+	}
+
+	/* save fd if in primary process */
+	dev->intr_handle.fd = open(devname, O_RDWR);
+	if (dev->intr_handle.fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			devname, strerror(errno));
+		goto error;
+	}
+	dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+
+	/* allocate the mapping details for secondary processes*/
+	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
+	if (*uio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto error;
+	}
+
+	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
+	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
+
+	return 0;
+
+error:
+	pci_uio_free_resource(dev, *uio_res);
+	return -1;
+}
+
+int
+pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx)
+{
+	int fd;
+	char *devname;
+	void *mapaddr;
+	uint64_t offset;
+	uint64_t pagesz;
+	struct pci_map *maps;
+
+	maps = uio_res->maps;
+	devname = uio_res->path;
+	pagesz = sysconf(_SC_PAGESIZE);
+
+	/* allocate memory to keep path */
+	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+	if (maps[map_idx].path == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+				strerror(errno));
+		return -1;
+	}
+
+	/*
+	 * open resource file, to mmap it
+	 */
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				devname, strerror(errno));
+		goto error;
+	}
+
+	/* if matching map is found, then use it */
+	offset = res_idx * pagesz;
+	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
+			(size_t)dev->mem_resource[res_idx].len, 0);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		goto error;
+
+	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+	maps[map_idx].size = dev->mem_resource[res_idx].len;
+	maps[map_idx].addr = mapaddr;
+	maps[map_idx].offset = offset;
+	strcpy(maps[map_idx].path, devname);
+	dev->mem_resource[res_idx].addr = mapaddr;
+
+	return 0;
+
+error:
+	rte_free(maps[map_idx].path);
+	return -1;
+}
+
+static int
+pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
+{
+	struct rte_pci_device *dev;
+	struct pci_bar_io bar;
+	unsigned i, max;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL) {
+		return -1;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr.domain = conf->pc_sel.pc_domain;
+	dev->addr.bus = conf->pc_sel.pc_bus;
+	dev->addr.devid = conf->pc_sel.pc_dev;
+	dev->addr.function = conf->pc_sel.pc_func;
+
+	/* get vendor id */
+	dev->id.vendor_id = conf->pc_vendor;
+
+	/* get device id */
+	dev->id.device_id = conf->pc_device;
+
+	/* get subsystem_vendor id */
+	dev->id.subsystem_vendor_id = conf->pc_subvendor;
+
+	/* get subsystem_device id */
+	dev->id.subsystem_device_id = conf->pc_subdevice;
+
+	/* get class id */
+	dev->id.class_id = (conf->pc_class << 16) |
+			   (conf->pc_subclass << 8) |
+			   (conf->pc_progif);
+
+	/* TODO: get max_vfs */
+	dev->max_vfs = 0;
+
+	/* FreeBSD has no NUMA support (yet) */
+	dev->device.numa_node = 0;
+
+	pci_name_set(dev);
+
+	/* FreeBSD has only one pass through driver */
+	dev->kdrv = RTE_KDRV_NIC_UIO;
+
+	/* parse resources */
+	switch (conf->pc_hdr & PCIM_HDRTYPE) {
+	case PCIM_HDRTYPE_NORMAL:
+		max = PCIR_MAX_BAR_0;
+		break;
+	case PCIM_HDRTYPE_BRIDGE:
+		max = PCIR_MAX_BAR_1;
+		break;
+	case PCIM_HDRTYPE_CARDBUS:
+		max = PCIR_MAX_BAR_2;
+		break;
+	default:
+		goto skipdev;
+	}
+
+	for (i = 0; i <= max; i++) {
+		bar.pbi_sel = conf->pc_sel;
+		bar.pbi_reg = PCIR_BAR(i);
+		if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
+			continue;
+
+		dev->mem_resource[i].len = bar.pbi_length;
+		if (PCI_BAR_IO(bar.pbi_base)) {
+			dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
+			continue;
+		}
+		dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
+	}
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
+		rte_pci_add_device(dev);
+	}
+	else {
+		struct rte_pci_device *dev2 = NULL;
+		int ret;
+
+		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
+			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+			else if (ret < 0) {
+				rte_pci_insert_device(dev2, dev);
+			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->max_vfs = dev->max_vfs;
+				pci_name_set(dev2);
+				memmove(dev2->mem_resource,
+					dev->mem_resource,
+					sizeof(dev->mem_resource));
+				free(dev);
+			}
+			return 0;
+		}
+		rte_pci_add_device(dev);
+	}
+
+	return 0;
+
+skipdev:
+	free(dev);
+	return 0;
+}
+
+/*
+ * Scan the content of the PCI bus, and add the devices in the devices
+ * list. Call pci_scan_one() for each pci entry found.
+ */
+int
+rte_pci_scan(void)
+{
+	int fd;
+	unsigned dev_count = 0;
+	struct pci_conf matches[16];
+	struct pci_conf_io conf_io = {
+			.pat_buf_len = 0,
+			.num_patterns = 0,
+			.patterns = NULL,
+			.match_buf_len = sizeof(matches),
+			.matches = &matches[0],
+	};
+
+	/* for debug purposes, PCI can be disabled */
+	if (internal_config.no_pci)
+		return 0;
+
+	fd = open("/dev/pci", O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	do {
+		unsigned i;
+		if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+			RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+					__func__, strerror(errno));
+			goto error;
+		}
+
+		for (i = 0; i < conf_io.num_matches; i++)
+			if (pci_scan_one(fd, &matches[i]) < 0)
+				goto error;
+
+		dev_count += conf_io.num_matches;
+	} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
+
+	close(fd);
+
+	RTE_LOG(DEBUG, EAL, "PCI scan found %u devices\n", dev_count);
+	return 0;
+
+error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+	int fd;
+	struct pci_conf matches[2];
+	struct pci_match_conf match = {
+		.pc_sel = {
+			.pc_domain = addr->domain,
+			.pc_bus = addr->bus,
+			.pc_dev = addr->devid,
+			.pc_func = addr->function,
+		},
+	};
+	struct pci_conf_io conf_io = {
+		.pat_buf_len = 0,
+		.num_patterns = 1,
+		.patterns = &match,
+		.match_buf_len = sizeof(matches),
+		.matches = &matches[0],
+	};
+
+	fd = open("/dev/pci", O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+				__func__, strerror(errno));
+		goto error;
+	}
+
+	if (conf_io.num_matches != 1)
+		goto error;
+
+	if (pci_scan_one(fd, &matches[0]) < 0)
+		goto error;
+
+	close(fd);
+
+	return 0;
+
+error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/* Read PCI config space. */
+int rte_pci_read_config(const struct rte_pci_device *dev,
+		void *buf, size_t len, off_t offset)
+{
+	int fd = -1;
+	int size;
+	struct pci_io pi = {
+		.pi_sel = {
+			.pc_domain = dev->addr.domain,
+			.pc_bus = dev->addr.bus,
+			.pc_dev = dev->addr.devid,
+			.pc_func = dev->addr.function,
+		},
+		.pi_reg = offset,
+	};
+
+	fd = open("/dev/pci", O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	while (len > 0) {
+		size = (len >= 4) ? 4 : ((len >= 2) ? 2 : 1);
+		pi.pi_width = size;
+
+		if (ioctl(fd, PCIOCREAD, &pi) < 0)
+			goto error;
+		memcpy(buf, &pi.pi_data, size);
+
+		buf = (char *)buf + size;
+		pi.pi_reg += size;
+		len -= size;
+	}
+	close(fd);
+
+	return 0;
+
+ error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/* Write PCI config space. */
+int rte_pci_write_config(const struct rte_pci_device *dev,
+		const void *buf, size_t len, off_t offset)
+{
+	int fd = -1;
+
+	struct pci_io pi = {
+		.pi_sel = {
+			.pc_domain = dev->addr.domain,
+			.pc_bus = dev->addr.bus,
+			.pc_dev = dev->addr.devid,
+			.pc_func = dev->addr.function,
+		},
+		.pi_reg = offset,
+		.pi_data = *(const uint32_t *)buf,
+		.pi_width = len,
+	};
+
+	if (len == 3 || len > sizeof(pi.pi_data)) {
+		RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__);
+		goto error;
+	}
+
+	memcpy(&pi.pi_data, buf, len);
+
+	fd = open("/dev/pci", O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	if (ioctl(fd, PCIOCWRITE, &pi) < 0)
+		goto error;
+
+	close(fd);
+	return 0;
+
+ error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+int
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p)
+{
+	int ret;
+
+	switch (dev->kdrv) {
+#if defined(RTE_ARCH_X86)
+	case RTE_KDRV_NIC_UIO:
+		if ((uintptr_t) dev->mem_resource[bar].addr <= UINT16_MAX) {
+			p->base = (uintptr_t)dev->mem_resource[bar].addr;
+			ret = 0;
+		} else
+			ret = -1;
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	if (!ret)
+		p->dev = dev;
+
+	return ret;
+}
+
+static void
+pci_uio_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+#if defined(RTE_ARCH_X86)
+	uint8_t *d;
+	int size;
+	unsigned short reg = p->base + offset;
+
+	for (d = data; len > 0; d += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+			*(uint32_t *)d = inl(reg);
+		} else if (len >= 2) {
+			size = 2;
+			*(uint16_t *)d = inw(reg);
+		} else {
+			size = 1;
+			*d = inb(reg);
+		}
+	}
+#else
+	RTE_SET_USED(p);
+	RTE_SET_USED(data);
+	RTE_SET_USED(len);
+	RTE_SET_USED(offset);
+#endif
+}
+
+void
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+pci_uio_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+#if defined(RTE_ARCH_X86)
+	const uint8_t *s;
+	int size;
+	unsigned short reg = p->base + offset;
+
+	for (s = data; len > 0; s += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+			outl(reg, *(const uint32_t *)s);
+		} else if (len >= 2) {
+			size = 2;
+			outw(reg, *(const uint16_t *)s);
+		} else {
+			size = 1;
+			outb(reg, *s);
+		}
+	}
+#else
+	RTE_SET_USED(p);
+	RTE_SET_USED(data);
+	RTE_SET_USED(len);
+	RTE_SET_USED(offset);
+#endif
+}
+
+void
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	default:
+		break;
+	}
+}
+
+int
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
+{
+	int ret;
+
+	switch (p->dev->kdrv) {
+#if defined(RTE_ARCH_X86)
+	case RTE_KDRV_NIC_UIO:
+		ret = 0;
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/bus/pci/include/rte_bus_pci.h b/drivers/bus/pci/include/rte_bus_pci.h
new file mode 100644
index 0000000..b05dbf9
--- /dev/null
+++ b/drivers/bus/pci/include/rte_bus_pci.h
@@ -0,0 +1,387 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_BUS_PCI_H_
+#define _RTE_BUS_PCI_H_
+
+/**
+ * @file
+ *
+ * RTE PCI Bus Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+
+/** Pathname of PCI devices directory. */
+const char *pci_get_sysfs_path(void);
+
+/* Forward declarations */
+struct rte_pci_device;
+struct rte_pci_driver;
+
+/** List of PCI devices */
+TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
+/** List of PCI drivers */
+TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
+
+/* PCI Bus iterators */
+#define FOREACH_DEVICE_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
+
+#define FOREACH_DRIVER_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
+
+struct rte_devargs;
+
+/**
+ * A structure describing a PCI device.
+ */
+struct rte_pci_device {
+	TAILQ_ENTRY(rte_pci_device) next;   /**< Next probed PCI device. */
+	struct rte_device device;           /**< Inherit core device */
+	struct rte_pci_addr addr;           /**< PCI location. */
+	struct rte_pci_id id;               /**< PCI ID. */
+	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
+					    /**< PCI Memory Resource */
+	struct rte_intr_handle intr_handle; /**< Interrupt handle */
+	struct rte_pci_driver *driver;      /**< Associated driver */
+	uint16_t max_vfs;                   /**< sriov enable if not zero */
+	enum rte_kernel_driver kdrv;        /**< Kernel driver passthrough */
+	char name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_pci_device.
+ */
+#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
+
+#define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
+
+/** Any PCI device identifier (vendor, device, ...) */
+#define PCI_ANY_ID (0xffff)
+#define RTE_CLASS_ANY_ID (0xffffff)
+
+#ifdef __cplusplus
+/** C++ macro used to help building up tables of device IDs */
+#define RTE_PCI_DEVICE(vend, dev) \
+	RTE_CLASS_ANY_ID,         \
+	(vend),                   \
+	(dev),                    \
+	PCI_ANY_ID,               \
+	PCI_ANY_ID
+#else
+/** Macro used to help building up tables of device IDs */
+#define RTE_PCI_DEVICE(vend, dev)          \
+	.class_id = RTE_CLASS_ANY_ID,      \
+	.vendor_id = (vend),               \
+	.device_id = (dev),                \
+	.subsystem_vendor_id = PCI_ANY_ID, \
+	.subsystem_device_id = PCI_ANY_ID
+#endif
+
+/**
+ * Initialisation function for the driver called during PCI probing.
+ */
+typedef int (pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
+
+/**
+ * Uninitialisation function for the driver called during hotplugging.
+ */
+typedef int (pci_remove_t)(struct rte_pci_device *);
+
+/**
+ * A structure describing a PCI driver.
+ */
+struct rte_pci_driver {
+	TAILQ_ENTRY(rte_pci_driver) next;  /**< Next in list. */
+	struct rte_driver driver;          /**< Inherit core driver. */
+	struct rte_pci_bus *bus;           /**< PCI bus reference. */
+	pci_probe_t *probe;                /**< Device Probe function. */
+	pci_remove_t *remove;              /**< Device Remove function. */
+	const struct rte_pci_id *id_table; /**< ID table, NULL terminated. */
+	uint32_t drv_flags;                /**< Flags contolling handling of device. */
+};
+
+/**
+ * Structure describing the PCI bus
+ */
+struct rte_pci_bus {
+	struct rte_bus bus;               /**< Inherit the generic class */
+	struct rte_pci_device_list device_list;  /**< List of PCI devices */
+	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
+};
+
+/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
+#define RTE_PCI_DRV_NEED_MAPPING 0x0001
+/** Device driver supports link state interrupt */
+#define RTE_PCI_DRV_INTR_LSC	0x0008
+/** Device driver supports device removal interrupt */
+#define RTE_PCI_DRV_INTR_RMV 0x0010
+/** Device driver needs to keep mapped resources if unsupported dev detected */
+#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
+
+/**
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ *
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_pci_scan(void);
+
+/**
+ * Probe the PCI bus
+ *
+ * @return
+ *   - 0 on success.
+ *   - !0 on error.
+ */
+int
+rte_pci_probe(void);
+
+/**
+ * Map the PCI device resources in user space virtual memory address
+ *
+ * Note that driver should not call this function when flag
+ * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for
+ * you when it's on.
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ *
+ * @return
+ *   0 on success, negative on error and positive if no driver
+ *   is found for the device.
+ */
+int rte_pci_map_device(struct rte_pci_device *dev);
+
+/**
+ * Unmap this device
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ */
+void rte_pci_unmap_device(struct rte_pci_device *dev);
+
+/**
+ * Probe the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the probe() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to probe.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_probe_one(const struct rte_pci_addr *addr);
+
+/**
+ * Close the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the remove() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_detach(const struct rte_pci_addr *addr);
+
+/**
+ * Dump the content of the PCI bus.
+ *
+ * @param f
+ *   A pointer to a file for output
+ */
+void rte_pci_dump(FILE *f);
+
+/**
+ * Register a PCI driver.
+ *
+ * @param driver
+ *   A pointer to a rte_pci_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_pci_register(struct rte_pci_driver *driver);
+
+/** Helper for PCI device registration from driver (eth, crypto) instance */
+#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
+RTE_INIT(pciinitfn_ ##nm); \
+static void pciinitfn_ ##nm(void) \
+{\
+	(pci_drv).driver.name = RTE_STR(nm);\
+	rte_pci_register(&pci_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a PCI driver.
+ *
+ * @param driver
+ *   A pointer to a rte_pci_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_pci_unregister(struct rte_pci_driver *driver);
+
+/**
+ * Read PCI config space.
+ *
+ * @param device
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ * @param buf
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into PCI config space
+ */
+int rte_pci_read_config(const struct rte_pci_device *device,
+		void *buf, size_t len, off_t offset);
+
+/**
+ * Write PCI config space.
+ *
+ * @param device
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ * @param buf
+ *   A data buffer containing the bytes should be written
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into PCI config space
+ */
+int rte_pci_write_config(const struct rte_pci_device *device,
+		const void *buf, size_t len, off_t offset);
+
+/**
+ * A structure used to access io resources for a pci device.
+ * rte_pci_ioport is arch, os, driver specific, and should not be used outside
+ * of pci ioport api.
+ */
+struct rte_pci_ioport {
+	struct rte_pci_device *dev;
+	uint64_t base;
+	uint64_t len; /* only filled for memory mapped ports */
+};
+
+/**
+ * Initialize a rte_pci_ioport object for a pci device io resource.
+ *
+ * This object is then used to gain access to those io resources (see below).
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use.
+ * @param bar
+ *   Index of the io pci resource we want to access.
+ * @param p
+ *   The rte_pci_ioport object to be initialized.
+ * @return
+ *  0 on success, negative on error.
+ */
+int rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p);
+
+/**
+ * Release any resources used in a rte_pci_ioport object.
+ *
+ * @param p
+ *   The rte_pci_ioport object to be uninitialized.
+ * @return
+ *  0 on success, negative on error.
+ */
+int rte_pci_ioport_unmap(struct rte_pci_ioport *p);
+
+/**
+ * Read from a io pci resource.
+ *
+ * @param p
+ *   The rte_pci_ioport object from which we want to read.
+ * @param data
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into the pci io resource.
+ */
+void rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset);
+
+/**
+ * Write to a io pci resource.
+ *
+ * @param p
+ *   The rte_pci_ioport object to which we want to write.
+ * @param data
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into the pci io resource.
+ */
+void rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_BUS_PCI_H_ */
diff --git a/drivers/bus/pci/linux/Makefile b/drivers/bus/pci/linux/Makefile
new file mode 100644
index 0000000..d2ea84c
--- /dev/null
+++ b/drivers/bus/pci/linux/Makefile
@@ -0,0 +1,37 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += rte_pci.c
+SRCS += rte_pci_uio.c
+SRCS += rte_pci_vfio.c
+SRCS += rte_vfio_mp_sync.c
+
+CFLAGS += -D_GNU_SOURCE
diff --git a/drivers/bus/pci/linux/rte_pci.c b/drivers/bus/pci/linux/rte_pci.c
new file mode 100644
index 0000000..c2ac82b
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_pci.c
@@ -0,0 +1,722 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <dirent.h>
+
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+#include <rte_devargs.h>
+#include <rte_memcpy.h>
+
+#include "eal_filesystem.h"
+#include "private.h"
+#include "rte_pci_init.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in sysfs.
+ * When a registered device matches a driver, it is then initialized with
+ * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
+ */
+
+extern struct rte_pci_bus rte_pci_bus;
+
+static int
+pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
+{
+	int count;
+	char path[PATH_MAX];
+	char *name;
+
+	if (!filename || !dri_name)
+		return -1;
+
+	count = readlink(filename, path, PATH_MAX);
+	if (count >= PATH_MAX)
+		return -1;
+
+	/* For device does not have a driver */
+	if (count < 0)
+		return 1;
+
+	path[count] = '\0';
+
+	name = strrchr(path, '/');
+	if (name) {
+		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
+		return 0;
+	}
+
+	return -1;
+}
+
+/* Map pci device */
+int
+rte_pci_map_device(struct rte_pci_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_map_resource(dev);
+#endif
+		break;
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+		if (rte_eal_using_phys_addrs()) {
+			/* map resources for devices that use uio */
+			ret = pci_uio_map_resource(dev);
+		}
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+/* Unmap pci device */
+void
+rte_pci_unmap_device(struct rte_pci_device *dev)
+{
+	/* try unmapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+		if (pci_vfio_is_enabled())
+			pci_vfio_unmap_resource(dev);
+#endif
+		break;
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+		/* unmap resources for devices that use uio */
+		pci_uio_unmap_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+void *
+pci_find_max_end_va(void)
+{
+	const struct rte_memseg *seg = rte_eal_get_physmem_layout();
+	const struct rte_memseg *last = seg;
+	unsigned i = 0;
+
+	for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
+		if (seg->addr == NULL)
+			break;
+
+		if (seg->addr > last->addr)
+			last = seg;
+
+	}
+	return RTE_PTR_ADD(last->addr, last->len);
+}
+
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int
+pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+	uint64_t *end_addr, uint64_t *flags)
+{
+	union pci_resource_info {
+		struct {
+			char *phys_addr;
+			char *end_addr;
+			char *flags;
+		};
+		char *ptrs[PCI_RESOURCE_FMT_NVAL];
+	} res_info;
+
+	if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
+		RTE_LOG(ERR, EAL,
+			"%s(): bad resource format\n", __func__);
+		return -1;
+	}
+	errno = 0;
+	*phys_addr = strtoull(res_info.phys_addr, NULL, 16);
+	*end_addr = strtoull(res_info.end_addr, NULL, 16);
+	*flags = strtoull(res_info.flags, NULL, 16);
+	if (errno != 0) {
+		RTE_LOG(ERR, EAL,
+			"%s(): bad resource format\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
+
+/* parse the "resource" sysfs file */
+static int
+pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
+{
+	FILE *f;
+	char buf[BUFSIZ];
+	int i;
+	uint64_t phys_addr, end_addr, flags;
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
+		return -1;
+	}
+
+	for (i = 0; i<PCI_MAX_RESOURCE; i++) {
+
+		if (fgets(buf, sizeof(buf), f) == NULL) {
+			RTE_LOG(ERR, EAL,
+				"%s(): cannot read resource\n", __func__);
+			goto error;
+		}
+		if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+				&end_addr, &flags) < 0)
+			goto error;
+
+		if (flags & IORESOURCE_MEM) {
+			dev->mem_resource[i].phys_addr = phys_addr;
+			dev->mem_resource[i].len = end_addr - phys_addr + 1;
+			/* not mapped for now */
+			dev->mem_resource[i].addr = NULL;
+		}
+	}
+	fclose(f);
+	return 0;
+
+error:
+	fclose(f);
+	return -1;
+}
+
+/* Scan one pci sysfs entry, and fill the devices list from it. */
+static int
+pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
+{
+	char filename[PATH_MAX];
+	unsigned long tmp;
+	struct rte_pci_device *dev;
+	char driver[PATH_MAX];
+	int ret;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL)
+		return -1;
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr = *addr;
+
+	/* get vendor id */
+	snprintf(filename, sizeof(filename), "%s/vendor", dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.vendor_id = (uint16_t)tmp;
+
+	/* get device id */
+	snprintf(filename, sizeof(filename), "%s/device", dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.device_id = (uint16_t)tmp;
+
+	/* get subsystem_vendor id */
+	snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.subsystem_vendor_id = (uint16_t)tmp;
+
+	/* get subsystem_device id */
+	snprintf(filename, sizeof(filename), "%s/subsystem_device",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.subsystem_device_id = (uint16_t)tmp;
+
+	/* get class_id */
+	snprintf(filename, sizeof(filename), "%s/class",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	/* the least 24 bits are valid: class, subclass, program interface */
+	dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
+
+	/* get max_vfs */
+	dev->max_vfs = 0;
+	snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
+	if (!access(filename, F_OK) &&
+	    eal_parse_sysfs_value(filename, &tmp) == 0)
+		dev->max_vfs = (uint16_t)tmp;
+	else {
+		/* for non igb_uio driver, need kernel version >= 3.8 */
+		snprintf(filename, sizeof(filename),
+			 "%s/sriov_numvfs", dirname);
+		if (!access(filename, F_OK) &&
+		    eal_parse_sysfs_value(filename, &tmp) == 0)
+			dev->max_vfs = (uint16_t)tmp;
+	}
+
+	/* get numa node, default to 0 if not present */
+	snprintf(filename, sizeof(filename), "%s/numa_node",
+		 dirname);
+
+	if (access(filename, F_OK) != -1) {
+		if (eal_parse_sysfs_value(filename, &tmp) == 0)
+			dev->device.numa_node = tmp;
+		else
+			dev->device.numa_node = -1;
+	} else {
+		dev->device.numa_node = 0;
+	}
+
+	pci_name_set(dev);
+
+	/* parse resources */
+	snprintf(filename, sizeof(filename), "%s/resource", dirname);
+	if (pci_parse_sysfs_resource(filename, dev) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
+		free(dev);
+		return -1;
+	}
+
+	/* parse driver */
+	snprintf(filename, sizeof(filename), "%s/driver", dirname);
+	ret = pci_get_kernel_driver_by_path(filename, driver);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
+		free(dev);
+		return -1;
+	}
+
+	if (!ret) {
+		if (!strcmp(driver, "vfio-pci"))
+			dev->kdrv = RTE_KDRV_VFIO;
+		else if (!strcmp(driver, "igb_uio"))
+			dev->kdrv = RTE_KDRV_IGB_UIO;
+		else if (!strcmp(driver, "uio_pci_generic"))
+			dev->kdrv = RTE_KDRV_UIO_GENERIC;
+		else
+			dev->kdrv = RTE_KDRV_UNKNOWN;
+	} else
+		dev->kdrv = RTE_KDRV_NONE;
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
+		rte_pci_add_device(dev);
+	} else {
+		struct rte_pci_device *dev2;
+		int ret;
+
+		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
+			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+
+			if (ret < 0) {
+				rte_pci_insert_device(dev2, dev);
+			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->max_vfs = dev->max_vfs;
+				pci_name_set(dev2);
+				memmove(dev2->mem_resource, dev->mem_resource,
+					sizeof(dev->mem_resource));
+				free(dev);
+			}
+			return 0;
+		}
+
+		rte_pci_add_device(dev);
+	}
+
+	return 0;
+}
+
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+	char filename[PATH_MAX];
+
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
+		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
+		 addr->function);
+
+	return pci_scan_one(filename, addr);
+}
+
+/*
+ * split up a pci address into its constituent parts.
+ */
+static int
+parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
+{
+	/* first split on ':' */
+	union splitaddr {
+		struct {
+			char *domain;
+			char *bus;
+			char *devid;
+			char *function;
+		};
+		char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
+	} splitaddr;
+
+	char *buf_copy = strndup(buf, bufsize);
+	if (buf_copy == NULL)
+		return -1;
+
+	if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
+			!= PCI_FMT_NVAL - 1)
+		goto error;
+	/* final split is on '.' between devid and function */
+	splitaddr.function = strchr(splitaddr.devid,'.');
+	if (splitaddr.function == NULL)
+		goto error;
+	*splitaddr.function++ = '\0';
+
+	/* now convert to int values */
+	errno = 0;
+	addr->domain = strtoul(splitaddr.domain, NULL, 16);
+	addr->bus = strtoul(splitaddr.bus, NULL, 16);
+	addr->devid = strtoul(splitaddr.devid, NULL, 16);
+	addr->function = strtoul(splitaddr.function, NULL, 10);
+	if (errno != 0)
+		goto error;
+
+	free(buf_copy); /* free the copy made with strdup */
+	return 0;
+error:
+	free(buf_copy);
+	return -1;
+}
+
+/*
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ */
+int
+rte_pci_scan(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+	struct rte_pci_addr addr;
+
+	/* for debug purposes, PCI can be disabled */
+	if (internal_config.no_pci)
+		return 0;
+
+	dir = opendir(pci_get_sysfs_path());
+	if (dir == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
+			continue;
+
+		snprintf(dirname, sizeof(dirname), "%s/%s",
+				pci_get_sysfs_path(), e->d_name);
+
+		if (pci_scan_one(dirname, &addr) < 0)
+			goto error;
+	}
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
+
+/* Read PCI config space. */
+int rte_pci_read_config(const struct rte_pci_device *device,
+		void *buf, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &device->intr_handle;
+
+	switch (intr_handle->type) {
+	case RTE_INTR_HANDLE_UIO:
+	case RTE_INTR_HANDLE_UIO_INTX:
+		return pci_uio_read_config(intr_handle, buf, len, offset);
+
+#ifdef VFIO_PRESENT
+	case RTE_INTR_HANDLE_VFIO_MSIX:
+	case RTE_INTR_HANDLE_VFIO_MSI:
+	case RTE_INTR_HANDLE_VFIO_LEGACY:
+		return pci_vfio_read_config(intr_handle, buf, len, offset);
+#endif
+	default:
+		RTE_LOG(ERR, EAL,
+			"Unknown handle type of fd %d\n",
+					intr_handle->fd);
+		return -1;
+	}
+}
+
+/* Write PCI config space. */
+int rte_pci_write_config(const struct rte_pci_device *device,
+		const void *buf, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &device->intr_handle;
+
+	switch (intr_handle->type) {
+	case RTE_INTR_HANDLE_UIO:
+	case RTE_INTR_HANDLE_UIO_INTX:
+		return pci_uio_write_config(intr_handle, buf, len, offset);
+
+#ifdef VFIO_PRESENT
+	case RTE_INTR_HANDLE_VFIO_MSIX:
+	case RTE_INTR_HANDLE_VFIO_MSI:
+	case RTE_INTR_HANDLE_VFIO_LEGACY:
+		return pci_vfio_write_config(intr_handle, buf, len, offset);
+#endif
+	default:
+		RTE_LOG(ERR, EAL,
+			"Unknown handle type of fd %d\n",
+					intr_handle->fd);
+		return -1;
+	}
+}
+
+#if defined(RTE_ARCH_X86)
+static int
+pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
+		struct rte_pci_ioport *p)
+{
+	uint16_t start, end;
+	FILE *fp;
+	char *line = NULL;
+	char pci_id[16];
+	int found = 0;
+	size_t linesz;
+
+	snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
+		 dev->addr.domain, dev->addr.bus,
+		 dev->addr.devid, dev->addr.function);
+
+	fp = fopen("/proc/ioports", "r");
+	if (fp == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);
+		return -1;
+	}
+
+	while (getdelim(&line, &linesz, '\n', fp) > 0) {
+		char *ptr = line;
+		char *left;
+		int n;
+
+		n = strcspn(ptr, ":");
+		ptr[n] = 0;
+		left = &ptr[n + 1];
+
+		while (*left && isspace(*left))
+			left++;
+
+		if (!strncmp(left, pci_id, strlen(pci_id))) {
+			found = 1;
+
+			while (*ptr && isspace(*ptr))
+				ptr++;
+
+			sscanf(ptr, "%04hx-%04hx", &start, &end);
+
+			break;
+		}
+	}
+
+	free(line);
+	fclose(fp);
+
+	if (!found)
+		return -1;
+
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	p->base = start;
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
+
+	return 0;
+}
+#endif
+
+int
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p)
+{
+	int ret = -1;
+
+	switch (dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_ioport_map(dev, bar, p);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		ret = pci_uio_ioport_map(dev, bar, p);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+		ret = pci_ioport_map(dev, bar, p);
+#else
+		ret = pci_uio_ioport_map(dev, bar, p);
+#endif
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		ret = pci_ioport_map(dev, bar, p);
+#endif
+		break;
+	default:
+		break;
+	}
+
+	if (!ret)
+		p->dev = dev;
+
+	return ret;
+}
+
+void
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		pci_vfio_ioport_read(p, data, len, offset);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		pci_uio_ioport_read(p, data, len, offset);
+#endif
+		break;
+	default:
+		break;
+	}
+}
+
+void
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		pci_vfio_ioport_write(p, data, len, offset);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		pci_uio_ioport_write(p, data, len, offset);
+#endif
+		break;
+	default:
+		break;
+	}
+}
+
+int
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
+{
+	int ret = -1;
+
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_ioport_unmap(p);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		ret = pci_uio_ioport_unmap(p);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+		ret = 0;
+#else
+		ret = pci_uio_ioport_unmap(p);
+#endif
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		ret = 0;
+#endif
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/bus/pci/linux/rte_pci_init.h b/drivers/bus/pci/linux/rte_pci_init.h
new file mode 100644
index 0000000..ae2980d
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_pci_init.h
@@ -0,0 +1,97 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EAL_PCI_INIT_H_
+#define EAL_PCI_INIT_H_
+
+#include "eal_vfio.h"
+
+/** IO resource type: */
+#define IORESOURCE_IO         0x00000100
+#define IORESOURCE_MEM        0x00000200
+
+/*
+ * Helper function to map PCI resources right after hugepages in virtual memory
+ */
+extern void *pci_map_addr;
+void *pci_find_max_end_va(void);
+
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+	uint64_t *end_addr, uint64_t *flags);
+
+int pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res);
+void pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res);
+int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx);
+
+int pci_uio_read_config(const struct rte_intr_handle *intr_handle,
+			void *buf, size_t len, off_t offs);
+int pci_uio_write_config(const struct rte_intr_handle *intr_handle,
+			 const void *buf, size_t len, off_t offs);
+
+int pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		       struct rte_pci_ioport *p);
+void pci_uio_ioport_read(struct rte_pci_ioport *p,
+			 void *data, size_t len, off_t offset);
+void pci_uio_ioport_write(struct rte_pci_ioport *p,
+			  const void *data, size_t len, off_t offset);
+int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
+
+#ifdef VFIO_PRESENT
+
+/* access config space */
+int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
+			 void *buf, size_t len, off_t offs);
+int pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
+			  const void *buf, size_t len, off_t offs);
+
+int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
+		        struct rte_pci_ioport *p);
+void pci_vfio_ioport_read(struct rte_pci_ioport *p,
+			  void *data, size_t len, off_t offset);
+void pci_vfio_ioport_write(struct rte_pci_ioport *p,
+			   const void *data, size_t len, off_t offset);
+int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
+
+/* map/unmap VFIO resource prototype */
+int pci_vfio_map_resource(struct rte_pci_device *dev);
+int pci_vfio_unmap_resource(struct rte_pci_device *dev);
+
+#endif
+
+#endif /* EAL_PCI_INIT_H_ */
diff --git a/drivers/bus/pci/linux/rte_pci_uio.c b/drivers/bus/pci/linux/rte_pci_uio.c
new file mode 100644
index 0000000..eed6d0f
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_pci_uio.c
@@ -0,0 +1,567 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/sysmacros.h>
+#include <linux/pci_regs.h>
+
+#if defined(RTE_ARCH_X86)
+#include <sys/io.h>
+#endif
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_common.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "rte_pci_init.h"
+
+void *pci_map_addr = NULL;
+
+#define OFF_MAX              ((uint64_t)(off_t)-1)
+
+int
+pci_uio_read_config(const struct rte_intr_handle *intr_handle,
+		    void *buf, size_t len, off_t offset)
+{
+	return pread(intr_handle->uio_cfg_fd, buf, len, offset);
+}
+
+int
+pci_uio_write_config(const struct rte_intr_handle *intr_handle,
+		     const void *buf, size_t len, off_t offset)
+{
+	return pwrite(intr_handle->uio_cfg_fd, buf, len, offset);
+}
+
+static int
+pci_uio_set_bus_master(int dev_fd)
+{
+	uint16_t reg;
+	int ret;
+
+	ret = pread(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL,
+			"Cannot read command from PCI config space!\n");
+		return -1;
+	}
+
+	/* return if bus mastering is already on */
+	if (reg & PCI_COMMAND_MASTER)
+		return 0;
+
+	reg |= PCI_COMMAND_MASTER;
+
+	ret = pwrite(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL,
+			"Cannot write command to PCI config space!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
+{
+	FILE *f;
+	char filename[PATH_MAX];
+	int ret;
+	unsigned major, minor;
+	dev_t dev;
+
+	/* get the name of the sysfs file that contains the major and minor
+	 * of the uio device and read its content */
+	snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path);
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n",
+			__func__);
+		return -1;
+	}
+
+	ret = fscanf(f, "%u:%u", &major, &minor);
+	if (ret != 2) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n",
+			__func__);
+		fclose(f);
+		return -1;
+	}
+	fclose(f);
+
+	/* create the char device "mknod /dev/uioX c major minor" */
+	snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
+	dev = makedev(major, minor);
+	ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
+	if (ret != 0) {
+		RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	return ret;
+}
+
+/*
+ * Return the uioX char device used for a pci device. On success, return
+ * the UIO number and fill dstbuf string with the path of the device in
+ * sysfs. On error, return a negative value. In this case dstbuf is
+ * invalid.
+ */
+static int
+pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
+			   unsigned int buflen, int create)
+{
+	struct rte_pci_addr *loc = &dev->addr;
+	unsigned int uio_num;
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+
+	/* depending on kernel version, uio can be located in uio/uioX
+	 * or uio:uioX */
+
+	snprintf(dirname, sizeof(dirname),
+			"%s/" PCI_PRI_FMT "/uio", pci_get_sysfs_path(),
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	dir = opendir(dirname);
+	if (dir == NULL) {
+		/* retry with the parent directory */
+		snprintf(dirname, sizeof(dirname),
+				"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
+				loc->domain, loc->bus, loc->devid, loc->function);
+		dir = opendir(dirname);
+
+		if (dir == NULL) {
+			RTE_LOG(ERR, EAL, "Cannot opendir %s\n", dirname);
+			return -1;
+		}
+	}
+
+	/* take the first file starting with "uio" */
+	while ((e = readdir(dir)) != NULL) {
+		/* format could be uio%d ...*/
+		int shortprefix_len = sizeof("uio") - 1;
+		/* ... or uio:uio%d */
+		int longprefix_len = sizeof("uio:uio") - 1;
+		char *endptr;
+
+		if (strncmp(e->d_name, "uio", 3) != 0)
+			continue;
+
+		/* first try uio%d */
+		errno = 0;
+		uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
+		if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
+			snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
+			break;
+		}
+
+		/* then try uio:uio%d */
+		errno = 0;
+		uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
+		if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
+			snprintf(dstbuf, buflen, "%s/uio:uio%u", dirname, uio_num);
+			break;
+		}
+	}
+	closedir(dir);
+
+	/* No uio resource found */
+	if (e == NULL)
+		return -1;
+
+	/* create uio device if we've been asked to */
+	if (internal_config.create_uio_dev && create &&
+			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
+		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
+
+	return uio_num;
+}
+
+void
+pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res)
+{
+	rte_free(uio_res);
+
+	if (dev->intr_handle.uio_cfg_fd >= 0) {
+		close(dev->intr_handle.uio_cfg_fd);
+		dev->intr_handle.uio_cfg_fd = -1;
+	}
+	if (dev->intr_handle.fd >= 0) {
+		close(dev->intr_handle.fd);
+		dev->intr_handle.fd = -1;
+		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	}
+}
+
+int
+pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res)
+{
+	char dirname[PATH_MAX];
+	char cfgname[PATH_MAX];
+	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	int uio_num;
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+
+	/* find uio resource */
+	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 1);
+	if (uio_num < 0) {
+		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+		return 1;
+	}
+	snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
+
+	/* save fd if in primary process */
+	dev->intr_handle.fd = open(devname, O_RDWR);
+	if (dev->intr_handle.fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			devname, strerror(errno));
+		goto error;
+	}
+
+	snprintf(cfgname, sizeof(cfgname),
+			"/sys/class/uio/uio%u/device/config", uio_num);
+	dev->intr_handle.uio_cfg_fd = open(cfgname, O_RDWR);
+	if (dev->intr_handle.uio_cfg_fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			cfgname, strerror(errno));
+		goto error;
+	}
+
+	if (dev->kdrv == RTE_KDRV_IGB_UIO)
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+	else {
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
+
+		/* set bus master that is not done by uio_pci_generic */
+		if (pci_uio_set_bus_master(dev->intr_handle.uio_cfg_fd)) {
+			RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
+			goto error;
+		}
+	}
+
+	/* allocate the mapping details for secondary processes*/
+	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
+	if (*uio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto error;
+	}
+
+	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
+	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
+
+	return 0;
+
+error:
+	pci_uio_free_resource(dev, *uio_res);
+	return -1;
+}
+
+int
+pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx)
+{
+	int fd;
+	char devname[PATH_MAX];
+	void *mapaddr;
+	struct rte_pci_addr *loc;
+	struct pci_map *maps;
+
+	loc = &dev->addr;
+	maps = uio_res->maps;
+
+	/* update devname for mmap  */
+	snprintf(devname, sizeof(devname),
+			"%s/" PCI_PRI_FMT "/resource%d",
+			pci_get_sysfs_path(),
+			loc->domain, loc->bus, loc->devid,
+			loc->function, res_idx);
+
+	/* allocate memory to keep path */
+	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+	if (maps[map_idx].path == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+				strerror(errno));
+		return -1;
+	}
+
+	/*
+	 * open resource file, to mmap it
+	 */
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				devname, strerror(errno));
+		goto error;
+	}
+
+	/* try mapping somewhere close to the end of hugepages */
+	if (pci_map_addr == NULL)
+		pci_map_addr = pci_find_max_end_va();
+
+	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
+			(size_t)dev->mem_resource[res_idx].len, 0);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		goto error;
+
+	pci_map_addr = RTE_PTR_ADD(mapaddr,
+			(size_t)dev->mem_resource[res_idx].len);
+
+	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+	maps[map_idx].size = dev->mem_resource[res_idx].len;
+	maps[map_idx].addr = mapaddr;
+	maps[map_idx].offset = 0;
+	strcpy(maps[map_idx].path, devname);
+	dev->mem_resource[res_idx].addr = mapaddr;
+
+	return 0;
+
+error:
+	rte_free(maps[map_idx].path);
+	return -1;
+}
+
+#if defined(RTE_ARCH_X86)
+int
+pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		   struct rte_pci_ioport *p)
+{
+	char dirname[PATH_MAX];
+	char filename[PATH_MAX];
+	int uio_num;
+	unsigned long start;
+
+	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 0);
+	if (uio_num < 0)
+		return -1;
+
+	/* get portio start */
+	snprintf(filename, sizeof(filename),
+		 "%s/portio/port%d/start", dirname, bar);
+	if (eal_parse_sysfs_value(filename, &start) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
+			__func__);
+		return -1;
+	}
+	/* ensure we don't get anything funny here, read/write will cast to
+	 * uin16_t */
+	if (start > UINT16_MAX)
+		return -1;
+
+	/* FIXME only for primary process ? */
+	if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {
+
+		snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
+		dev->intr_handle.fd = open(filename, O_RDWR);
+		if (dev->intr_handle.fd < 0) {
+			RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				filename, strerror(errno));
+			return -1;
+		}
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+	}
+
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);
+
+	p->base = start;
+	p->len = 0;
+	return 0;
+}
+#else
+int
+pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		   struct rte_pci_ioport *p)
+{
+	FILE *f;
+	char buf[BUFSIZ];
+	char filename[PATH_MAX];
+	uint64_t phys_addr, end_addr, flags;
+	int fd, i;
+	void *addr;
+
+	/* open and read addresses of the corresponding resource in sysfs */
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
+		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function);
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",
+			strerror(errno));
+		return -1;
+	}
+	for (i = 0; i < bar + 1; i++) {
+		if (fgets(buf, sizeof(buf), f) == NULL) {
+			RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");
+			goto error;
+		}
+	}
+	if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+			&end_addr, &flags) < 0)
+		goto error;
+	if ((flags & IORESOURCE_IO) == 0) {
+		RTE_LOG(ERR, EAL, "BAR %d is not an IO resource\n", bar);
+		goto error;
+	}
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
+		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function, bar);
+
+	/* mmap the pci resource */
+	fd = open(filename, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
+			strerror(errno));
+		goto error;
+	}
+	addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
+		MAP_SHARED, fd, 0);
+	close(fd);
+	if (addr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s\n",
+			strerror(errno));
+		goto error;
+	}
+
+	/* strangely, the base address is mmap addr + phys_addr */
+	p->base = (uintptr_t)addr + phys_addr;
+	p->len = end_addr + 1;
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"\n", p->base);
+	fclose(f);
+
+	return 0;
+
+error:
+	fclose(f);
+	return -1;
+}
+#endif
+
+void
+pci_uio_ioport_read(struct rte_pci_ioport *p,
+		    void *data, size_t len, off_t offset)
+{
+	uint8_t *d;
+	int size;
+	uintptr_t reg = p->base + offset;
+
+	for (d = data; len > 0; d += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+#if defined(RTE_ARCH_X86)
+			*(uint32_t *)d = inl(reg);
+#else
+			*(uint32_t *)d = *(volatile uint32_t *)reg;
+#endif
+		} else if (len >= 2) {
+			size = 2;
+#if defined(RTE_ARCH_X86)
+			*(uint16_t *)d = inw(reg);
+#else
+			*(uint16_t *)d = *(volatile uint16_t *)reg;
+#endif
+		} else {
+			size = 1;
+#if defined(RTE_ARCH_X86)
+			*d = inb(reg);
+#else
+			*d = *(volatile uint8_t *)reg;
+#endif
+		}
+	}
+}
+
+void
+pci_uio_ioport_write(struct rte_pci_ioport *p,
+		     const void *data, size_t len, off_t offset)
+{
+	const uint8_t *s;
+	int size;
+	uintptr_t reg = p->base + offset;
+
+	for (s = data; len > 0; s += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+#if defined(RTE_ARCH_X86)
+			outl_p(*(const uint32_t *)s, reg);
+#else
+			*(volatile uint32_t *)reg = *(const uint32_t *)s;
+#endif
+		} else if (len >= 2) {
+			size = 2;
+#if defined(RTE_ARCH_X86)
+			outw_p(*(const uint16_t *)s, reg);
+#else
+			*(volatile uint16_t *)reg = *(const uint16_t *)s;
+#endif
+		} else {
+			size = 1;
+#if defined(RTE_ARCH_X86)
+			outb_p(*s, reg);
+#else
+			*(volatile uint8_t *)reg = *s;
+#endif
+		}
+	}
+}
+
+int
+pci_uio_ioport_unmap(struct rte_pci_ioport *p)
+{
+#if defined(RTE_ARCH_X86)
+	RTE_SET_USED(p);
+	/* FIXME close intr fd ? */
+	return 0;
+#else
+	return munmap((void *)(uintptr_t)p->base, p->len);
+#endif
+}
diff --git a/drivers/bus/pci/linux/rte_pci_vfio.c b/drivers/bus/pci/linux/rte_pci_vfio.c
new file mode 100644
index 0000000..81b67c9
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_pci_vfio.c
@@ -0,0 +1,674 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <fcntl.h>
+#include <linux/pci_regs.h>
+#include <sys/eventfd.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "rte_pci_init.h"
+#include "eal_vfio.h"
+#include "private.h"
+
+/**
+ * @file
+ * PCI probing under linux (VFIO version)
+ *
+ * This code tries to determine if the PCI device is bound to VFIO driver,
+ * and initialize it (map BARs, set up interrupts) if that's the case.
+ *
+ * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
+ */
+
+#ifdef VFIO_PRESENT
+
+#define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
+#define PAGE_MASK   (~(PAGE_SIZE - 1))
+
+static struct rte_tailq_elem rte_vfio_tailq = {
+	.name = "VFIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_vfio_tailq)
+
+int
+pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
+		    void *buf, size_t len, off_t offs)
+{
+	return pread64(intr_handle->vfio_dev_fd, buf, len,
+	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
+}
+
+int
+pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
+		    const void *buf, size_t len, off_t offs)
+{
+	return pwrite64(intr_handle->vfio_dev_fd, buf, len,
+	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
+}
+
+/* get PCI BAR number where MSI-X interrupts are */
+static int
+pci_vfio_get_msix_bar(int fd, int *msix_bar, uint32_t *msix_table_offset,
+		      uint32_t *msix_table_size)
+{
+	int ret;
+	uint32_t reg;
+	uint16_t flags;
+	uint8_t cap_id, cap_offset;
+
+	/* read PCI capability pointer from config space */
+	ret = pread64(fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_CAPABILITY_LIST);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
+				"config space!\n");
+		return -1;
+	}
+
+	/* we need first byte */
+	cap_offset = reg & 0xFF;
+
+	while (cap_offset) {
+
+		/* read PCI capability ID */
+		ret = pread64(fd, &reg, sizeof(reg),
+				VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+				cap_offset);
+		if (ret != sizeof(reg)) {
+			RTE_LOG(ERR, EAL, "Cannot read capability ID from PCI "
+					"config space!\n");
+			return -1;
+		}
+
+		/* we need first byte */
+		cap_id = reg & 0xFF;
+
+		/* if we haven't reached MSI-X, check next capability */
+		if (cap_id != PCI_CAP_ID_MSIX) {
+			ret = pread64(fd, &reg, sizeof(reg),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset);
+			if (ret != sizeof(reg)) {
+				RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
+						"config space!\n");
+				return -1;
+			}
+
+			/* we need second byte */
+			cap_offset = (reg & 0xFF00) >> 8;
+
+			continue;
+		}
+		/* else, read table offset */
+		else {
+			/* table offset resides in the next 4 bytes */
+			ret = pread64(fd, &reg, sizeof(reg),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset + 4);
+			if (ret != sizeof(reg)) {
+				RTE_LOG(ERR, EAL, "Cannot read table offset from PCI config "
+						"space!\n");
+				return -1;
+			}
+
+			ret = pread64(fd, &flags, sizeof(flags),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset + 2);
+			if (ret != sizeof(flags)) {
+				RTE_LOG(ERR, EAL, "Cannot read table flags from PCI config "
+						"space!\n");
+				return -1;
+			}
+
+			*msix_bar = reg & RTE_PCI_MSIX_TABLE_BIR;
+			*msix_table_offset = reg & RTE_PCI_MSIX_TABLE_OFFSET;
+			*msix_table_size = 16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE));
+
+			return 0;
+		}
+	}
+	return 0;
+}
+
+/* set PCI bus mastering */
+static int
+pci_vfio_set_bus_master(int dev_fd, bool op)
+{
+	uint16_t reg;
+	int ret;
+
+	ret = pread64(dev_fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n");
+		return -1;
+	}
+
+	if (op)
+		/* set the master bit */
+		reg |= PCI_COMMAND_MASTER;
+	else
+		reg &= ~(PCI_COMMAND_MASTER);
+
+	ret = pwrite64(dev_fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_COMMAND);
+
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* set up interrupt support (but not enable interrupts) */
+static int
+pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
+{
+	int i, ret, intr_idx;
+
+	/* default to invalid index */
+	intr_idx = VFIO_PCI_NUM_IRQS;
+
+	/* get interrupt type from internal config (MSI-X by default, can be
+	 * overridden from the command line
+	 */
+	switch (internal_config.vfio_intr_mode) {
+	case RTE_INTR_MODE_MSIX:
+		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
+		break;
+	case RTE_INTR_MODE_MSI:
+		intr_idx = VFIO_PCI_MSI_IRQ_INDEX;
+		break;
+	case RTE_INTR_MODE_LEGACY:
+		intr_idx = VFIO_PCI_INTX_IRQ_INDEX;
+		break;
+	/* don't do anything if we want to automatically determine interrupt type */
+	case RTE_INTR_MODE_NONE:
+		break;
+	default:
+		RTE_LOG(ERR, EAL, "  unknown default interrupt type!\n");
+		return -1;
+	}
+
+	/* start from MSI-X interrupt type */
+	for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) {
+		struct vfio_irq_info irq = { .argsz = sizeof(irq) };
+		int fd = -1;
+
+		/* skip interrupt modes we don't want */
+		if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE &&
+				i != intr_idx)
+			continue;
+
+		irq.index = i;
+
+		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  cannot get IRQ info, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+
+		/* if this vector cannot be used with eventfd, fail if we explicitly
+		 * specified interrupt type, otherwise continue */
+		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
+			if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE) {
+				RTE_LOG(ERR, EAL,
+						"  interrupt vector does not support eventfd!\n");
+				return -1;
+			} else
+				continue;
+		}
+
+		/* set up an eventfd for interrupts */
+		fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
+		if (fd < 0) {
+			RTE_LOG(ERR, EAL, "  cannot set up eventfd, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+
+		dev->intr_handle.fd = fd;
+		dev->intr_handle.vfio_dev_fd = vfio_dev_fd;
+
+		switch (i) {
+		case VFIO_PCI_MSIX_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSIX;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
+			break;
+		case VFIO_PCI_MSI_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSI;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
+			break;
+		case VFIO_PCI_INTX_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_LEGACY;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
+			break;
+		default:
+			RTE_LOG(ERR, EAL, "  unknown interrupt type!\n");
+			return -1;
+		}
+
+		return 0;
+	}
+
+	/* if we're here, we haven't found a suitable interrupt vector */
+	return -1;
+}
+
+/*
+ * map the PCI resources of a PCI device in virtual memory (VFIO version).
+ * primary and secondary processes follow almost exactly the same path
+ */
+int
+pci_vfio_map_resource(struct rte_pci_device *dev)
+{
+	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+	char pci_addr[PATH_MAX] = {0};
+	int vfio_dev_fd;
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret, msix_bar;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+
+	struct pci_map *maps;
+	uint32_t msix_table_offset = 0;
+	uint32_t msix_table_size = 0;
+	uint32_t ioport_bar;
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	if ((ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
+					&vfio_dev_fd, &device_info)))
+		return ret;
+
+	/* get MSI-X BAR, if any (we have to know where it is because we can't
+	 * easily mmap it when using VFIO) */
+	msix_bar = -1;
+	ret = pci_vfio_get_msix_bar(vfio_dev_fd, &msix_bar,
+				    &msix_table_offset, &msix_table_size);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "  %s cannot get MSI-X BAR number!\n", pci_addr);
+		close(vfio_dev_fd);
+		return -1;
+	}
+
+	/* if we're in a primary process, allocate vfio_res and get region info */
+	if (internal_config.process_type == RTE_PROC_PRIMARY) {
+		vfio_res = rte_zmalloc("VFIO_RES", sizeof(*vfio_res), 0);
+		if (vfio_res == NULL) {
+			RTE_LOG(ERR, EAL,
+				"%s(): cannot store uio mmap details\n", __func__);
+			close(vfio_dev_fd);
+			return -1;
+		}
+		memcpy(&vfio_res->pci_addr, &dev->addr, sizeof(vfio_res->pci_addr));
+
+		/* get number of registers (up to BAR5) */
+		vfio_res->nb_maps = RTE_MIN((int) device_info.num_regions,
+				VFIO_PCI_BAR5_REGION_INDEX + 1);
+	} else {
+		/* if we're in a secondary process, just find our tailq entry */
+		TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
+			if (rte_eal_compare_pci_addr(&vfio_res->pci_addr,
+						     &dev->addr))
+				continue;
+			break;
+		}
+		/* if we haven't found our tailq entry, something's wrong */
+		if (vfio_res == NULL) {
+			RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
+					pci_addr);
+			close(vfio_dev_fd);
+			return -1;
+		}
+	}
+
+	/* map BARs */
+	maps = vfio_res->maps;
+
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+		struct vfio_region_info reg = { .argsz = sizeof(reg) };
+		void *bar_addr;
+		struct memreg {
+			unsigned long offset, size;
+		} memreg[2] = {};
+
+		reg.index = i;
+
+		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg);
+
+		if (ret) {
+			RTE_LOG(ERR, EAL, "  %s cannot get device region info "
+					"error %i (%s)\n", pci_addr, errno, strerror(errno));
+			close(vfio_dev_fd);
+			if (internal_config.process_type == RTE_PROC_PRIMARY)
+				rte_free(vfio_res);
+			return -1;
+		}
+
+		/* chk for io port region */
+		ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar),
+			      VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX)
+			      + PCI_BASE_ADDRESS_0 + i*4);
+
+		if (ret != sizeof(ioport_bar)) {
+			RTE_LOG(ERR, EAL,
+				"Cannot read command (%x) from config space!\n",
+				PCI_BASE_ADDRESS_0 + i*4);
+			return -1;
+		}
+
+		if (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) {
+			RTE_LOG(INFO, EAL,
+				"Ignore mapping IO port bar(%d) addr: %x\n",
+				 i, ioport_bar);
+			continue;
+		}
+
+		/* skip non-mmapable BARs */
+		if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0)
+			continue;
+
+		if (i == msix_bar) {
+			/*
+			 * VFIO will not let us map the MSI-X table,
+			 * but we can map around it.
+			 */
+			uint32_t table_start = msix_table_offset;
+			uint32_t table_end = table_start + msix_table_size;
+			table_end = (table_end + ~PAGE_MASK) & PAGE_MASK;
+			table_start &= PAGE_MASK;
+
+			if (table_start == 0 && table_end >= reg.size) {
+				/* Cannot map this BAR */
+				RTE_LOG(DEBUG, EAL, "Skipping BAR %d\n", i);
+				continue;
+			} else {
+				memreg[0].offset = reg.offset;
+				memreg[0].size = table_start;
+				memreg[1].offset = reg.offset + table_end;
+				memreg[1].size = reg.size - table_end;
+
+				RTE_LOG(DEBUG, EAL,
+					"Trying to map BAR %d that contains the MSI-X "
+					"table. Trying offsets: "
+					"0x%04lx:0x%04lx, 0x%04lx:0x%04lx\n", i,
+					memreg[0].offset, memreg[0].size,
+					memreg[1].offset, memreg[1].size);
+			}
+		} else {
+			memreg[0].offset = reg.offset;
+			memreg[0].size = reg.size;
+		}
+
+		/* try to figure out an address */
+		if (internal_config.process_type == RTE_PROC_PRIMARY) {
+			/* try mapping somewhere close to the end of hugepages */
+			if (pci_map_addr == NULL)
+				pci_map_addr = pci_find_max_end_va();
+
+			bar_addr = pci_map_addr;
+			pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
+		} else {
+			bar_addr = maps[i].addr;
+		}
+
+		/* reserve the address using an inaccessible mapping */
+		bar_addr = mmap(bar_addr, reg.size, 0, MAP_PRIVATE |
+				MAP_ANONYMOUS, -1, 0);
+		if (bar_addr != MAP_FAILED) {
+			void *map_addr = NULL;
+			if (memreg[0].size) {
+				/* actual map of first part */
+				map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
+							    memreg[0].offset,
+							    memreg[0].size,
+							    MAP_FIXED);
+			}
+
+			/* if there's a second part, try to map it */
+			if (map_addr != MAP_FAILED
+			    && memreg[1].offset && memreg[1].size) {
+				void *second_addr = RTE_PTR_ADD(bar_addr,
+								memreg[1].offset -
+								(uintptr_t)reg.offset);
+				map_addr = pci_map_resource(second_addr,
+							    vfio_dev_fd, memreg[1].offset,
+							    memreg[1].size,
+							    MAP_FIXED);
+			}
+
+			if (map_addr == MAP_FAILED || !map_addr) {
+				munmap(bar_addr, reg.size);
+				bar_addr = MAP_FAILED;
+			}
+		}
+
+		if (bar_addr == MAP_FAILED ||
+				(internal_config.process_type == RTE_PROC_SECONDARY &&
+						bar_addr != maps[i].addr)) {
+			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n", pci_addr, i,
+					strerror(errno));
+			close(vfio_dev_fd);
+			if (internal_config.process_type == RTE_PROC_PRIMARY)
+				rte_free(vfio_res);
+			return -1;
+		}
+
+		maps[i].addr = bar_addr;
+		maps[i].offset = reg.offset;
+		maps[i].size = reg.size;
+		maps[i].path = NULL; /* vfio doesn't have per-resource paths */
+		dev->mem_resource[i].addr = bar_addr;
+	}
+
+	/* if secondary process, do not set up interrupts */
+	if (internal_config.process_type == RTE_PROC_PRIMARY) {
+		if (pci_vfio_setup_interrupts(dev, vfio_dev_fd) != 0) {
+			RTE_LOG(ERR, EAL, "  %s error setting up interrupts!\n", pci_addr);
+			close(vfio_dev_fd);
+			rte_free(vfio_res);
+			return -1;
+		}
+
+		/* set bus mastering for the device */
+		if (pci_vfio_set_bus_master(vfio_dev_fd, true)) {
+			RTE_LOG(ERR, EAL, "  %s cannot set up bus mastering!\n", pci_addr);
+			close(vfio_dev_fd);
+			rte_free(vfio_res);
+			return -1;
+		}
+
+		/* Reset the device */
+		ioctl(vfio_dev_fd, VFIO_DEVICE_RESET);
+	}
+
+	if (internal_config.process_type == RTE_PROC_PRIMARY)
+		TAILQ_INSERT_TAIL(vfio_res_list, vfio_res, next);
+
+	return 0;
+}
+
+int
+pci_vfio_unmap_resource(struct rte_pci_device *dev)
+{
+	char pci_addr[PATH_MAX] = {0};
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list;
+
+	struct pci_map *maps;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+
+	if (close(dev->intr_handle.fd) < 0) {
+		RTE_LOG(INFO, EAL, "Error when closing eventfd file descriptor for %s\n",
+			pci_addr);
+		return -1;
+	}
+
+	if (pci_vfio_set_bus_master(dev->intr_handle.vfio_dev_fd, false)) {
+		RTE_LOG(ERR, EAL, "  %s cannot unset bus mastering for PCI device!\n",
+				pci_addr);
+		return -1;
+	}
+
+	ret = vfio_release_device(pci_get_sysfs_path(), pci_addr,
+				  dev->intr_handle.vfio_dev_fd);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot release device\n", __func__);
+		return ret;
+	}
+
+	vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+	/* Get vfio_res */
+	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
+		if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
+			continue;
+		break;
+	}
+	/* if we haven't found our tailq entry, something's wrong */
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
+				pci_addr);
+		return -1;
+	}
+
+	/* unmap BARs */
+	maps = vfio_res->maps;
+
+	RTE_LOG(INFO, EAL, "Releasing pci mapped resource for %s\n",
+		pci_addr);
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+
+		/*
+		 * We do not need to be aware of MSI-X table BAR mappings as
+		 * when mapping. Just using current maps array is enough
+		 */
+		if (maps[i].addr) {
+			RTE_LOG(INFO, EAL, "Calling pci_unmap_resource for %s at %p\n",
+				pci_addr, maps[i].addr);
+			pci_unmap_resource(maps[i].addr, maps[i].size);
+		}
+	}
+
+	TAILQ_REMOVE(vfio_res_list, vfio_res, next);
+
+	return 0;
+}
+
+int
+pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
+		    struct rte_pci_ioport *p)
+{
+	if (bar < VFIO_PCI_BAR0_REGION_INDEX ||
+	    bar > VFIO_PCI_BAR5_REGION_INDEX) {
+		RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar);
+		return -1;
+	}
+
+	p->dev = dev;
+	p->base = VFIO_GET_REGION_ADDR(bar);
+	return 0;
+}
+
+void
+pci_vfio_ioport_read(struct rte_pci_ioport *p,
+		     void *data, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
+
+	if (pread64(intr_handle->vfio_dev_fd, data,
+		    len, p->base + offset) <= 0)
+		RTE_LOG(ERR, EAL,
+			"Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n",
+			VFIO_GET_REGION_IDX(p->base), (int)offset);
+}
+
+void
+pci_vfio_ioport_write(struct rte_pci_ioport *p,
+		      const void *data, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
+
+	if (pwrite64(intr_handle->vfio_dev_fd, data,
+		     len, p->base + offset) <= 0)
+		RTE_LOG(ERR, EAL,
+			"Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n",
+			VFIO_GET_REGION_IDX(p->base), (int)offset);
+}
+
+int
+pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
+{
+	RTE_SET_USED(p);
+	return -1;
+}
+
+int
+pci_vfio_enable(void)
+{
+	return vfio_enable("vfio_pci");
+}
+
+int
+pci_vfio_is_enabled(void)
+{
+	return vfio_is_enabled("vfio_pci");
+}
+#endif
diff --git a/drivers/bus/pci/linux/rte_vfio_mp_sync.c b/drivers/bus/pci/linux/rte_vfio_mp_sync.c
new file mode 100644
index 0000000..2c1654d
--- /dev/null
+++ b/drivers/bus/pci/linux/rte_vfio_mp_sync.c
@@ -0,0 +1,424 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <pthread.h>
+
+/* sys/un.h with __USE_MISC uses strlen, which is unsafe */
+#ifdef __USE_MISC
+#define REMOVED_USE_MISC
+#undef __USE_MISC
+#endif
+#include <sys/un.h>
+/* make sure we redefine __USE_MISC only if it was previously undefined */
+#ifdef REMOVED_USE_MISC
+#define __USE_MISC
+#undef REMOVED_USE_MISC
+#endif
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "eal_thread.h"
+#include "rte_pci_init.h"
+
+/**
+ * @file
+ * VFIO socket for communication between primary and secondary processes.
+ *
+ * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
+ */
+
+#ifdef VFIO_PRESENT
+
+#define SOCKET_PATH_FMT "%s/.%s_mp_socket"
+#define CMSGLEN (CMSG_LEN(sizeof(int)))
+#define FD_TO_CMSGHDR(fd, chdr) \
+		do {\
+			(chdr).cmsg_len = CMSGLEN;\
+			(chdr).cmsg_level = SOL_SOCKET;\
+			(chdr).cmsg_type = SCM_RIGHTS;\
+			memcpy((chdr).__cmsg_data, &(fd), sizeof(fd));\
+		} while (0)
+#define CMSGHDR_TO_FD(chdr, fd) \
+			memcpy(&(fd), (chdr).__cmsg_data, sizeof(fd))
+
+static pthread_t socket_thread;
+static int mp_socket_fd;
+
+
+/* get socket path (/var/run if root, $HOME otherwise) */
+static void
+get_socket_path(char *buffer, int bufsz)
+{
+	const char *dir = "/var/run";
+	const char *home_dir = getenv("HOME");
+
+	if (getuid() != 0 && home_dir != NULL)
+		dir = home_dir;
+
+	/* use current prefix as file path */
+	snprintf(buffer, bufsz, SOCKET_PATH_FMT, dir,
+			internal_config.hugefile_prefix);
+}
+
+
+
+/*
+ * data flow for socket comm protocol:
+ * 1. client sends SOCKET_REQ_CONTAINER or SOCKET_REQ_GROUP
+ * 1a. in case of SOCKET_REQ_GROUP, client also then sends group number
+ * 2. server receives message
+ * 2a. in case of invalid group, SOCKET_ERR is sent back to client
+ * 2b. in case of unbound group, SOCKET_NO_FD is sent back to client
+ * 2c. in case of valid group, SOCKET_OK is sent and immediately followed by fd
+ *
+ * in case of any error, socket is closed.
+ */
+
+/* send a request, return -1 on error */
+int
+vfio_mp_sync_send_request(int socket, int req)
+{
+	struct msghdr hdr;
+	struct iovec iov;
+	int buf;
+	int ret;
+
+	memset(&hdr, 0, sizeof(hdr));
+
+	buf = req;
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+
+	ret = sendmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+	return 0;
+}
+
+/* receive a request and return it */
+int
+vfio_mp_sync_receive_request(int socket)
+{
+	int buf;
+	struct msghdr hdr;
+	struct iovec iov;
+	int ret, req;
+
+	memset(&hdr, 0, sizeof(hdr));
+
+	buf = SOCKET_ERR;
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+
+	ret = recvmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+
+	req = buf;
+
+	return req;
+}
+
+/* send OK in message, fd in control message */
+int
+vfio_mp_sync_send_fd(int socket, int fd)
+{
+	int buf;
+	struct msghdr hdr;
+	struct cmsghdr *chdr;
+	char chdr_buf[CMSGLEN];
+	struct iovec iov;
+	int ret;
+
+	chdr = (struct cmsghdr *) chdr_buf;
+	memset(chdr, 0, sizeof(chdr_buf));
+	memset(&hdr, 0, sizeof(hdr));
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+	hdr.msg_control = chdr;
+	hdr.msg_controllen = CMSGLEN;
+
+	buf = SOCKET_OK;
+	FD_TO_CMSGHDR(fd, *chdr);
+
+	ret = sendmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+	return 0;
+}
+
+/* receive OK in message, fd in control message */
+int
+vfio_mp_sync_receive_fd(int socket)
+{
+	int buf;
+	struct msghdr hdr;
+	struct cmsghdr *chdr;
+	char chdr_buf[CMSGLEN];
+	struct iovec iov;
+	int ret, req, fd;
+
+	buf = SOCKET_ERR;
+
+	chdr = (struct cmsghdr *) chdr_buf;
+	memset(chdr, 0, sizeof(chdr_buf));
+	memset(&hdr, 0, sizeof(hdr));
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+	hdr.msg_control = chdr;
+	hdr.msg_controllen = CMSGLEN;
+
+	ret = recvmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+
+	req = buf;
+
+	if (req != SOCKET_OK)
+		return -1;
+
+	CMSGHDR_TO_FD(*chdr, fd);
+
+	return fd;
+}
+
+/* connect socket_fd in secondary process to the primary process's socket */
+int
+vfio_mp_sync_connect_to_primary(void)
+{
+	struct sockaddr_un addr;
+	socklen_t sockaddr_len;
+	int socket_fd;
+
+	/* set up a socket */
+	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+	if (socket_fd < 0) {
+		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
+		return -1;
+	}
+
+	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
+	addr.sun_family = AF_UNIX;
+
+	sockaddr_len = sizeof(struct sockaddr_un);
+
+	if (connect(socket_fd, (struct sockaddr *) &addr, sockaddr_len) == 0)
+		return socket_fd;
+
+	/* if connect failed */
+	close(socket_fd);
+	return -1;
+}
+
+
+
+/*
+ * socket listening thread for primary process
+ */
+static __attribute__((noreturn)) void *
+vfio_mp_sync_thread(void __rte_unused * arg)
+{
+	int ret, fd, vfio_data;
+
+	/* wait for requests on the socket */
+	for (;;) {
+		int conn_sock;
+		struct sockaddr_un addr;
+		socklen_t sockaddr_len = sizeof(addr);
+
+		/* this is a blocking call */
+		conn_sock = accept(mp_socket_fd, (struct sockaddr *) &addr,
+				&sockaddr_len);
+
+		/* just restart on error */
+		if (conn_sock == -1)
+			continue;
+
+		/* set socket to linger after close */
+		struct linger l;
+		l.l_onoff = 1;
+		l.l_linger = 60;
+
+		if (setsockopt(conn_sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0)
+			RTE_LOG(WARNING, EAL, "Cannot set SO_LINGER option "
+					"on listen socket (%s)\n", strerror(errno));
+
+		ret = vfio_mp_sync_receive_request(conn_sock);
+
+		switch (ret) {
+		case SOCKET_REQ_CONTAINER:
+			fd = vfio_get_container_fd();
+			if (fd < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			else
+				vfio_mp_sync_send_fd(conn_sock, fd);
+			close(fd);
+			break;
+		case SOCKET_REQ_GROUP:
+			/* wait for group number */
+			vfio_data = vfio_mp_sync_receive_request(conn_sock);
+			if (vfio_data < 0) {
+				close(conn_sock);
+				continue;
+			}
+
+			fd = vfio_get_group_fd(vfio_data);
+
+			if (fd < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			/* if VFIO group exists but isn't bound to VFIO driver */
+			else if (fd == 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
+			/* if group exists and is bound to VFIO driver */
+			else {
+				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
+				vfio_mp_sync_send_fd(conn_sock, fd);
+			}
+			break;
+		case SOCKET_CLR_GROUP:
+			/* wait for group fd */
+			vfio_data = vfio_mp_sync_receive_request(conn_sock);
+			if (vfio_data < 0) {
+				close(conn_sock);
+				continue;
+			}
+
+			ret = clear_group(vfio_data);
+
+			if (ret < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
+			else
+				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
+			break;
+		default:
+			vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			break;
+		}
+		close(conn_sock);
+	}
+}
+
+static int
+vfio_mp_sync_socket_setup(void)
+{
+	int ret, socket_fd;
+	struct sockaddr_un addr;
+	socklen_t sockaddr_len;
+
+	/* set up a socket */
+	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+	if (socket_fd < 0) {
+		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
+		return -1;
+	}
+
+	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
+	addr.sun_family = AF_UNIX;
+
+	sockaddr_len = sizeof(struct sockaddr_un);
+
+	unlink(addr.sun_path);
+
+	ret = bind(socket_fd, (struct sockaddr *) &addr, sockaddr_len);
+	if (ret) {
+		RTE_LOG(ERR, EAL, "Failed to bind socket: %s!\n", strerror(errno));
+		close(socket_fd);
+		return -1;
+	}
+
+	ret = listen(socket_fd, 50);
+	if (ret) {
+		RTE_LOG(ERR, EAL, "Failed to listen: %s!\n", strerror(errno));
+		close(socket_fd);
+		return -1;
+	}
+
+	/* save the socket in local configuration */
+	mp_socket_fd = socket_fd;
+
+	return 0;
+}
+
+/*
+ * set up a local socket and tell it to listen for incoming connections
+ */
+int
+vfio_mp_sync_setup(void)
+{
+	int ret;
+	char thread_name[RTE_MAX_THREAD_NAME_LEN];
+
+	if (vfio_mp_sync_socket_setup() < 0) {
+		RTE_LOG(ERR, EAL, "Failed to set up local socket!\n");
+		return -1;
+	}
+
+	ret = pthread_create(&socket_thread, NULL,
+			vfio_mp_sync_thread, NULL);
+	if (ret) {
+		RTE_LOG(ERR, EAL,
+			"Failed to create thread for communication with secondary processes!\n");
+		close(mp_socket_fd);
+		return -1;
+	}
+
+	/* Set thread_name for aid in debugging. */
+	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "vfio-sync");
+	ret = rte_thread_setname(socket_thread, thread_name);
+	if (ret)
+		RTE_LOG(DEBUG, EAL,
+			"Failed to set thread name for secondary processes!\n");
+
+	return 0;
+}
+
+#endif
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
new file mode 100644
index 0000000..7ff1fc4
--- /dev/null
+++ b/drivers/bus/pci/private.h
@@ -0,0 +1,173 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PCI_PRIVATE_H_
+#define _PCI_PRIVATE_H_
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <rte_pci.h>
+
+struct rte_pci_driver;
+struct rte_pci_device;
+
+/**
+ * Find the name of a PCI device.
+ */
+void
+pci_name_set(struct rte_pci_device *dev);
+
+/**
+ * Add a PCI device to the PCI Bus (append to PCI Device list). This function
+ * also updates the bus references of the PCI Device (and the generic device
+ * object embedded within.
+ *
+ * @param pci_dev
+ *	PCI device to add
+ * @return void
+ */
+void rte_pci_add_device(struct rte_pci_device *pci_dev);
+
+/**
+ * Insert a PCI device in the PCI Bus at a particular location in the device
+ * list. It also updates the PCI Bus reference of the new devices to be
+ * inserted.
+ *
+ * @param exist_pci_dev
+ *	Existing PCI device in PCI Bus
+ * @param new_pci_dev
+ *	PCI device to be added before exist_pci_dev
+ * @return void
+ */
+void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+		struct rte_pci_device *new_pci_dev);
+
+/**
+ * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
+ * in the PCI device object as well as the generic device object.
+ *
+ * @param pci_device
+ *	PCI device to be removed from PCI Bus
+ * @return void
+ */
+void rte_pci_remove_device(struct rte_pci_device *pci_device);
+
+/**
+ * Update a pci device object by asking the kernel for the latest information.
+ *
+ * This function is private to EAL.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to look for
+ * @return
+ *   - 0 on success.
+ *   - negative on error.
+ */
+int pci_update_device(const struct rte_pci_addr *addr);
+
+/**
+ * Unbind kernel driver for this device
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_unbind_kernel_driver(struct rte_pci_device *dev);
+
+/**
+ * Map the PCI resource of a PCI device in virtual memory
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_map_resource(struct rte_pci_device *dev);
+
+/**
+ * Unmap the PCI resource of a PCI device
+ *
+ * This function is private to EAL.
+ */
+void pci_uio_unmap_resource(struct rte_pci_device *dev);
+
+/**
+ * Allocate uio resource for PCI device
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device to allocate uio resource
+ * @param uio_res
+ *   Pointer to uio resource.
+ *   If the function returns 0, the pointer will be filled.
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res);
+
+/**
+ * Free uio resource for PCI device
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device to free uio resource
+ * @param uio_res
+ *   Pointer to uio resource.
+ */
+void pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res);
+
+/**
+ * Map device memory to uio resource
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device that has memory information.
+ * @param res_idx
+ *   Memory resource index of the PCI device.
+ * @param uio_res
+ *  uio resource that will keep mapping information.
+ * @param map_idx
+ *   Mapping information index of the uio resource.
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx);
+
+#endif /* _PCI_PRIVATE_H_ */
diff --git a/drivers/bus/pci/rte_bus_pci_version.map b/drivers/bus/pci/rte_bus_pci_version.map
new file mode 100644
index 0000000..c1973f6
--- /dev/null
+++ b/drivers/bus/pci/rte_bus_pci_version.map
@@ -0,0 +1,21 @@
+DPDK_17.11 {
+	global:
+
+	rte_pci_detach;
+	rte_pci_dump;
+	rte_pci_ioport_map;
+	rte_pci_ioport_read;
+	rte_pci_ioport_unmap;
+	rte_pci_ioport_write;
+	rte_pci_map_device;
+	rte_pci_probe;
+	rte_pci_probe_one;
+	rte_pci_read_config;
+	rte_pci_register;
+	rte_pci_scan;
+	rte_pci_unmap_device;
+	rte_pci_unregister;
+	rte_pci_write_config;
+
+	local: *;
+};
diff --git a/drivers/bus/pci/rte_pci_common.c b/drivers/bus/pci/rte_pci_common.c
new file mode 100644
index 0000000..c37b85b
--- /dev/null
+++ b/drivers/bus/pci/rte_pci_common.c
@@ -0,0 +1,542 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+
+#include "private.h"
+
+extern struct rte_pci_bus rte_pci_bus;
+
+#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
+
+const char *pci_get_sysfs_path(void)
+{
+	const char *path = NULL;
+
+	path = getenv("SYSFS_PCI_DEVICES");
+	if (path == NULL)
+		return SYSFS_PCI_DEVICES;
+
+	return path;
+}
+
+static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
+{
+	struct rte_devargs *devargs;
+	struct rte_pci_addr addr;
+	struct rte_bus *pbus;
+
+	pbus = rte_bus_find_by_name("pci");
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->bus != pbus)
+			continue;
+		devargs->bus->parse(devargs->name, &addr);
+		if (!rte_eal_compare_pci_addr(&dev->addr, &addr))
+			return devargs;
+	}
+	return NULL;
+}
+
+void
+pci_name_set(struct rte_pci_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	/* Each device has its internal, canonical name set. */
+	rte_pci_device_name(&dev->addr,
+			dev->name, sizeof(dev->name));
+	devargs = pci_devargs_lookup(dev);
+	dev->device.devargs = devargs;
+	/* In blacklist mode, if the device is not blacklisted, no
+	 * rte_devargs exists for it.
+	 */
+	if (devargs != NULL)
+		/* If an rte_devargs exists, the generic rte_device uses the
+		 * given name as its namea
+		 */
+		dev->device.name = dev->device.devargs->name;
+	else
+		/* Otherwise, it uses the internal, canonical form. */
+		dev->device.name = dev->name;
+}
+
+/*
+ * Match the PCI Driver and Device using the ID Table
+ *
+ * @param pci_drv
+ *	PCI driver from which ID table would be extracted
+ * @param pci_dev
+ *	PCI device to match against the driver
+ * @return
+ *	1 for successful match
+ *	0 for unsuccessful match
+ */
+static int
+rte_pci_match(const struct rte_pci_driver *pci_drv,
+	      const struct rte_pci_device *pci_dev)
+{
+	const struct rte_pci_id *id_table;
+
+	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
+	     id_table++) {
+		/* check if device's identifiers match the driver's ones */
+		if (id_table->vendor_id != pci_dev->id.vendor_id &&
+				id_table->vendor_id != PCI_ANY_ID)
+			continue;
+		if (id_table->device_id != pci_dev->id.device_id &&
+				id_table->device_id != PCI_ANY_ID)
+			continue;
+		if (id_table->subsystem_vendor_id !=
+		    pci_dev->id.subsystem_vendor_id &&
+		    id_table->subsystem_vendor_id != PCI_ANY_ID)
+			continue;
+		if (id_table->subsystem_device_id !=
+		    pci_dev->id.subsystem_device_id &&
+		    id_table->subsystem_device_id != PCI_ANY_ID)
+			continue;
+		if (id_table->class_id != pci_dev->id.class_id &&
+				id_table->class_id != RTE_CLASS_ANY_ID)
+			continue;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * If vendor/device ID match, call the probe() function of the
+ * driver.
+ */
+static int
+rte_pci_probe_one_driver(struct rte_pci_driver *dr,
+			 struct rte_pci_device *dev)
+{
+	int ret;
+	struct rte_pci_addr *loc;
+
+	if ((dr == NULL) || (dev == NULL))
+		return -EINVAL;
+
+	loc = &dev->addr;
+
+	/* The device is not blacklisted; Check if driver supports it */
+	if (!rte_pci_match(dr, dev))
+		/* Match of device and driver failed */
+		return 1;
+
+	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			loc->domain, loc->bus, loc->devid, loc->function,
+			dev->device.numa_node);
+
+	/* no initialization when blacklisted, return without error */
+	if (dev->device.devargs != NULL &&
+		dev->device.devargs->policy ==
+			RTE_DEV_BLACKLISTED) {
+		RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
+			" initializing\n");
+		return 1;
+	}
+
+	if (dev->device.numa_node < 0) {
+		RTE_LOG(WARNING, EAL, "  Invalid NUMA socket, default to 0\n");
+		dev->device.numa_node = 0;
+	}
+
+	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
+		dev->id.device_id, dr->driver.name);
+
+	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+		/* map resources for devices that use igb_uio */
+		ret = rte_pci_map_device(dev);
+		if (ret != 0)
+			return ret;
+	}
+
+	/* reference driver structure */
+	dev->driver = dr;
+	dev->device.driver = &dr->driver;
+
+	/* call the driver probe() function */
+	ret = dr->probe(dr, dev);
+	if (ret) {
+		dev->driver = NULL;
+		dev->device.driver = NULL;
+		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
+			/* Don't unmap if device is unsupported and
+			 * driver needs mapped resources.
+			 */
+			!(ret > 0 &&
+				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
+			rte_pci_unmap_device(dev);
+	}
+
+	return ret;
+}
+
+/*
+ * If vendor/device ID match, call the remove() function of the
+ * driver.
+ */
+static int
+rte_pci_detach_dev(struct rte_pci_device *dev)
+{
+	struct rte_pci_addr *loc;
+	struct rte_pci_driver *dr;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	dr = dev->driver;
+	loc = &dev->addr;
+
+	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			loc->domain, loc->bus, loc->devid,
+			loc->function, dev->device.numa_node);
+
+	RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
+			dev->id.device_id, dr->driver.name);
+
+	if (dr->remove && (dr->remove(dev) < 0))
+		return -1;	/* negative value is an error */
+
+	/* clear driver structure */
+	dev->driver = NULL;
+
+	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
+		/* unmap resources for devices that use igb_uio */
+		rte_pci_unmap_device(dev);
+
+	return 0;
+}
+
+/*
+ * If vendor/device ID match, call the probe() function of all
+ * registered driver for the given device. Return -1 if initialization
+ * failed, return 1 if no driver is found for this device.
+ */
+static int
+pci_probe_all_drivers(struct rte_pci_device *dev)
+{
+	struct rte_pci_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	/* Check if a driver is already loaded */
+	if (dev->driver != NULL)
+		return 0;
+
+	FOREACH_DRIVER_ON_PCIBUS(dr) {
+		rc = rte_pci_probe_one_driver(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * Find the pci device specified by pci address, then invoke probe function of
+ * the driver of the device.
+ */
+int
+rte_pci_probe_one(const struct rte_pci_addr *addr)
+{
+	struct rte_pci_device *dev = NULL;
+
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	/* update current pci device in global list, kernel bindings might have
+	 * changed since last time we looked at it.
+	 */
+	if (pci_update_device(addr) < 0)
+		goto err_return;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (rte_eal_compare_pci_addr(&dev->addr, addr))
+			continue;
+
+		ret = pci_probe_all_drivers(dev);
+		if (ret)
+			goto err_return;
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL,
+		"Requested device " PCI_PRI_FMT " cannot be used\n",
+		addr->domain, addr->bus, addr->devid, addr->function);
+	return -1;
+}
+
+/*
+ * Detach device specified by its pci address.
+ */
+int
+rte_pci_detach(const struct rte_pci_addr *addr)
+{
+	struct rte_pci_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (rte_eal_compare_pci_addr(&dev->addr, addr))
+			continue;
+
+		ret = rte_pci_detach_dev(dev);
+		if (ret < 0)
+			/* negative value is an error */
+			goto err_return;
+		if (ret > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+
+		rte_pci_remove_device(dev);
+		free(dev);
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
+			" cannot be used\n", dev->addr.domain, dev->addr.bus,
+			dev->addr.devid, dev->addr.function);
+	return -1;
+}
+
+/*
+ * Scan the content of the PCI bus, and call the probe() function for
+ * all registered drivers that have a matching entry in its id_table
+ * for discovered devices.
+ */
+int
+rte_pci_probe(void)
+{
+	struct rte_pci_device *dev = NULL;
+	size_t probed = 0, failed = 0;
+	struct rte_devargs *devargs;
+	int probe_all = 0;
+	int ret = 0;
+
+	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
+		probe_all = 1;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		probed++;
+
+		devargs = dev->device.devargs;
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = pci_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->policy == RTE_DEV_WHITELISTED)
+			ret = pci_probe_all_drivers(dev);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
+				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
+				 dev->addr.devid, dev->addr.function);
+			rte_errno = errno;
+			failed++;
+			ret = 0;
+		}
+	}
+
+	return (probed && probed == failed) ? -1 : 0;
+}
+
+/* dump one device */
+static int
+pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
+{
+	int i;
+
+	fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
+	       dev->addr.devid, dev->addr.function);
+	fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
+	       dev->id.device_id);
+
+	for (i = 0; i != sizeof(dev->mem_resource) /
+		sizeof(dev->mem_resource[0]); i++) {
+		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
+			dev->mem_resource[i].phys_addr,
+			dev->mem_resource[i].len);
+	}
+	return 0;
+}
+
+/* dump devices on the bus */
+void
+rte_pci_dump(FILE *f)
+{
+	struct rte_pci_device *dev = NULL;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		pci_dump_one_device(f, dev);
+	}
+}
+
+static int
+pci_parse(const char *name, void *addr)
+{
+	struct rte_pci_addr *out = addr;
+	struct rte_pci_addr pci_addr;
+	bool parse;
+
+	parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
+		 eal_parse_pci_DomBDF(name, &pci_addr) == 0);
+	if (parse && addr != NULL)
+		*out = pci_addr;
+	return parse == false;
+}
+
+/* register a driver */
+void
+rte_pci_register(struct rte_pci_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
+	driver->bus = &rte_pci_bus;
+}
+
+/* unregister a driver */
+void
+rte_pci_unregister(struct rte_pci_driver *driver)
+{
+	TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
+	driver->bus = NULL;
+}
+
+/* Add a device to PCI bus */
+void
+rte_pci_add_device(struct rte_pci_device *pci_dev)
+{
+	TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
+}
+
+/* Insert a device into a predefined position in PCI bus */
+void
+rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+		      struct rte_pci_device *new_pci_dev)
+{
+	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
+}
+
+/* Remove a device from PCI bus */
+void
+rte_pci_remove_device(struct rte_pci_device *pci_dev)
+{
+	TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
+}
+
+static struct rte_device *
+pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		const void *data)
+{
+	struct rte_pci_device *dev;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (start && &dev->device == start) {
+			start = NULL; /* starting point found */
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+
+	return NULL;
+}
+
+static int
+pci_plug(struct rte_device *dev)
+{
+	return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
+}
+
+static int
+pci_unplug(struct rte_device *dev)
+{
+	struct rte_pci_device *pdev;
+	int ret;
+
+	pdev = RTE_DEV_TO_PCI(dev);
+	ret = rte_pci_detach_dev(pdev);
+	rte_pci_remove_device(pdev);
+	free(pdev);
+	return ret;
+}
+
+struct rte_pci_bus rte_pci_bus = {
+	.bus = {
+		.scan = rte_pci_scan,
+		.probe = rte_pci_probe,
+		.find_device = pci_find_device,
+		.plug = pci_plug,
+		.unplug = pci_unplug,
+		.parse = pci_parse,
+	},
+	.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
+	.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(pci, rte_pci_bus.bus);
diff --git a/drivers/bus/pci/rte_pci_common_uio.c b/drivers/bus/pci/rte_pci_common_uio.c
new file mode 100644
index 0000000..4365660
--- /dev/null
+++ b/drivers/bus/pci/rte_pci_common_uio.c
@@ -0,0 +1,234 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_tailq.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+
+#include "private.h"
+
+static struct rte_tailq_elem rte_uio_tailq = {
+	.name = "UIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_uio_tailq)
+
+static int
+pci_uio_map_secondary(struct rte_pci_device *dev)
+{
+	int fd, i, j;
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	TAILQ_FOREACH(uio_res, uio_res_list, next) {
+
+		/* skip this element if it doesn't match our PCI address */
+		if (rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+			continue;
+
+		for (i = 0; i != uio_res->nb_maps; i++) {
+			/*
+			 * open devname, to mmap it
+			 */
+			fd = open(uio_res->maps[i].path, O_RDWR);
+			if (fd < 0) {
+				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+					uio_res->maps[i].path, strerror(errno));
+				return -1;
+			}
+
+			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
+					fd, (off_t)uio_res->maps[i].offset,
+					(size_t)uio_res->maps[i].size, 0);
+			/* fd is not needed in slave process, close it */
+			close(fd);
+			if (mapaddr != uio_res->maps[i].addr) {
+				RTE_LOG(ERR, EAL,
+					"Cannot mmap device resource file %s to address: %p\n",
+					uio_res->maps[i].path,
+					uio_res->maps[i].addr);
+				if (mapaddr != MAP_FAILED) {
+					/* unmap addrs correctly mapped */
+					for (j = 0; j < i; j++)
+						pci_unmap_resource(
+							uio_res->maps[j].addr,
+							(size_t)uio_res->maps[j].size);
+					/* unmap addr wrongly mapped */
+					pci_unmap_resource(mapaddr,
+						(size_t)uio_res->maps[i].size);
+				}
+				return -1;
+			}
+		}
+		return 0;
+	}
+
+	RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
+	return 1;
+}
+
+/* map the PCI resource of a PCI device in virtual memory */
+int
+pci_uio_map_resource(struct rte_pci_device *dev)
+{
+	int i, map_idx = 0, ret;
+	uint64_t phaddr;
+	struct mapped_pci_resource *uio_res = NULL;
+	struct mapped_pci_res_list *uio_res_list =
+		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.uio_cfg_fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* secondary processes - use already recorded details */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return pci_uio_map_secondary(dev);
+
+	/* allocate uio resource */
+	ret = pci_uio_alloc_resource(dev, &uio_res);
+	if (ret)
+		return ret;
+
+	/* Map all BARs */
+	for (i = 0; i != PCI_MAX_RESOURCE; i++) {
+		/* skip empty BAR */
+		phaddr = dev->mem_resource[i].phys_addr;
+		if (phaddr == 0)
+			continue;
+
+		ret = pci_uio_map_resource_by_index(dev, i,
+				uio_res, map_idx);
+		if (ret)
+			goto error;
+
+		map_idx++;
+	}
+
+	uio_res->nb_maps = map_idx;
+
+	TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
+
+	return 0;
+error:
+	for (i = 0; i < map_idx; i++) {
+		pci_unmap_resource(uio_res->maps[i].addr,
+				(size_t)uio_res->maps[i].size);
+		rte_free(uio_res->maps[i].path);
+	}
+	pci_uio_free_resource(dev, uio_res);
+	return -1;
+}
+
+static void
+pci_uio_unmap(struct mapped_pci_resource *uio_res)
+{
+	int i;
+
+	if (uio_res == NULL)
+		return;
+
+	for (i = 0; i != uio_res->nb_maps; i++) {
+		pci_unmap_resource(uio_res->maps[i].addr,
+				(size_t)uio_res->maps[i].size);
+		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+			rte_free(uio_res->maps[i].path);
+	}
+}
+
+static struct mapped_pci_resource *
+pci_uio_find_resource(struct rte_pci_device *dev)
+{
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	if (dev == NULL)
+		return NULL;
+
+	TAILQ_FOREACH(uio_res, uio_res_list, next) {
+
+		/* skip this element if it doesn't match our PCI address */
+		if (!rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+			return uio_res;
+	}
+	return NULL;
+}
+
+/* unmap the PCI resource of a PCI device in virtual memory */
+void
+pci_uio_unmap_resource(struct rte_pci_device *dev)
+{
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	if (dev == NULL)
+		return;
+
+	/* find an entry for the device */
+	uio_res = pci_uio_find_resource(dev);
+	if (uio_res == NULL)
+		return;
+
+	/* secondary processes - just free maps */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return pci_uio_unmap(uio_res);
+
+	TAILQ_REMOVE(uio_res_list, uio_res, next);
+
+	/* unmap all resources */
+	pci_uio_unmap(uio_res);
+
+	/* free uio resource */
+	rte_free(uio_res);
+
+	/* close fd if in primary process */
+	close(dev->intr_handle.fd);
+	if (dev->intr_handle.uio_cfg_fd >= 0) {
+		close(dev->intr_handle.uio_cfg_fd);
+		dev->intr_handle.uio_cfg_fd = -1;
+	}
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+}
diff --git a/lib/Makefile b/lib/Makefile
index 86caba1..147be60 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-y += librte_compat
 DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
+DIRS-$(CONFIG_RTE_LIBRTE_PCI) += librte_pci
+DEPDIRS-librte_pci := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
 DEPDIRS-librte_ring := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 005019e..e5273f7 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -55,7 +55,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
@@ -69,8 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_errno.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 5fa5988..b7c045f 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -66,7 +66,6 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_bus.h>
-#include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_version.h>
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
deleted file mode 100644
index 04eacdc..0000000
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ /dev/null
@@ -1,670 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-#include <limits.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/pciio.h>
-#include <dev/pci/pcireg.h>
-
-#if defined(RTE_ARCH_X86)
-#include <machine/cpufunc.h>
-#endif
-
-#include <rte_interrupts.h>
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_common.h>
-#include <rte_launch.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_eal.h>
-#include <rte_eal_memconfig.h>
-#include <rte_per_lcore.h>
-#include <rte_lcore.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-#include <rte_debug.h>
-#include <rte_devargs.h>
-
-#include "eal_filesystem.h"
-#include "eal_private.h"
-
-/**
- * @file
- * PCI probing under linux
- *
- * This code is used to simulate a PCI probe by parsing information in
- * sysfs. Moreover, when a registered driver matches a device, the
- * kernel driver currently using it is unloaded and replaced by
- * igb_uio module, which is a very minimal userland driver for Intel
- * network card, only providing access to PCI BAR to applications, and
- * enabling bus master.
- */
-
-extern struct rte_pci_bus rte_pci_bus;
-
-/* Map pci device */
-int
-rte_pci_map_device(struct rte_pci_device *dev)
-{
-	int ret = -1;
-
-	/* try mapping the NIC resources */
-	switch (dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		/* map resources for devices that use uio */
-		ret = pci_uio_map_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		ret = 1;
-		break;
-	}
-
-	return ret;
-}
-
-/* Unmap pci device */
-void
-rte_pci_unmap_device(struct rte_pci_device *dev)
-{
-	/* try unmapping the NIC resources */
-	switch (dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		/* unmap resources for devices that use uio */
-		pci_uio_unmap_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		break;
-	}
-}
-
-void
-pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res)
-{
-	rte_free(uio_res);
-
-	if (dev->intr_handle.fd) {
-		close(dev->intr_handle.fd);
-		dev->intr_handle.fd = -1;
-		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	}
-}
-
-int
-pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res)
-{
-	char devname[PATH_MAX]; /* contains the /dev/uioX */
-	struct rte_pci_addr *loc;
-
-	loc = &dev->addr;
-
-	snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
-			dev->addr.bus, dev->addr.devid, dev->addr.function);
-
-	if (access(devname, O_RDWR) < 0) {
-		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
-				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
-		return 1;
-	}
-
-	/* save fd if in primary process */
-	dev->intr_handle.fd = open(devname, O_RDWR);
-	if (dev->intr_handle.fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			devname, strerror(errno));
-		goto error;
-	}
-	dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-
-	/* allocate the mapping details for secondary processes*/
-	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
-	if (*uio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto error;
-	}
-
-	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
-	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
-
-	return 0;
-
-error:
-	pci_uio_free_resource(dev, *uio_res);
-	return -1;
-}
-
-int
-pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx)
-{
-	int fd;
-	char *devname;
-	void *mapaddr;
-	uint64_t offset;
-	uint64_t pagesz;
-	struct pci_map *maps;
-
-	maps = uio_res->maps;
-	devname = uio_res->path;
-	pagesz = sysconf(_SC_PAGESIZE);
-
-	/* allocate memory to keep path */
-	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
-	if (maps[map_idx].path == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
-				strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * open resource file, to mmap it
-	 */
-	fd = open(devname, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				devname, strerror(errno));
-		goto error;
-	}
-
-	/* if matching map is found, then use it */
-	offset = res_idx * pagesz;
-	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
-			(size_t)dev->mem_resource[res_idx].len, 0);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		goto error;
-
-	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
-	maps[map_idx].size = dev->mem_resource[res_idx].len;
-	maps[map_idx].addr = mapaddr;
-	maps[map_idx].offset = offset;
-	strcpy(maps[map_idx].path, devname);
-	dev->mem_resource[res_idx].addr = mapaddr;
-
-	return 0;
-
-error:
-	rte_free(maps[map_idx].path);
-	return -1;
-}
-
-static int
-pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
-{
-	struct rte_pci_device *dev;
-	struct pci_bar_io bar;
-	unsigned i, max;
-
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL) {
-		return -1;
-	}
-
-	memset(dev, 0, sizeof(*dev));
-	dev->addr.domain = conf->pc_sel.pc_domain;
-	dev->addr.bus = conf->pc_sel.pc_bus;
-	dev->addr.devid = conf->pc_sel.pc_dev;
-	dev->addr.function = conf->pc_sel.pc_func;
-
-	/* get vendor id */
-	dev->id.vendor_id = conf->pc_vendor;
-
-	/* get device id */
-	dev->id.device_id = conf->pc_device;
-
-	/* get subsystem_vendor id */
-	dev->id.subsystem_vendor_id = conf->pc_subvendor;
-
-	/* get subsystem_device id */
-	dev->id.subsystem_device_id = conf->pc_subdevice;
-
-	/* get class id */
-	dev->id.class_id = (conf->pc_class << 16) |
-			   (conf->pc_subclass << 8) |
-			   (conf->pc_progif);
-
-	/* TODO: get max_vfs */
-	dev->max_vfs = 0;
-
-	/* FreeBSD has no NUMA support (yet) */
-	dev->device.numa_node = 0;
-
-	pci_name_set(dev);
-
-	/* FreeBSD has only one pass through driver */
-	dev->kdrv = RTE_KDRV_NIC_UIO;
-
-	/* parse resources */
-	switch (conf->pc_hdr & PCIM_HDRTYPE) {
-	case PCIM_HDRTYPE_NORMAL:
-		max = PCIR_MAX_BAR_0;
-		break;
-	case PCIM_HDRTYPE_BRIDGE:
-		max = PCIR_MAX_BAR_1;
-		break;
-	case PCIM_HDRTYPE_CARDBUS:
-		max = PCIR_MAX_BAR_2;
-		break;
-	default:
-		goto skipdev;
-	}
-
-	for (i = 0; i <= max; i++) {
-		bar.pbi_sel = conf->pc_sel;
-		bar.pbi_reg = PCIR_BAR(i);
-		if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
-			continue;
-
-		dev->mem_resource[i].len = bar.pbi_length;
-		if (PCI_BAR_IO(bar.pbi_base)) {
-			dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
-			continue;
-		}
-		dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
-	}
-
-	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-		rte_pci_add_device(dev);
-	}
-	else {
-		struct rte_pci_device *dev2 = NULL;
-		int ret;
-
-		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
-			if (ret > 0)
-				continue;
-			else if (ret < 0) {
-				rte_pci_insert_device(dev2, dev);
-			} else { /* already registered */
-				dev2->kdrv = dev->kdrv;
-				dev2->max_vfs = dev->max_vfs;
-				pci_name_set(dev2);
-				memmove(dev2->mem_resource,
-					dev->mem_resource,
-					sizeof(dev->mem_resource));
-				free(dev);
-			}
-			return 0;
-		}
-		rte_pci_add_device(dev);
-	}
-
-	return 0;
-
-skipdev:
-	free(dev);
-	return 0;
-}
-
-/*
- * Scan the content of the PCI bus, and add the devices in the devices
- * list. Call pci_scan_one() for each pci entry found.
- */
-int
-rte_pci_scan(void)
-{
-	int fd;
-	unsigned dev_count = 0;
-	struct pci_conf matches[16];
-	struct pci_conf_io conf_io = {
-			.pat_buf_len = 0,
-			.num_patterns = 0,
-			.patterns = NULL,
-			.match_buf_len = sizeof(matches),
-			.matches = &matches[0],
-	};
-
-	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
-		return 0;
-
-	fd = open("/dev/pci", O_RDONLY);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	do {
-		unsigned i;
-		if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
-			RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
-					__func__, strerror(errno));
-			goto error;
-		}
-
-		for (i = 0; i < conf_io.num_matches; i++)
-			if (pci_scan_one(fd, &matches[i]) < 0)
-				goto error;
-
-		dev_count += conf_io.num_matches;
-	} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
-
-	close(fd);
-
-	RTE_LOG(DEBUG, EAL, "PCI scan found %u devices\n", dev_count);
-	return 0;
-
-error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-int
-pci_update_device(const struct rte_pci_addr *addr)
-{
-	int fd;
-	struct pci_conf matches[2];
-	struct pci_match_conf match = {
-		.pc_sel = {
-			.pc_domain = addr->domain,
-			.pc_bus = addr->bus,
-			.pc_dev = addr->devid,
-			.pc_func = addr->function,
-		},
-	};
-	struct pci_conf_io conf_io = {
-		.pat_buf_len = 0,
-		.num_patterns = 1,
-		.patterns = &match,
-		.match_buf_len = sizeof(matches),
-		.matches = &matches[0],
-	};
-
-	fd = open("/dev/pci", O_RDONLY);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
-				__func__, strerror(errno));
-		goto error;
-	}
-
-	if (conf_io.num_matches != 1)
-		goto error;
-
-	if (pci_scan_one(fd, &matches[0]) < 0)
-		goto error;
-
-	close(fd);
-
-	return 0;
-
-error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/* Read PCI config space. */
-int rte_pci_read_config(const struct rte_pci_device *dev,
-		void *buf, size_t len, off_t offset)
-{
-	int fd = -1;
-	int size;
-	struct pci_io pi = {
-		.pi_sel = {
-			.pc_domain = dev->addr.domain,
-			.pc_bus = dev->addr.bus,
-			.pc_dev = dev->addr.devid,
-			.pc_func = dev->addr.function,
-		},
-		.pi_reg = offset,
-	};
-
-	fd = open("/dev/pci", O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	while (len > 0) {
-		size = (len >= 4) ? 4 : ((len >= 2) ? 2 : 1);
-		pi.pi_width = size;
-
-		if (ioctl(fd, PCIOCREAD, &pi) < 0)
-			goto error;
-		memcpy(buf, &pi.pi_data, size);
-
-		buf = (char *)buf + size;
-		pi.pi_reg += size;
-		len -= size;
-	}
-	close(fd);
-
-	return 0;
-
- error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/* Write PCI config space. */
-int rte_pci_write_config(const struct rte_pci_device *dev,
-		const void *buf, size_t len, off_t offset)
-{
-	int fd = -1;
-
-	struct pci_io pi = {
-		.pi_sel = {
-			.pc_domain = dev->addr.domain,
-			.pc_bus = dev->addr.bus,
-			.pc_dev = dev->addr.devid,
-			.pc_func = dev->addr.function,
-		},
-		.pi_reg = offset,
-		.pi_data = *(const uint32_t *)buf,
-		.pi_width = len,
-	};
-
-	if (len == 3 || len > sizeof(pi.pi_data)) {
-		RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__);
-		goto error;
-	}
-
-	memcpy(&pi.pi_data, buf, len);
-
-	fd = open("/dev/pci", O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	if (ioctl(fd, PCIOCWRITE, &pi) < 0)
-		goto error;
-
-	close(fd);
-	return 0;
-
- error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-int
-rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p)
-{
-	int ret;
-
-	switch (dev->kdrv) {
-#if defined(RTE_ARCH_X86)
-	case RTE_KDRV_NIC_UIO:
-		if ((uintptr_t) dev->mem_resource[bar].addr <= UINT16_MAX) {
-			p->base = (uintptr_t)dev->mem_resource[bar].addr;
-			ret = 0;
-		} else
-			ret = -1;
-		break;
-#endif
-	default:
-		ret = -1;
-		break;
-	}
-
-	if (!ret)
-		p->dev = dev;
-
-	return ret;
-}
-
-static void
-pci_uio_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-#if defined(RTE_ARCH_X86)
-	uint8_t *d;
-	int size;
-	unsigned short reg = p->base + offset;
-
-	for (d = data; len > 0; d += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-			*(uint32_t *)d = inl(reg);
-		} else if (len >= 2) {
-			size = 2;
-			*(uint16_t *)d = inw(reg);
-		} else {
-			size = 1;
-			*d = inb(reg);
-		}
-	}
-#else
-	RTE_SET_USED(p);
-	RTE_SET_USED(data);
-	RTE_SET_USED(len);
-	RTE_SET_USED(offset);
-#endif
-}
-
-void
-rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	default:
-		break;
-	}
-}
-
-static void
-pci_uio_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-#if defined(RTE_ARCH_X86)
-	const uint8_t *s;
-	int size;
-	unsigned short reg = p->base + offset;
-
-	for (s = data; len > 0; s += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-			outl(reg, *(const uint32_t *)s);
-		} else if (len >= 2) {
-			size = 2;
-			outw(reg, *(const uint16_t *)s);
-		} else {
-			size = 1;
-			outb(reg, *s);
-		}
-	}
-#else
-	RTE_SET_USED(p);
-	RTE_SET_USED(data);
-	RTE_SET_USED(len);
-	RTE_SET_USED(offset);
-#endif
-}
-
-void
-rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	default:
-		break;
-	}
-}
-
-int
-rte_pci_ioport_unmap(struct rte_pci_ioport *p)
-{
-	int ret;
-
-	switch (p->dev->kdrv) {
-#if defined(RTE_ARCH_X86)
-	case RTE_KDRV_NIC_UIO:
-		ret = 0;
-		break;
-#endif
-	default:
-		ret = -1;
-		break;
-	}
-
-	return ret;
-}
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 2065c53..cdd9dca 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -169,21 +169,6 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_pci_detach;
-	rte_pci_dump;
-	rte_pci_ioport_map;
-	rte_pci_ioport_read;
-	rte_pci_ioport_unmap;
-	rte_pci_ioport_write;
-	rte_pci_map_device;
-	rte_pci_probe;
-	rte_pci_probe_one;
-	rte_pci_read_config;
-	rte_pci_register;
-	rte_pci_scan;
-	rte_pci_unmap_device;
-	rte_pci_unregister;
-	rte_pci_write_config;
 	rte_vdev_init;
 	rte_vdev_register;
 	rte_vdev_uninit;
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index e8fd67a..ac8d3bb 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h
 INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
deleted file mode 100644
index 52fd38c..0000000
--- a/lib/librte_eal/common/eal_common_pci.c
+++ /dev/null
@@ -1,580 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   Copyright 2013-2014 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-
-#include <rte_errno.h>
-#include <rte_interrupts.h>
-#include <rte_log.h>
-#include <rte_bus.h>
-#include <rte_pci.h>
-#include <rte_per_lcore.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_eal.h>
-#include <rte_string_fns.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-
-#include "eal_private.h"
-
-extern struct rte_pci_bus rte_pci_bus;
-
-#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
-
-const char *pci_get_sysfs_path(void)
-{
-	const char *path = NULL;
-
-	path = getenv("SYSFS_PCI_DEVICES");
-	if (path == NULL)
-		return SYSFS_PCI_DEVICES;
-
-	return path;
-}
-
-static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_pci_addr addr;
-	struct rte_bus *pbus;
-
-	pbus = rte_bus_find_by_name("pci");
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-		if (devargs->bus != pbus)
-			continue;
-		devargs->bus->parse(devargs->name, &addr);
-		if (!rte_eal_compare_pci_addr(&dev->addr, &addr))
-			return devargs;
-	}
-	return NULL;
-}
-
-void
-pci_name_set(struct rte_pci_device *dev)
-{
-	struct rte_devargs *devargs;
-
-	/* Each device has its internal, canonical name set. */
-	rte_pci_device_name(&dev->addr,
-			dev->name, sizeof(dev->name));
-	devargs = pci_devargs_lookup(dev);
-	dev->device.devargs = devargs;
-	/* In blacklist mode, if the device is not blacklisted, no
-	 * rte_devargs exists for it.
-	 */
-	if (devargs != NULL)
-		/* If an rte_devargs exists, the generic rte_device uses the
-		 * given name as its namea
-		 */
-		dev->device.name = dev->device.devargs->name;
-	else
-		/* Otherwise, it uses the internal, canonical form. */
-		dev->device.name = dev->name;
-}
-
-/* map a particular resource from a file */
-void *
-pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
-		 int additional_flags)
-{
-	void *mapaddr;
-
-	/* Map the PCI memory resource of device */
-	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
-			MAP_SHARED | additional_flags, fd, offset);
-	if (mapaddr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
-			__func__, fd, requested_addr,
-			(unsigned long)size, (unsigned long)offset,
-			strerror(errno), mapaddr);
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
-
-	return mapaddr;
-}
-
-/* unmap a particular resource */
-void
-pci_unmap_resource(void *requested_addr, size_t size)
-{
-	if (requested_addr == NULL)
-		return;
-
-	/* Unmap the PCI memory resource of device */
-	if (munmap(requested_addr, size)) {
-		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
-			__func__, requested_addr, (unsigned long)size,
-			strerror(errno));
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
-				requested_addr);
-}
-
-/*
- * Match the PCI Driver and Device using the ID Table
- *
- * @param pci_drv
- *	PCI driver from which ID table would be extracted
- * @param pci_dev
- *	PCI device to match against the driver
- * @return
- *	1 for successful match
- *	0 for unsuccessful match
- */
-static int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev)
-{
-	const struct rte_pci_id *id_table;
-
-	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
-	     id_table++) {
-		/* check if device's identifiers match the driver's ones */
-		if (id_table->vendor_id != pci_dev->id.vendor_id &&
-				id_table->vendor_id != PCI_ANY_ID)
-			continue;
-		if (id_table->device_id != pci_dev->id.device_id &&
-				id_table->device_id != PCI_ANY_ID)
-			continue;
-		if (id_table->subsystem_vendor_id !=
-		    pci_dev->id.subsystem_vendor_id &&
-		    id_table->subsystem_vendor_id != PCI_ANY_ID)
-			continue;
-		if (id_table->subsystem_device_id !=
-		    pci_dev->id.subsystem_device_id &&
-		    id_table->subsystem_device_id != PCI_ANY_ID)
-			continue;
-		if (id_table->class_id != pci_dev->id.class_id &&
-				id_table->class_id != RTE_CLASS_ANY_ID)
-			continue;
-
-		return 1;
-	}
-
-	return 0;
-}
-
-/*
- * If vendor/device ID match, call the probe() function of the
- * driver.
- */
-static int
-rte_pci_probe_one_driver(struct rte_pci_driver *dr,
-			 struct rte_pci_device *dev)
-{
-	int ret;
-	struct rte_pci_addr *loc;
-
-	if ((dr == NULL) || (dev == NULL))
-		return -EINVAL;
-
-	loc = &dev->addr;
-
-	/* The device is not blacklisted; Check if driver supports it */
-	if (!rte_pci_match(dr, dev))
-		/* Match of device and driver failed */
-		return 1;
-
-	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-			loc->domain, loc->bus, loc->devid, loc->function,
-			dev->device.numa_node);
-
-	/* no initialization when blacklisted, return without error */
-	if (dev->device.devargs != NULL &&
-		dev->device.devargs->policy ==
-			RTE_DEV_BLACKLISTED) {
-		RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
-			" initializing\n");
-		return 1;
-	}
-
-	if (dev->device.numa_node < 0) {
-		RTE_LOG(WARNING, EAL, "  Invalid NUMA socket, default to 0\n");
-		dev->device.numa_node = 0;
-	}
-
-	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
-		dev->id.device_id, dr->driver.name);
-
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
-		/* map resources for devices that use igb_uio */
-		ret = rte_pci_map_device(dev);
-		if (ret != 0)
-			return ret;
-	}
-
-	/* reference driver structure */
-	dev->driver = dr;
-	dev->device.driver = &dr->driver;
-
-	/* call the driver probe() function */
-	ret = dr->probe(dr, dev);
-	if (ret) {
-		dev->driver = NULL;
-		dev->device.driver = NULL;
-		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
-			/* Don't unmap if device is unsupported and
-			 * driver needs mapped resources.
-			 */
-			!(ret > 0 &&
-				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
-			rte_pci_unmap_device(dev);
-	}
-
-	return ret;
-}
-
-/*
- * If vendor/device ID match, call the remove() function of the
- * driver.
- */
-static int
-rte_pci_detach_dev(struct rte_pci_device *dev)
-{
-	struct rte_pci_addr *loc;
-	struct rte_pci_driver *dr;
-
-	if (dev == NULL)
-		return -EINVAL;
-
-	dr = dev->driver;
-	loc = &dev->addr;
-
-	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-			loc->domain, loc->bus, loc->devid,
-			loc->function, dev->device.numa_node);
-
-	RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
-			dev->id.device_id, dr->driver.name);
-
-	if (dr->remove && (dr->remove(dev) < 0))
-		return -1;	/* negative value is an error */
-
-	/* clear driver structure */
-	dev->driver = NULL;
-
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
-		/* unmap resources for devices that use igb_uio */
-		rte_pci_unmap_device(dev);
-
-	return 0;
-}
-
-/*
- * If vendor/device ID match, call the probe() function of all
- * registered driver for the given device. Return -1 if initialization
- * failed, return 1 if no driver is found for this device.
- */
-static int
-pci_probe_all_drivers(struct rte_pci_device *dev)
-{
-	struct rte_pci_driver *dr = NULL;
-	int rc = 0;
-
-	if (dev == NULL)
-		return -1;
-
-	/* Check if a driver is already loaded */
-	if (dev->driver != NULL)
-		return 0;
-
-	FOREACH_DRIVER_ON_PCIBUS(dr) {
-		rc = rte_pci_probe_one_driver(dr, dev);
-		if (rc < 0)
-			/* negative value is an error */
-			return -1;
-		if (rc > 0)
-			/* positive value means driver doesn't support it */
-			continue;
-		return 0;
-	}
-	return 1;
-}
-
-/*
- * Find the pci device specified by pci address, then invoke probe function of
- * the driver of the device.
- */
-int
-rte_pci_probe_one(const struct rte_pci_addr *addr)
-{
-	struct rte_pci_device *dev = NULL;
-
-	int ret = 0;
-
-	if (addr == NULL)
-		return -1;
-
-	/* update current pci device in global list, kernel bindings might have
-	 * changed since last time we looked at it.
-	 */
-	if (pci_update_device(addr) < 0)
-		goto err_return;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_eal_compare_pci_addr(&dev->addr, addr))
-			continue;
-
-		ret = pci_probe_all_drivers(dev);
-		if (ret)
-			goto err_return;
-		return 0;
-	}
-	return -1;
-
-err_return:
-	RTE_LOG(WARNING, EAL,
-		"Requested device " PCI_PRI_FMT " cannot be used\n",
-		addr->domain, addr->bus, addr->devid, addr->function);
-	return -1;
-}
-
-/*
- * Detach device specified by its pci address.
- */
-int
-rte_pci_detach(const struct rte_pci_addr *addr)
-{
-	struct rte_pci_device *dev = NULL;
-	int ret = 0;
-
-	if (addr == NULL)
-		return -1;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_eal_compare_pci_addr(&dev->addr, addr))
-			continue;
-
-		ret = rte_pci_detach_dev(dev);
-		if (ret < 0)
-			/* negative value is an error */
-			goto err_return;
-		if (ret > 0)
-			/* positive value means driver doesn't support it */
-			continue;
-
-		rte_pci_remove_device(dev);
-		free(dev);
-		return 0;
-	}
-	return -1;
-
-err_return:
-	RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
-			" cannot be used\n", dev->addr.domain, dev->addr.bus,
-			dev->addr.devid, dev->addr.function);
-	return -1;
-}
-
-/*
- * Scan the content of the PCI bus, and call the probe() function for
- * all registered drivers that have a matching entry in its id_table
- * for discovered devices.
- */
-int
-rte_pci_probe(void)
-{
-	struct rte_pci_device *dev = NULL;
-	size_t probed = 0, failed = 0;
-	struct rte_devargs *devargs;
-	int probe_all = 0;
-	int ret = 0;
-
-	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
-		probe_all = 1;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		probed++;
-
-		devargs = dev->device.devargs;
-		/* probe all or only whitelisted devices */
-		if (probe_all)
-			ret = pci_probe_all_drivers(dev);
-		else if (devargs != NULL &&
-			devargs->policy == RTE_DEV_WHITELISTED)
-			ret = pci_probe_all_drivers(dev);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
-				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
-				 dev->addr.devid, dev->addr.function);
-			rte_errno = errno;
-			failed++;
-			ret = 0;
-		}
-	}
-
-	return (probed && probed == failed) ? -1 : 0;
-}
-
-/* dump one device */
-static int
-pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
-{
-	int i;
-
-	fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
-	       dev->addr.devid, dev->addr.function);
-	fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
-	       dev->id.device_id);
-
-	for (i = 0; i != sizeof(dev->mem_resource) /
-		sizeof(dev->mem_resource[0]); i++) {
-		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
-			dev->mem_resource[i].phys_addr,
-			dev->mem_resource[i].len);
-	}
-	return 0;
-}
-
-/* dump devices on the bus */
-void
-rte_pci_dump(FILE *f)
-{
-	struct rte_pci_device *dev = NULL;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		pci_dump_one_device(f, dev);
-	}
-}
-
-static int
-pci_parse(const char *name, void *addr)
-{
-	struct rte_pci_addr *out = addr;
-	struct rte_pci_addr pci_addr;
-	bool parse;
-
-	parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
-		 eal_parse_pci_DomBDF(name, &pci_addr) == 0);
-	if (parse && addr != NULL)
-		*out = pci_addr;
-	return parse == false;
-}
-
-/* register a driver */
-void
-rte_pci_register(struct rte_pci_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
-	driver->bus = &rte_pci_bus;
-}
-
-/* unregister a driver */
-void
-rte_pci_unregister(struct rte_pci_driver *driver)
-{
-	TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
-	driver->bus = NULL;
-}
-
-/* Add a device to PCI bus */
-void
-rte_pci_add_device(struct rte_pci_device *pci_dev)
-{
-	TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
-}
-
-/* Insert a device into a predefined position in PCI bus */
-void
-rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
-		      struct rte_pci_device *new_pci_dev)
-{
-	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
-}
-
-/* Remove a device from PCI bus */
-void
-rte_pci_remove_device(struct rte_pci_device *pci_dev)
-{
-	TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
-}
-
-static struct rte_device *
-pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		const void *data)
-{
-	struct rte_pci_device *dev;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (start && &dev->device == start) {
-			start = NULL; /* starting point found */
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-
-	return NULL;
-}
-
-static int
-pci_plug(struct rte_device *dev)
-{
-	return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
-}
-
-static int
-pci_unplug(struct rte_device *dev)
-{
-	struct rte_pci_device *pdev;
-	int ret;
-
-	pdev = RTE_DEV_TO_PCI(dev);
-	ret = rte_pci_detach_dev(pdev);
-	rte_pci_remove_device(pdev);
-	free(pdev);
-	return ret;
-}
-
-struct rte_pci_bus rte_pci_bus = {
-	.bus = {
-		.scan = rte_pci_scan,
-		.probe = rte_pci_probe,
-		.find_device = pci_find_device,
-		.plug = pci_plug,
-		.unplug = pci_unplug,
-		.parse = pci_parse,
-	},
-	.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
-	.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
-};
-
-RTE_REGISTER_BUS(pci, rte_pci_bus.bus);
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
deleted file mode 100644
index 367a681..0000000
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include <rte_eal.h>
-#include <rte_tailq.h>
-#include <rte_log.h>
-#include <rte_malloc.h>
-
-#include "eal_private.h"
-
-static struct rte_tailq_elem rte_uio_tailq = {
-	.name = "UIO_RESOURCE_LIST",
-};
-EAL_REGISTER_TAILQ(rte_uio_tailq)
-
-static int
-pci_uio_map_secondary(struct rte_pci_device *dev)
-{
-	int fd, i, j;
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	TAILQ_FOREACH(uio_res, uio_res_list, next) {
-
-		/* skip this element if it doesn't match our PCI address */
-		if (rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
-			continue;
-
-		for (i = 0; i != uio_res->nb_maps; i++) {
-			/*
-			 * open devname, to mmap it
-			 */
-			fd = open(uio_res->maps[i].path, O_RDWR);
-			if (fd < 0) {
-				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-					uio_res->maps[i].path, strerror(errno));
-				return -1;
-			}
-
-			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
-					fd, (off_t)uio_res->maps[i].offset,
-					(size_t)uio_res->maps[i].size, 0);
-			/* fd is not needed in slave process, close it */
-			close(fd);
-			if (mapaddr != uio_res->maps[i].addr) {
-				RTE_LOG(ERR, EAL,
-					"Cannot mmap device resource file %s to address: %p\n",
-					uio_res->maps[i].path,
-					uio_res->maps[i].addr);
-				if (mapaddr != MAP_FAILED) {
-					/* unmap addrs correctly mapped */
-					for (j = 0; j < i; j++)
-						pci_unmap_resource(
-							uio_res->maps[j].addr,
-							(size_t)uio_res->maps[j].size);
-					/* unmap addr wrongly mapped */
-					pci_unmap_resource(mapaddr,
-						(size_t)uio_res->maps[i].size);
-				}
-				return -1;
-			}
-		}
-		return 0;
-	}
-
-	RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
-	return 1;
-}
-
-/* map the PCI resource of a PCI device in virtual memory */
-int
-pci_uio_map_resource(struct rte_pci_device *dev)
-{
-	int i, map_idx = 0, ret;
-	uint64_t phaddr;
-	struct mapped_pci_resource *uio_res = NULL;
-	struct mapped_pci_res_list *uio_res_list =
-		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.uio_cfg_fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* secondary processes - use already recorded details */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return pci_uio_map_secondary(dev);
-
-	/* allocate uio resource */
-	ret = pci_uio_alloc_resource(dev, &uio_res);
-	if (ret)
-		return ret;
-
-	/* Map all BARs */
-	for (i = 0; i != PCI_MAX_RESOURCE; i++) {
-		/* skip empty BAR */
-		phaddr = dev->mem_resource[i].phys_addr;
-		if (phaddr == 0)
-			continue;
-
-		ret = pci_uio_map_resource_by_index(dev, i,
-				uio_res, map_idx);
-		if (ret)
-			goto error;
-
-		map_idx++;
-	}
-
-	uio_res->nb_maps = map_idx;
-
-	TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
-
-	return 0;
-error:
-	for (i = 0; i < map_idx; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
-				(size_t)uio_res->maps[i].size);
-		rte_free(uio_res->maps[i].path);
-	}
-	pci_uio_free_resource(dev, uio_res);
-	return -1;
-}
-
-static void
-pci_uio_unmap(struct mapped_pci_resource *uio_res)
-{
-	int i;
-
-	if (uio_res == NULL)
-		return;
-
-	for (i = 0; i != uio_res->nb_maps; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
-				(size_t)uio_res->maps[i].size);
-		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-			rte_free(uio_res->maps[i].path);
-	}
-}
-
-static struct mapped_pci_resource *
-pci_uio_find_resource(struct rte_pci_device *dev)
-{
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	if (dev == NULL)
-		return NULL;
-
-	TAILQ_FOREACH(uio_res, uio_res_list, next) {
-
-		/* skip this element if it doesn't match our PCI address */
-		if (!rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
-			return uio_res;
-	}
-	return NULL;
-}
-
-/* unmap the PCI resource of a PCI device in virtual memory */
-void
-pci_uio_unmap_resource(struct rte_pci_device *dev)
-{
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	if (dev == NULL)
-		return;
-
-	/* find an entry for the device */
-	uio_res = pci_uio_find_resource(dev);
-	if (uio_res == NULL)
-		return;
-
-	/* secondary processes - just free maps */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return pci_uio_unmap(uio_res);
-
-	TAILQ_REMOVE(uio_res_list, uio_res, next);
-
-	/* unmap all resources */
-	pci_uio_unmap(uio_res);
-
-	/* free uio resource */
-	rte_free(uio_res);
-
-	/* close fd if in primary process */
-	close(dev->intr_handle.fd);
-	if (dev->intr_handle.uio_cfg_fd >= 0) {
-		close(dev->intr_handle.uio_cfg_fd);
-		dev->intr_handle.uio_cfg_fd = -1;
-	}
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 10a7078..fc504ef 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,7 +36,6 @@
 
 #include <stdbool.h>
 #include <stdio.h>
-#include <rte_pci.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -109,137 +108,6 @@ int rte_eal_timer_init(void);
  */
 int rte_eal_log_init(const char *id, int facility);
 
-struct rte_pci_driver;
-struct rte_pci_device;
-
-/**
- * Find the name of a PCI device.
- */
-void pci_name_set(struct rte_pci_device *dev);
-
-/**
- * Add a PCI device to the PCI Bus (append to PCI Device list). This function
- * also updates the bus references of the PCI Device (and the generic device
- * object embedded within.
- *
- * @param pci_dev
- *	PCI device to add
- * @return void
- */
-void rte_pci_add_device(struct rte_pci_device *pci_dev);
-
-/**
- * Insert a PCI device in the PCI Bus at a particular location in the device
- * list. It also updates the PCI Bus reference of the new devices to be
- * inserted.
- *
- * @param exist_pci_dev
- *	Existing PCI device in PCI Bus
- * @param new_pci_dev
- *	PCI device to be added before exist_pci_dev
- * @return void
- */
-void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
-		struct rte_pci_device *new_pci_dev);
-
-/**
- * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
- * in the PCI device object as well as the generic device object.
- *
- * @param pci_device
- *	PCI device to be removed from PCI Bus
- * @return void
- */
-void rte_pci_remove_device(struct rte_pci_device *pci_device);
-
-/**
- * Update a pci device object by asking the kernel for the latest information.
- *
- * This function is private to EAL.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to look for
- * @return
- *   - 0 on success.
- *   - negative on error.
- */
-int pci_update_device(const struct rte_pci_addr *addr);
-
-/**
- * Unbind kernel driver for this device
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int pci_unbind_kernel_driver(struct rte_pci_device *dev);
-
-/**
- * Map the PCI resource of a PCI device in virtual memory
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_map_resource(struct rte_pci_device *dev);
-
-/**
- * Unmap the PCI resource of a PCI device
- *
- * This function is private to EAL.
- */
-void pci_uio_unmap_resource(struct rte_pci_device *dev);
-
-/**
- * Allocate uio resource for PCI device
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device to allocate uio resource
- * @param uio_res
- *   Pointer to uio resource.
- *   If the function returns 0, the pointer will be filled.
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res);
-
-/**
- * Free uio resource for PCI device
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device to free uio resource
- * @param uio_res
- *   Pointer to uio resource.
- */
-void pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res);
-
-/**
- * Map device memory to uio resource
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device that has memory information.
- * @param res_idx
- *   Memory resource index of the PCI device.
- * @param uio_res
- *  uio resource that will keep mapping information.
- * @param map_idx
- *   Mapping information index of the uio resource.
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx);
-
 /**
  * Init tail queues for non-EAL library structures. This is to allow
  * the rings, mempools, etc. lists to be shared among multiple processes
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
deleted file mode 100644
index 8b12339..0000000
--- a/lib/librte_eal/common/include/rte_pci.h
+++ /dev/null
@@ -1,598 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   Copyright 2013-2014 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_PCI_H_
-#define _RTE_PCI_H_
-
-/**
- * @file
- *
- * RTE PCI Interface
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <errno.h>
-#include <sys/queue.h>
-#include <stdint.h>
-#include <inttypes.h>
-
-#include <rte_debug.h>
-#include <rte_interrupts.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-
-/** Pathname of PCI devices directory. */
-const char *pci_get_sysfs_path(void);
-
-/** Formatting string for PCI device identifier: Ex: 0000:00:01.0 */
-#define PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
-#define PCI_PRI_STR_SIZE sizeof("XXXXXXXX:XX:XX.X")
-
-/** Short formatting string, without domain, for PCI device: Ex: 00:01.0 */
-#define PCI_SHORT_PRI_FMT "%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
-
-/** Nb. of values in PCI device identifier format string. */
-#define PCI_FMT_NVAL 4
-
-/** Nb. of values in PCI resource format. */
-#define PCI_RESOURCE_FMT_NVAL 3
-
-/** Maximum number of PCI resources. */
-#define PCI_MAX_RESOURCE 6
-
-/* Forward declarations */
-struct rte_pci_device;
-struct rte_pci_driver;
-
-/** List of PCI devices */
-TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
-/** List of PCI drivers */
-TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
-
-/* PCI Bus iterators */
-#define FOREACH_DEVICE_ON_PCIBUS(p)	\
-		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
-
-#define FOREACH_DRIVER_ON_PCIBUS(p)	\
-		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
-
-/**
- * A structure describing an ID for a PCI driver. Each driver provides a
- * table of these IDs for each device that it supports.
- */
-struct rte_pci_id {
-	uint32_t class_id;            /**< Class ID (class, subclass, pi) or RTE_CLASS_ANY_ID. */
-	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
-	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
-	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
-	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
-};
-
-/**
- * A structure describing the location of a PCI device.
- */
-struct rte_pci_addr {
-	uint32_t domain;                /**< Device domain */
-	uint8_t bus;                    /**< Device bus */
-	uint8_t devid;                  /**< Device ID */
-	uint8_t function;               /**< Device function. */
-};
-
-struct rte_devargs;
-
-/**
- * A structure describing a PCI device.
- */
-struct rte_pci_device {
-	TAILQ_ENTRY(rte_pci_device) next;       /**< Next probed PCI device. */
-	struct rte_device device;               /**< Inherit core device */
-	struct rte_pci_addr addr;               /**< PCI location. */
-	struct rte_pci_id id;                   /**< PCI ID. */
-	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
-						/**< PCI Memory Resource */
-	struct rte_intr_handle intr_handle;     /**< Interrupt handle */
-	struct rte_pci_driver *driver;          /**< Associated driver */
-	uint16_t max_vfs;                       /**< sriov enable if not zero */
-	enum rte_kernel_driver kdrv;            /**< Kernel driver passthrough */
-	char name[PCI_PRI_STR_SIZE+1];          /**< PCI location (ASCII) */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_pci_device.
- */
-#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
-
-/** Any PCI device identifier (vendor, device, ...) */
-#define PCI_ANY_ID (0xffff)
-#define RTE_CLASS_ANY_ID (0xffffff)
-
-#ifdef __cplusplus
-/** C++ macro used to help building up tables of device IDs */
-#define RTE_PCI_DEVICE(vend, dev) \
-	RTE_CLASS_ANY_ID,         \
-	(vend),                   \
-	(dev),                    \
-	PCI_ANY_ID,               \
-	PCI_ANY_ID
-#else
-/** Macro used to help building up tables of device IDs */
-#define RTE_PCI_DEVICE(vend, dev)          \
-	.class_id = RTE_CLASS_ANY_ID,      \
-	.vendor_id = (vend),               \
-	.device_id = (dev),                \
-	.subsystem_vendor_id = PCI_ANY_ID, \
-	.subsystem_device_id = PCI_ANY_ID
-#endif
-
-/**
- * Initialisation function for the driver called during PCI probing.
- */
-typedef int (pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
-
-/**
- * Uninitialisation function for the driver called during hotplugging.
- */
-typedef int (pci_remove_t)(struct rte_pci_device *);
-
-/**
- * A structure describing a PCI driver.
- */
-struct rte_pci_driver {
-	TAILQ_ENTRY(rte_pci_driver) next;       /**< Next in list. */
-	struct rte_driver driver;               /**< Inherit core driver. */
-	struct rte_pci_bus *bus;                /**< PCI bus reference. */
-	pci_probe_t *probe;                     /**< Device Probe function. */
-	pci_remove_t *remove;                   /**< Device Remove function. */
-	const struct rte_pci_id *id_table;	/**< ID table, NULL terminated. */
-	uint32_t drv_flags;                     /**< Flags contolling handling of device. */
-};
-
-/**
- * Structure describing the PCI bus
- */
-struct rte_pci_bus {
-	struct rte_bus bus;               /**< Inherit the generic class */
-	struct rte_pci_device_list device_list;  /**< List of PCI devices */
-	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
-};
-
-/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
-#define RTE_PCI_DRV_NEED_MAPPING 0x0001
-/** Device driver supports link state interrupt */
-#define RTE_PCI_DRV_INTR_LSC	0x0008
-/** Device driver supports device removal interrupt */
-#define RTE_PCI_DRV_INTR_RMV 0x0010
-/** Device driver needs to keep mapped resources if unsupported dev detected */
-#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
-
-/**
- * A structure describing a PCI mapping.
- */
-struct pci_map {
-	void *addr;
-	char *path;
-	uint64_t offset;
-	uint64_t size;
-	uint64_t phaddr;
-};
-
-/**
- * A structure describing a mapped PCI resource.
- * For multi-process we need to reproduce all PCI mappings in secondary
- * processes, so save them in a tailq.
- */
-struct mapped_pci_resource {
-	TAILQ_ENTRY(mapped_pci_resource) next;
-
-	struct rte_pci_addr pci_addr;
-	char path[PATH_MAX];
-	int nb_maps;
-	struct pci_map maps[PCI_MAX_RESOURCE];
-};
-
-/** mapped pci device list */
-TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
-
-/**< Internal use only - Macro used by pci addr parsing functions **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
-do {                                                               \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
-
-/**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided without
- * a domain prefix (i.e. domain returned is always 0)
- *
- * @param input
- *	The input string to be parsed. Should have the format XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned. Domain will always be
- *	returned as 0
- * @return
- *  0 on success, negative on error.
- */
-static inline int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-
-/**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided including
- * a domain prefix.
- *
- * @param input
- *	The input string to be parsed. Should have the format XXXX:XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned
- * @return
- *  0 on success, negative on error.
- */
-static inline int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-#undef GET_PCIADDR_FIELD
-
-/**
- * Utility function to write a pci device name, this device name can later be
- * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
- * BDF helpers.
- *
- * @param addr
- *	The PCI Bus-Device-Function address
- * @param output
- *	The output buffer string
- * @param size
- *	The output buffer size
- */
-static inline void
-rte_pci_device_name(const struct rte_pci_addr *addr,
-		char *output, size_t size)
-{
-	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
-	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
-			    addr->domain, addr->bus,
-			    addr->devid, addr->function) >= 0);
-}
-
-/* Compare two PCI device addresses. */
-/**
- * Utility function to compare two PCI device addresses.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to compare
- * @param addr2
- *	The PCI Bus-Device-Function address to compare
- * @return
- *	0 on equal PCI address.
- *	Positive on addr is greater than addr2.
- *	Negative on addr is less than addr2, or error.
- */
-static inline int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			 const struct rte_pci_addr *addr2)
-{
-	uint64_t dev_addr, dev_addr2;
-
-	if ((addr == NULL) || (addr2 == NULL))
-		return -1;
-
-	dev_addr = ((uint64_t)addr->domain << 24) |
-		(addr->bus << 16) | (addr->devid << 8) | addr->function;
-	dev_addr2 = ((uint64_t)addr2->domain << 24) |
-		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
-
-	if (dev_addr > dev_addr2)
-		return 1;
-	else if (dev_addr < dev_addr2)
-		return -1;
-	else
-		return 0;
-}
-
-/**
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- *
- * @return
- *  0 on success, negative on error
- */
-int rte_pci_scan(void);
-
-/**
- * Probe the PCI bus
- *
- * @return
- *   - 0 on success.
- *   - !0 on error.
- */
-int
-rte_pci_probe(void);
-
-/**
- * Map the PCI device resources in user space virtual memory address
- *
- * Note that driver should not call this function when flag
- * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for
- * you when it's on.
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- *
- * @return
- *   0 on success, negative on error and positive if no driver
- *   is found for the device.
- */
-int rte_pci_map_device(struct rte_pci_device *dev);
-
-/**
- * Unmap this device
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- */
-void rte_pci_unmap_device(struct rte_pci_device *dev);
-
-/**
- * @internal
- * Map a particular resource from a file.
- *
- * @param requested_addr
- *      The starting address for the new mapping range.
- * @param fd
- *      The file descriptor.
- * @param offset
- *      The offset for the mapping range.
- * @param size
- *      The size for the mapping range.
- * @param additional_flags
- *      The additional flags for the mapping range.
- * @return
- *   - On success, the function returns a pointer to the mapped area.
- *   - On error, the value MAP_FAILED is returned.
- */
-void *pci_map_resource(void *requested_addr, int fd, off_t offset,
-		size_t size, int additional_flags);
-
-/**
- * @internal
- * Unmap a particular resource.
- *
- * @param requested_addr
- *      The address for the unmapping range.
- * @param size
- *      The size for the unmapping range.
- */
-void pci_unmap_resource(void *requested_addr, size_t size);
-
-/**
- * Probe the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the probe() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to probe.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_probe_one(const struct rte_pci_addr *addr);
-
-/**
- * Close the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the remove() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to close.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_detach(const struct rte_pci_addr *addr);
-
-/**
- * Dump the content of the PCI bus.
- *
- * @param f
- *   A pointer to a file for output
- */
-void rte_pci_dump(FILE *f);
-
-/**
- * Register a PCI driver.
- *
- * @param driver
- *   A pointer to a rte_pci_driver structure describing the driver
- *   to be registered.
- */
-void rte_pci_register(struct rte_pci_driver *driver);
-
-/** Helper for PCI device registration from driver (eth, crypto) instance */
-#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
-RTE_INIT(pciinitfn_ ##nm); \
-static void pciinitfn_ ##nm(void) \
-{\
-	(pci_drv).driver.name = RTE_STR(nm);\
-	rte_pci_register(&pci_drv); \
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-/**
- * Unregister a PCI driver.
- *
- * @param driver
- *   A pointer to a rte_pci_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_pci_unregister(struct rte_pci_driver *driver);
-
-/**
- * Read PCI config space.
- *
- * @param device
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- * @param buf
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into PCI config space
- */
-int rte_pci_read_config(const struct rte_pci_device *device,
-		void *buf, size_t len, off_t offset);
-
-/**
- * Write PCI config space.
- *
- * @param device
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- * @param buf
- *   A data buffer containing the bytes should be written
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into PCI config space
- */
-int rte_pci_write_config(const struct rte_pci_device *device,
-		const void *buf, size_t len, off_t offset);
-
-/**
- * A structure used to access io resources for a pci device.
- * rte_pci_ioport is arch, os, driver specific, and should not be used outside
- * of pci ioport api.
- */
-struct rte_pci_ioport {
-	struct rte_pci_device *dev;
-	uint64_t base;
-	uint64_t len; /* only filled for memory mapped ports */
-};
-
-/**
- * Initialize a rte_pci_ioport object for a pci device io resource.
- *
- * This object is then used to gain access to those io resources (see below).
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use.
- * @param bar
- *   Index of the io pci resource we want to access.
- * @param p
- *   The rte_pci_ioport object to be initialized.
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p);
-
-/**
- * Release any resources used in a rte_pci_ioport object.
- *
- * @param p
- *   The rte_pci_ioport object to be uninitialized.
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_ioport_unmap(struct rte_pci_ioport *p);
-
-/**
- * Read from a io pci resource.
- *
- * @param p
- *   The rte_pci_ioport object from which we want to read.
- * @param data
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into the pci io resource.
- */
-void rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset);
-
-/**
- * Write to a io pci resource.
- *
- * @param p
- *   The rte_pci_ioport object to which we want to write.
- * @param data
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into the pci io resource.
- */
-void rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RTE_PCI_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 90bca4d..4abc886 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -64,10 +64,6 @@ endif
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
@@ -81,8 +77,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_errno.c
@@ -109,16 +103,12 @@ CFLAGS_eal_common_cpuflags.o := $(CPUFLAGS_LIST)
 
 CFLAGS_eal.o := -D_GNU_SOURCE
 CFLAGS_eal_interrupts.o := -D_GNU_SOURCE
-CFLAGS_eal_vfio_mp_sync.o := -D_GNU_SOURCE
 CFLAGS_eal_timer.o := -D_GNU_SOURCE
 CFLAGS_eal_lcore.o := -D_GNU_SOURCE
 CFLAGS_eal_thread.o := -D_GNU_SOURCE
 CFLAGS_eal_log.o := -D_GNU_SOURCE
 CFLAGS_eal_common_log.o := -D_GNU_SOURCE
 CFLAGS_eal_hugepage_info.o := -D_GNU_SOURCE
-CFLAGS_eal_pci.o := -D_GNU_SOURCE
-CFLAGS_eal_pci_uio.o := -D_GNU_SOURCE
-CFLAGS_eal_pci_vfio.o := -D_GNU_SOURCE
 CFLAGS_eal_common_whitelist.o := -D_GNU_SOURCE
 CFLAGS_eal_common_options.o := -D_GNU_SOURCE
 CFLAGS_eal_common_thread.o := -D_GNU_SOURCE
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 48f12f4..f72da15 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -71,7 +71,6 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_bus.h>
-#include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_version.h>
diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
index 3e9ac41..0bebf00 100644
--- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
@@ -60,7 +60,6 @@
 #include <rte_branch_prediction.h>
 #include <rte_debug.h>
 #include <rte_log.h>
-#include <rte_pci.h>
 #include <rte_malloc.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
deleted file mode 100644
index 8951ce7..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ /dev/null
@@ -1,722 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <dirent.h>
-
-#include <rte_log.h>
-#include <rte_bus.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-#include <rte_devargs.h>
-#include <rte_memcpy.h>
-
-#include "eal_filesystem.h"
-#include "eal_private.h"
-#include "eal_pci_init.h"
-
-/**
- * @file
- * PCI probing under linux
- *
- * This code is used to simulate a PCI probe by parsing information in sysfs.
- * When a registered device matches a driver, it is then initialized with
- * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
- */
-
-extern struct rte_pci_bus rte_pci_bus;
-
-static int
-pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
-{
-	int count;
-	char path[PATH_MAX];
-	char *name;
-
-	if (!filename || !dri_name)
-		return -1;
-
-	count = readlink(filename, path, PATH_MAX);
-	if (count >= PATH_MAX)
-		return -1;
-
-	/* For device does not have a driver */
-	if (count < 0)
-		return 1;
-
-	path[count] = '\0';
-
-	name = strrchr(path, '/');
-	if (name) {
-		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
-		return 0;
-	}
-
-	return -1;
-}
-
-/* Map pci device */
-int
-rte_pci_map_device(struct rte_pci_device *dev)
-{
-	int ret = -1;
-
-	/* try mapping the NIC resources using VFIO if it exists */
-	switch (dev->kdrv) {
-	case RTE_KDRV_VFIO:
-#ifdef VFIO_PRESENT
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_map_resource(dev);
-#endif
-		break;
-	case RTE_KDRV_IGB_UIO:
-	case RTE_KDRV_UIO_GENERIC:
-		if (rte_eal_using_phys_addrs()) {
-			/* map resources for devices that use uio */
-			ret = pci_uio_map_resource(dev);
-		}
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		ret = 1;
-		break;
-	}
-
-	return ret;
-}
-
-/* Unmap pci device */
-void
-rte_pci_unmap_device(struct rte_pci_device *dev)
-{
-	/* try unmapping the NIC resources using VFIO if it exists */
-	switch (dev->kdrv) {
-	case RTE_KDRV_VFIO:
-#ifdef VFIO_PRESENT
-		if (pci_vfio_is_enabled())
-			pci_vfio_unmap_resource(dev);
-#endif
-		break;
-	case RTE_KDRV_IGB_UIO:
-	case RTE_KDRV_UIO_GENERIC:
-		/* unmap resources for devices that use uio */
-		pci_uio_unmap_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		break;
-	}
-}
-
-void *
-pci_find_max_end_va(void)
-{
-	const struct rte_memseg *seg = rte_eal_get_physmem_layout();
-	const struct rte_memseg *last = seg;
-	unsigned i = 0;
-
-	for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
-		if (seg->addr == NULL)
-			break;
-
-		if (seg->addr > last->addr)
-			last = seg;
-
-	}
-	return RTE_PTR_ADD(last->addr, last->len);
-}
-
-/* parse one line of the "resource" sysfs file (note that the 'line'
- * string is modified)
- */
-int
-pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
-	uint64_t *end_addr, uint64_t *flags)
-{
-	union pci_resource_info {
-		struct {
-			char *phys_addr;
-			char *end_addr;
-			char *flags;
-		};
-		char *ptrs[PCI_RESOURCE_FMT_NVAL];
-	} res_info;
-
-	if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
-		RTE_LOG(ERR, EAL,
-			"%s(): bad resource format\n", __func__);
-		return -1;
-	}
-	errno = 0;
-	*phys_addr = strtoull(res_info.phys_addr, NULL, 16);
-	*end_addr = strtoull(res_info.end_addr, NULL, 16);
-	*flags = strtoull(res_info.flags, NULL, 16);
-	if (errno != 0) {
-		RTE_LOG(ERR, EAL,
-			"%s(): bad resource format\n", __func__);
-		return -1;
-	}
-
-	return 0;
-}
-
-/* parse the "resource" sysfs file */
-static int
-pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
-{
-	FILE *f;
-	char buf[BUFSIZ];
-	int i;
-	uint64_t phys_addr, end_addr, flags;
-
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
-		return -1;
-	}
-
-	for (i = 0; i<PCI_MAX_RESOURCE; i++) {
-
-		if (fgets(buf, sizeof(buf), f) == NULL) {
-			RTE_LOG(ERR, EAL,
-				"%s(): cannot read resource\n", __func__);
-			goto error;
-		}
-		if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
-				&end_addr, &flags) < 0)
-			goto error;
-
-		if (flags & IORESOURCE_MEM) {
-			dev->mem_resource[i].phys_addr = phys_addr;
-			dev->mem_resource[i].len = end_addr - phys_addr + 1;
-			/* not mapped for now */
-			dev->mem_resource[i].addr = NULL;
-		}
-	}
-	fclose(f);
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
-}
-
-/* Scan one pci sysfs entry, and fill the devices list from it. */
-static int
-pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
-{
-	char filename[PATH_MAX];
-	unsigned long tmp;
-	struct rte_pci_device *dev;
-	char driver[PATH_MAX];
-	int ret;
-
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL)
-		return -1;
-
-	memset(dev, 0, sizeof(*dev));
-	dev->addr = *addr;
-
-	/* get vendor id */
-	snprintf(filename, sizeof(filename), "%s/vendor", dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.vendor_id = (uint16_t)tmp;
-
-	/* get device id */
-	snprintf(filename, sizeof(filename), "%s/device", dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.device_id = (uint16_t)tmp;
-
-	/* get subsystem_vendor id */
-	snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.subsystem_vendor_id = (uint16_t)tmp;
-
-	/* get subsystem_device id */
-	snprintf(filename, sizeof(filename), "%s/subsystem_device",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.subsystem_device_id = (uint16_t)tmp;
-
-	/* get class_id */
-	snprintf(filename, sizeof(filename), "%s/class",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	/* the least 24 bits are valid: class, subclass, program interface */
-	dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
-
-	/* get max_vfs */
-	dev->max_vfs = 0;
-	snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
-	if (!access(filename, F_OK) &&
-	    eal_parse_sysfs_value(filename, &tmp) == 0)
-		dev->max_vfs = (uint16_t)tmp;
-	else {
-		/* for non igb_uio driver, need kernel version >= 3.8 */
-		snprintf(filename, sizeof(filename),
-			 "%s/sriov_numvfs", dirname);
-		if (!access(filename, F_OK) &&
-		    eal_parse_sysfs_value(filename, &tmp) == 0)
-			dev->max_vfs = (uint16_t)tmp;
-	}
-
-	/* get numa node, default to 0 if not present */
-	snprintf(filename, sizeof(filename), "%s/numa_node",
-		 dirname);
-
-	if (access(filename, F_OK) != -1) {
-		if (eal_parse_sysfs_value(filename, &tmp) == 0)
-			dev->device.numa_node = tmp;
-		else
-			dev->device.numa_node = -1;
-	} else {
-		dev->device.numa_node = 0;
-	}
-
-	pci_name_set(dev);
-
-	/* parse resources */
-	snprintf(filename, sizeof(filename), "%s/resource", dirname);
-	if (pci_parse_sysfs_resource(filename, dev) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
-		free(dev);
-		return -1;
-	}
-
-	/* parse driver */
-	snprintf(filename, sizeof(filename), "%s/driver", dirname);
-	ret = pci_get_kernel_driver_by_path(filename, driver);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
-		free(dev);
-		return -1;
-	}
-
-	if (!ret) {
-		if (!strcmp(driver, "vfio-pci"))
-			dev->kdrv = RTE_KDRV_VFIO;
-		else if (!strcmp(driver, "igb_uio"))
-			dev->kdrv = RTE_KDRV_IGB_UIO;
-		else if (!strcmp(driver, "uio_pci_generic"))
-			dev->kdrv = RTE_KDRV_UIO_GENERIC;
-		else
-			dev->kdrv = RTE_KDRV_UNKNOWN;
-	} else
-		dev->kdrv = RTE_KDRV_NONE;
-
-	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-		rte_pci_add_device(dev);
-	} else {
-		struct rte_pci_device *dev2;
-		int ret;
-
-		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
-			if (ret > 0)
-				continue;
-
-			if (ret < 0) {
-				rte_pci_insert_device(dev2, dev);
-			} else { /* already registered */
-				dev2->kdrv = dev->kdrv;
-				dev2->max_vfs = dev->max_vfs;
-				pci_name_set(dev2);
-				memmove(dev2->mem_resource, dev->mem_resource,
-					sizeof(dev->mem_resource));
-				free(dev);
-			}
-			return 0;
-		}
-
-		rte_pci_add_device(dev);
-	}
-
-	return 0;
-}
-
-int
-pci_update_device(const struct rte_pci_addr *addr)
-{
-	char filename[PATH_MAX];
-
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
-		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
-		 addr->function);
-
-	return pci_scan_one(filename, addr);
-}
-
-/*
- * split up a pci address into its constituent parts.
- */
-static int
-parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
-{
-	/* first split on ':' */
-	union splitaddr {
-		struct {
-			char *domain;
-			char *bus;
-			char *devid;
-			char *function;
-		};
-		char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
-	} splitaddr;
-
-	char *buf_copy = strndup(buf, bufsize);
-	if (buf_copy == NULL)
-		return -1;
-
-	if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
-			!= PCI_FMT_NVAL - 1)
-		goto error;
-	/* final split is on '.' between devid and function */
-	splitaddr.function = strchr(splitaddr.devid,'.');
-	if (splitaddr.function == NULL)
-		goto error;
-	*splitaddr.function++ = '\0';
-
-	/* now convert to int values */
-	errno = 0;
-	addr->domain = strtoul(splitaddr.domain, NULL, 16);
-	addr->bus = strtoul(splitaddr.bus, NULL, 16);
-	addr->devid = strtoul(splitaddr.devid, NULL, 16);
-	addr->function = strtoul(splitaddr.function, NULL, 10);
-	if (errno != 0)
-		goto error;
-
-	free(buf_copy); /* free the copy made with strdup */
-	return 0;
-error:
-	free(buf_copy);
-	return -1;
-}
-
-/*
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- */
-int
-rte_pci_scan(void)
-{
-	struct dirent *e;
-	DIR *dir;
-	char dirname[PATH_MAX];
-	struct rte_pci_addr addr;
-
-	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
-		return 0;
-
-	dir = opendir(pci_get_sysfs_path());
-	if (dir == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
-			__func__, strerror(errno));
-		return -1;
-	}
-
-	while ((e = readdir(dir)) != NULL) {
-		if (e->d_name[0] == '.')
-			continue;
-
-		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
-			continue;
-
-		snprintf(dirname, sizeof(dirname), "%s/%s",
-				pci_get_sysfs_path(), e->d_name);
-
-		if (pci_scan_one(dirname, &addr) < 0)
-			goto error;
-	}
-	closedir(dir);
-	return 0;
-
-error:
-	closedir(dir);
-	return -1;
-}
-
-/* Read PCI config space. */
-int rte_pci_read_config(const struct rte_pci_device *device,
-		void *buf, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &device->intr_handle;
-
-	switch (intr_handle->type) {
-	case RTE_INTR_HANDLE_UIO:
-	case RTE_INTR_HANDLE_UIO_INTX:
-		return pci_uio_read_config(intr_handle, buf, len, offset);
-
-#ifdef VFIO_PRESENT
-	case RTE_INTR_HANDLE_VFIO_MSIX:
-	case RTE_INTR_HANDLE_VFIO_MSI:
-	case RTE_INTR_HANDLE_VFIO_LEGACY:
-		return pci_vfio_read_config(intr_handle, buf, len, offset);
-#endif
-	default:
-		RTE_LOG(ERR, EAL,
-			"Unknown handle type of fd %d\n",
-					intr_handle->fd);
-		return -1;
-	}
-}
-
-/* Write PCI config space. */
-int rte_pci_write_config(const struct rte_pci_device *device,
-		const void *buf, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &device->intr_handle;
-
-	switch (intr_handle->type) {
-	case RTE_INTR_HANDLE_UIO:
-	case RTE_INTR_HANDLE_UIO_INTX:
-		return pci_uio_write_config(intr_handle, buf, len, offset);
-
-#ifdef VFIO_PRESENT
-	case RTE_INTR_HANDLE_VFIO_MSIX:
-	case RTE_INTR_HANDLE_VFIO_MSI:
-	case RTE_INTR_HANDLE_VFIO_LEGACY:
-		return pci_vfio_write_config(intr_handle, buf, len, offset);
-#endif
-	default:
-		RTE_LOG(ERR, EAL,
-			"Unknown handle type of fd %d\n",
-					intr_handle->fd);
-		return -1;
-	}
-}
-
-#if defined(RTE_ARCH_X86)
-static int
-pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
-		struct rte_pci_ioport *p)
-{
-	uint16_t start, end;
-	FILE *fp;
-	char *line = NULL;
-	char pci_id[16];
-	int found = 0;
-	size_t linesz;
-
-	snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
-		 dev->addr.domain, dev->addr.bus,
-		 dev->addr.devid, dev->addr.function);
-
-	fp = fopen("/proc/ioports", "r");
-	if (fp == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);
-		return -1;
-	}
-
-	while (getdelim(&line, &linesz, '\n', fp) > 0) {
-		char *ptr = line;
-		char *left;
-		int n;
-
-		n = strcspn(ptr, ":");
-		ptr[n] = 0;
-		left = &ptr[n + 1];
-
-		while (*left && isspace(*left))
-			left++;
-
-		if (!strncmp(left, pci_id, strlen(pci_id))) {
-			found = 1;
-
-			while (*ptr && isspace(*ptr))
-				ptr++;
-
-			sscanf(ptr, "%04hx-%04hx", &start, &end);
-
-			break;
-		}
-	}
-
-	free(line);
-	fclose(fp);
-
-	if (!found)
-		return -1;
-
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	p->base = start;
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
-
-	return 0;
-}
-#endif
-
-int
-rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p)
-{
-	int ret = -1;
-
-	switch (dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_ioport_map(dev, bar, p);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		ret = pci_uio_ioport_map(dev, bar, p);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-#if defined(RTE_ARCH_X86)
-		ret = pci_ioport_map(dev, bar, p);
-#else
-		ret = pci_uio_ioport_map(dev, bar, p);
-#endif
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		ret = pci_ioport_map(dev, bar, p);
-#endif
-		break;
-	default:
-		break;
-	}
-
-	if (!ret)
-		p->dev = dev;
-
-	return ret;
-}
-
-void
-rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		pci_vfio_ioport_read(p, data, len, offset);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		pci_uio_ioport_read(p, data, len, offset);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-void
-rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		pci_vfio_ioport_write(p, data, len, offset);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		pci_uio_ioport_write(p, data, len, offset);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-int
-rte_pci_ioport_unmap(struct rte_pci_ioport *p)
-{
-	int ret = -1;
-
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_ioport_unmap(p);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		ret = pci_uio_ioport_unmap(p);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-#if defined(RTE_ARCH_X86)
-		ret = 0;
-#else
-		ret = pci_uio_ioport_unmap(p);
-#endif
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		ret = 0;
-#endif
-		break;
-	default:
-		break;
-	}
-
-	return ret;
-}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
deleted file mode 100644
index ae2980d..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_init.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef EAL_PCI_INIT_H_
-#define EAL_PCI_INIT_H_
-
-#include "eal_vfio.h"
-
-/** IO resource type: */
-#define IORESOURCE_IO         0x00000100
-#define IORESOURCE_MEM        0x00000200
-
-/*
- * Helper function to map PCI resources right after hugepages in virtual memory
- */
-extern void *pci_map_addr;
-void *pci_find_max_end_va(void);
-
-/* parse one line of the "resource" sysfs file (note that the 'line'
- * string is modified)
- */
-int pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
-	uint64_t *end_addr, uint64_t *flags);
-
-int pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res);
-void pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res);
-int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx);
-
-int pci_uio_read_config(const struct rte_intr_handle *intr_handle,
-			void *buf, size_t len, off_t offs);
-int pci_uio_write_config(const struct rte_intr_handle *intr_handle,
-			 const void *buf, size_t len, off_t offs);
-
-int pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		       struct rte_pci_ioport *p);
-void pci_uio_ioport_read(struct rte_pci_ioport *p,
-			 void *data, size_t len, off_t offset);
-void pci_uio_ioport_write(struct rte_pci_ioport *p,
-			  const void *data, size_t len, off_t offset);
-int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
-
-#ifdef VFIO_PRESENT
-
-/* access config space */
-int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
-			 void *buf, size_t len, off_t offs);
-int pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
-			  const void *buf, size_t len, off_t offs);
-
-int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
-		        struct rte_pci_ioport *p);
-void pci_vfio_ioport_read(struct rte_pci_ioport *p,
-			  void *data, size_t len, off_t offset);
-void pci_vfio_ioport_write(struct rte_pci_ioport *p,
-			   const void *data, size_t len, off_t offset);
-int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
-
-/* map/unmap VFIO resource prototype */
-int pci_vfio_map_resource(struct rte_pci_device *dev);
-int pci_vfio_unmap_resource(struct rte_pci_device *dev);
-
-#endif
-
-#endif /* EAL_PCI_INIT_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
deleted file mode 100644
index fa10329..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/sysmacros.h>
-#include <linux/pci_regs.h>
-
-#if defined(RTE_ARCH_X86)
-#include <sys/io.h>
-#endif
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-
-void *pci_map_addr = NULL;
-
-#define OFF_MAX              ((uint64_t)(off_t)-1)
-
-int
-pci_uio_read_config(const struct rte_intr_handle *intr_handle,
-		    void *buf, size_t len, off_t offset)
-{
-	return pread(intr_handle->uio_cfg_fd, buf, len, offset);
-}
-
-int
-pci_uio_write_config(const struct rte_intr_handle *intr_handle,
-		     const void *buf, size_t len, off_t offset)
-{
-	return pwrite(intr_handle->uio_cfg_fd, buf, len, offset);
-}
-
-static int
-pci_uio_set_bus_master(int dev_fd)
-{
-	uint16_t reg;
-	int ret;
-
-	ret = pread(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL,
-			"Cannot read command from PCI config space!\n");
-		return -1;
-	}
-
-	/* return if bus mastering is already on */
-	if (reg & PCI_COMMAND_MASTER)
-		return 0;
-
-	reg |= PCI_COMMAND_MASTER;
-
-	ret = pwrite(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL,
-			"Cannot write command to PCI config space!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-static int
-pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
-{
-	FILE *f;
-	char filename[PATH_MAX];
-	int ret;
-	unsigned major, minor;
-	dev_t dev;
-
-	/* get the name of the sysfs file that contains the major and minor
-	 * of the uio device and read its content */
-	snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path);
-
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n",
-			__func__);
-		return -1;
-	}
-
-	ret = fscanf(f, "%u:%u", &major, &minor);
-	if (ret != 2) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n",
-			__func__);
-		fclose(f);
-		return -1;
-	}
-	fclose(f);
-
-	/* create the char device "mknod /dev/uioX c major minor" */
-	snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
-	dev = makedev(major, minor);
-	ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
-	if (ret != 0) {
-		RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
-			__func__, strerror(errno));
-		return -1;
-	}
-
-	return ret;
-}
-
-/*
- * Return the uioX char device used for a pci device. On success, return
- * the UIO number and fill dstbuf string with the path of the device in
- * sysfs. On error, return a negative value. In this case dstbuf is
- * invalid.
- */
-static int
-pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
-			   unsigned int buflen, int create)
-{
-	struct rte_pci_addr *loc = &dev->addr;
-	unsigned int uio_num;
-	struct dirent *e;
-	DIR *dir;
-	char dirname[PATH_MAX];
-
-	/* depending on kernel version, uio can be located in uio/uioX
-	 * or uio:uioX */
-
-	snprintf(dirname, sizeof(dirname),
-			"%s/" PCI_PRI_FMT "/uio", pci_get_sysfs_path(),
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	dir = opendir(dirname);
-	if (dir == NULL) {
-		/* retry with the parent directory */
-		snprintf(dirname, sizeof(dirname),
-				"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
-				loc->domain, loc->bus, loc->devid, loc->function);
-		dir = opendir(dirname);
-
-		if (dir == NULL) {
-			RTE_LOG(ERR, EAL, "Cannot opendir %s\n", dirname);
-			return -1;
-		}
-	}
-
-	/* take the first file starting with "uio" */
-	while ((e = readdir(dir)) != NULL) {
-		/* format could be uio%d ...*/
-		int shortprefix_len = sizeof("uio") - 1;
-		/* ... or uio:uio%d */
-		int longprefix_len = sizeof("uio:uio") - 1;
-		char *endptr;
-
-		if (strncmp(e->d_name, "uio", 3) != 0)
-			continue;
-
-		/* first try uio%d */
-		errno = 0;
-		uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
-		if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
-			snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
-			break;
-		}
-
-		/* then try uio:uio%d */
-		errno = 0;
-		uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
-		if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
-			snprintf(dstbuf, buflen, "%s/uio:uio%u", dirname, uio_num);
-			break;
-		}
-	}
-	closedir(dir);
-
-	/* No uio resource found */
-	if (e == NULL)
-		return -1;
-
-	/* create uio device if we've been asked to */
-	if (internal_config.create_uio_dev && create &&
-			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
-		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
-
-	return uio_num;
-}
-
-void
-pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res)
-{
-	rte_free(uio_res);
-
-	if (dev->intr_handle.uio_cfg_fd >= 0) {
-		close(dev->intr_handle.uio_cfg_fd);
-		dev->intr_handle.uio_cfg_fd = -1;
-	}
-	if (dev->intr_handle.fd >= 0) {
-		close(dev->intr_handle.fd);
-		dev->intr_handle.fd = -1;
-		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	}
-}
-
-int
-pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res)
-{
-	char dirname[PATH_MAX];
-	char cfgname[PATH_MAX];
-	char devname[PATH_MAX]; /* contains the /dev/uioX */
-	int uio_num;
-	struct rte_pci_addr *loc;
-
-	loc = &dev->addr;
-
-	/* find uio resource */
-	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 1);
-	if (uio_num < 0) {
-		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
-				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
-		return 1;
-	}
-	snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
-
-	/* save fd if in primary process */
-	dev->intr_handle.fd = open(devname, O_RDWR);
-	if (dev->intr_handle.fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			devname, strerror(errno));
-		goto error;
-	}
-
-	snprintf(cfgname, sizeof(cfgname),
-			"/sys/class/uio/uio%u/device/config", uio_num);
-	dev->intr_handle.uio_cfg_fd = open(cfgname, O_RDWR);
-	if (dev->intr_handle.uio_cfg_fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			cfgname, strerror(errno));
-		goto error;
-	}
-
-	if (dev->kdrv == RTE_KDRV_IGB_UIO)
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-	else {
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
-
-		/* set bus master that is not done by uio_pci_generic */
-		if (pci_uio_set_bus_master(dev->intr_handle.uio_cfg_fd)) {
-			RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
-			goto error;
-		}
-	}
-
-	/* allocate the mapping details for secondary processes*/
-	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
-	if (*uio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto error;
-	}
-
-	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
-	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
-
-	return 0;
-
-error:
-	pci_uio_free_resource(dev, *uio_res);
-	return -1;
-}
-
-int
-pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx)
-{
-	int fd;
-	char devname[PATH_MAX];
-	void *mapaddr;
-	struct rte_pci_addr *loc;
-	struct pci_map *maps;
-
-	loc = &dev->addr;
-	maps = uio_res->maps;
-
-	/* update devname for mmap  */
-	snprintf(devname, sizeof(devname),
-			"%s/" PCI_PRI_FMT "/resource%d",
-			pci_get_sysfs_path(),
-			loc->domain, loc->bus, loc->devid,
-			loc->function, res_idx);
-
-	/* allocate memory to keep path */
-	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
-	if (maps[map_idx].path == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
-				strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * open resource file, to mmap it
-	 */
-	fd = open(devname, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				devname, strerror(errno));
-		goto error;
-	}
-
-	/* try mapping somewhere close to the end of hugepages */
-	if (pci_map_addr == NULL)
-		pci_map_addr = pci_find_max_end_va();
-
-	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
-			(size_t)dev->mem_resource[res_idx].len, 0);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		goto error;
-
-	pci_map_addr = RTE_PTR_ADD(mapaddr,
-			(size_t)dev->mem_resource[res_idx].len);
-
-	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
-	maps[map_idx].size = dev->mem_resource[res_idx].len;
-	maps[map_idx].addr = mapaddr;
-	maps[map_idx].offset = 0;
-	strcpy(maps[map_idx].path, devname);
-	dev->mem_resource[res_idx].addr = mapaddr;
-
-	return 0;
-
-error:
-	rte_free(maps[map_idx].path);
-	return -1;
-}
-
-#if defined(RTE_ARCH_X86)
-int
-pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		   struct rte_pci_ioport *p)
-{
-	char dirname[PATH_MAX];
-	char filename[PATH_MAX];
-	int uio_num;
-	unsigned long start;
-
-	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 0);
-	if (uio_num < 0)
-		return -1;
-
-	/* get portio start */
-	snprintf(filename, sizeof(filename),
-		 "%s/portio/port%d/start", dirname, bar);
-	if (eal_parse_sysfs_value(filename, &start) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
-			__func__);
-		return -1;
-	}
-	/* ensure we don't get anything funny here, read/write will cast to
-	 * uin16_t */
-	if (start > UINT16_MAX)
-		return -1;
-
-	/* FIXME only for primary process ? */
-	if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {
-
-		snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
-		dev->intr_handle.fd = open(filename, O_RDWR);
-		if (dev->intr_handle.fd < 0) {
-			RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				filename, strerror(errno));
-			return -1;
-		}
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-	}
-
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);
-
-	p->base = start;
-	p->len = 0;
-	return 0;
-}
-#else
-int
-pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		   struct rte_pci_ioport *p)
-{
-	FILE *f;
-	char buf[BUFSIZ];
-	char filename[PATH_MAX];
-	uint64_t phys_addr, end_addr, flags;
-	int fd, i;
-	void *addr;
-
-	/* open and read addresses of the corresponding resource in sysfs */
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
-		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
-		dev->addr.devid, dev->addr.function);
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",
-			strerror(errno));
-		return -1;
-	}
-	for (i = 0; i < bar + 1; i++) {
-		if (fgets(buf, sizeof(buf), f) == NULL) {
-			RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");
-			goto error;
-		}
-	}
-	if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
-			&end_addr, &flags) < 0)
-		goto error;
-	if ((flags & IORESOURCE_IO) == 0) {
-		RTE_LOG(ERR, EAL, "BAR %d is not an IO resource\n", bar);
-		goto error;
-	}
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
-		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
-		dev->addr.devid, dev->addr.function, bar);
-
-	/* mmap the pci resource */
-	fd = open(filename, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
-			strerror(errno));
-		goto error;
-	}
-	addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
-		MAP_SHARED, fd, 0);
-	close(fd);
-	if (addr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s\n",
-			strerror(errno));
-		goto error;
-	}
-
-	/* strangely, the base address is mmap addr + phys_addr */
-	p->base = (uintptr_t)addr + phys_addr;
-	p->len = end_addr + 1;
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"\n", p->base);
-	fclose(f);
-
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
-}
-#endif
-
-void
-pci_uio_ioport_read(struct rte_pci_ioport *p,
-		    void *data, size_t len, off_t offset)
-{
-	uint8_t *d;
-	int size;
-	uintptr_t reg = p->base + offset;
-
-	for (d = data; len > 0; d += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-#if defined(RTE_ARCH_X86)
-			*(uint32_t *)d = inl(reg);
-#else
-			*(uint32_t *)d = *(volatile uint32_t *)reg;
-#endif
-		} else if (len >= 2) {
-			size = 2;
-#if defined(RTE_ARCH_X86)
-			*(uint16_t *)d = inw(reg);
-#else
-			*(uint16_t *)d = *(volatile uint16_t *)reg;
-#endif
-		} else {
-			size = 1;
-#if defined(RTE_ARCH_X86)
-			*d = inb(reg);
-#else
-			*d = *(volatile uint8_t *)reg;
-#endif
-		}
-	}
-}
-
-void
-pci_uio_ioport_write(struct rte_pci_ioport *p,
-		     const void *data, size_t len, off_t offset)
-{
-	const uint8_t *s;
-	int size;
-	uintptr_t reg = p->base + offset;
-
-	for (s = data; len > 0; s += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-#if defined(RTE_ARCH_X86)
-			outl_p(*(const uint32_t *)s, reg);
-#else
-			*(volatile uint32_t *)reg = *(const uint32_t *)s;
-#endif
-		} else if (len >= 2) {
-			size = 2;
-#if defined(RTE_ARCH_X86)
-			outw_p(*(const uint16_t *)s, reg);
-#else
-			*(volatile uint16_t *)reg = *(const uint16_t *)s;
-#endif
-		} else {
-			size = 1;
-#if defined(RTE_ARCH_X86)
-			outb_p(*s, reg);
-#else
-			*(volatile uint8_t *)reg = *s;
-#endif
-		}
-	}
-}
-
-int
-pci_uio_ioport_unmap(struct rte_pci_ioport *p)
-{
-#if defined(RTE_ARCH_X86)
-	RTE_SET_USED(p);
-	/* FIXME close intr fd ? */
-	return 0;
-#else
-	return munmap((void *)(uintptr_t)p->base, p->len);
-#endif
-}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
deleted file mode 100644
index aa9d96e..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <fcntl.h>
-#include <linux/pci_regs.h>
-#include <sys/eventfd.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <stdbool.h>
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-#include "eal_vfio.h"
-#include "eal_private.h"
-
-/**
- * @file
- * PCI probing under linux (VFIO version)
- *
- * This code tries to determine if the PCI device is bound to VFIO driver,
- * and initialize it (map BARs, set up interrupts) if that's the case.
- *
- * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
- */
-
-#ifdef VFIO_PRESENT
-
-#define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
-#define PAGE_MASK   (~(PAGE_SIZE - 1))
-
-static struct rte_tailq_elem rte_vfio_tailq = {
-	.name = "VFIO_RESOURCE_LIST",
-};
-EAL_REGISTER_TAILQ(rte_vfio_tailq)
-
-int
-pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
-		    void *buf, size_t len, off_t offs)
-{
-	return pread64(intr_handle->vfio_dev_fd, buf, len,
-	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
-}
-
-int
-pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
-		    const void *buf, size_t len, off_t offs)
-{
-	return pwrite64(intr_handle->vfio_dev_fd, buf, len,
-	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
-}
-
-/* get PCI BAR number where MSI-X interrupts are */
-static int
-pci_vfio_get_msix_bar(int fd, int *msix_bar, uint32_t *msix_table_offset,
-		      uint32_t *msix_table_size)
-{
-	int ret;
-	uint32_t reg;
-	uint16_t flags;
-	uint8_t cap_id, cap_offset;
-
-	/* read PCI capability pointer from config space */
-	ret = pread64(fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_CAPABILITY_LIST);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
-				"config space!\n");
-		return -1;
-	}
-
-	/* we need first byte */
-	cap_offset = reg & 0xFF;
-
-	while (cap_offset) {
-
-		/* read PCI capability ID */
-		ret = pread64(fd, &reg, sizeof(reg),
-				VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-				cap_offset);
-		if (ret != sizeof(reg)) {
-			RTE_LOG(ERR, EAL, "Cannot read capability ID from PCI "
-					"config space!\n");
-			return -1;
-		}
-
-		/* we need first byte */
-		cap_id = reg & 0xFF;
-
-		/* if we haven't reached MSI-X, check next capability */
-		if (cap_id != PCI_CAP_ID_MSIX) {
-			ret = pread64(fd, &reg, sizeof(reg),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset);
-			if (ret != sizeof(reg)) {
-				RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
-						"config space!\n");
-				return -1;
-			}
-
-			/* we need second byte */
-			cap_offset = (reg & 0xFF00) >> 8;
-
-			continue;
-		}
-		/* else, read table offset */
-		else {
-			/* table offset resides in the next 4 bytes */
-			ret = pread64(fd, &reg, sizeof(reg),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset + 4);
-			if (ret != sizeof(reg)) {
-				RTE_LOG(ERR, EAL, "Cannot read table offset from PCI config "
-						"space!\n");
-				return -1;
-			}
-
-			ret = pread64(fd, &flags, sizeof(flags),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset + 2);
-			if (ret != sizeof(flags)) {
-				RTE_LOG(ERR, EAL, "Cannot read table flags from PCI config "
-						"space!\n");
-				return -1;
-			}
-
-			*msix_bar = reg & RTE_PCI_MSIX_TABLE_BIR;
-			*msix_table_offset = reg & RTE_PCI_MSIX_TABLE_OFFSET;
-			*msix_table_size = 16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE));
-
-			return 0;
-		}
-	}
-	return 0;
-}
-
-/* set PCI bus mastering */
-static int
-pci_vfio_set_bus_master(int dev_fd, bool op)
-{
-	uint16_t reg;
-	int ret;
-
-	ret = pread64(dev_fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n");
-		return -1;
-	}
-
-	if (op)
-		/* set the master bit */
-		reg |= PCI_COMMAND_MASTER;
-	else
-		reg &= ~(PCI_COMMAND_MASTER);
-
-	ret = pwrite64(dev_fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_COMMAND);
-
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-/* set up interrupt support (but not enable interrupts) */
-static int
-pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
-{
-	int i, ret, intr_idx;
-
-	/* default to invalid index */
-	intr_idx = VFIO_PCI_NUM_IRQS;
-
-	/* get interrupt type from internal config (MSI-X by default, can be
-	 * overridden from the command line
-	 */
-	switch (internal_config.vfio_intr_mode) {
-	case RTE_INTR_MODE_MSIX:
-		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
-		break;
-	case RTE_INTR_MODE_MSI:
-		intr_idx = VFIO_PCI_MSI_IRQ_INDEX;
-		break;
-	case RTE_INTR_MODE_LEGACY:
-		intr_idx = VFIO_PCI_INTX_IRQ_INDEX;
-		break;
-	/* don't do anything if we want to automatically determine interrupt type */
-	case RTE_INTR_MODE_NONE:
-		break;
-	default:
-		RTE_LOG(ERR, EAL, "  unknown default interrupt type!\n");
-		return -1;
-	}
-
-	/* start from MSI-X interrupt type */
-	for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) {
-		struct vfio_irq_info irq = { .argsz = sizeof(irq) };
-		int fd = -1;
-
-		/* skip interrupt modes we don't want */
-		if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE &&
-				i != intr_idx)
-			continue;
-
-		irq.index = i;
-
-		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  cannot get IRQ info, "
-					"error %i (%s)\n", errno, strerror(errno));
-			return -1;
-		}
-
-		/* if this vector cannot be used with eventfd, fail if we explicitly
-		 * specified interrupt type, otherwise continue */
-		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
-			if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE) {
-				RTE_LOG(ERR, EAL,
-						"  interrupt vector does not support eventfd!\n");
-				return -1;
-			} else
-				continue;
-		}
-
-		/* set up an eventfd for interrupts */
-		fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
-		if (fd < 0) {
-			RTE_LOG(ERR, EAL, "  cannot set up eventfd, "
-					"error %i (%s)\n", errno, strerror(errno));
-			return -1;
-		}
-
-		dev->intr_handle.fd = fd;
-		dev->intr_handle.vfio_dev_fd = vfio_dev_fd;
-
-		switch (i) {
-		case VFIO_PCI_MSIX_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSIX;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
-			break;
-		case VFIO_PCI_MSI_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSI;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
-			break;
-		case VFIO_PCI_INTX_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_LEGACY;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
-			break;
-		default:
-			RTE_LOG(ERR, EAL, "  unknown interrupt type!\n");
-			return -1;
-		}
-
-		return 0;
-	}
-
-	/* if we're here, we haven't found a suitable interrupt vector */
-	return -1;
-}
-
-/*
- * map the PCI resources of a PCI device in virtual memory (VFIO version).
- * primary and secondary processes follow almost exactly the same path
- */
-int
-pci_vfio_map_resource(struct rte_pci_device *dev)
-{
-	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
-	char pci_addr[PATH_MAX] = {0};
-	int vfio_dev_fd;
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret, msix_bar;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-
-	struct pci_map *maps;
-	uint32_t msix_table_offset = 0;
-	uint32_t msix_table_size = 0;
-	uint32_t ioport_bar;
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	if ((ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
-					&vfio_dev_fd, &device_info)))
-		return ret;
-
-	/* get MSI-X BAR, if any (we have to know where it is because we can't
-	 * easily mmap it when using VFIO) */
-	msix_bar = -1;
-	ret = pci_vfio_get_msix_bar(vfio_dev_fd, &msix_bar,
-				    &msix_table_offset, &msix_table_size);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "  %s cannot get MSI-X BAR number!\n", pci_addr);
-		close(vfio_dev_fd);
-		return -1;
-	}
-
-	/* if we're in a primary process, allocate vfio_res and get region info */
-	if (internal_config.process_type == RTE_PROC_PRIMARY) {
-		vfio_res = rte_zmalloc("VFIO_RES", sizeof(*vfio_res), 0);
-		if (vfio_res == NULL) {
-			RTE_LOG(ERR, EAL,
-				"%s(): cannot store uio mmap details\n", __func__);
-			close(vfio_dev_fd);
-			return -1;
-		}
-		memcpy(&vfio_res->pci_addr, &dev->addr, sizeof(vfio_res->pci_addr));
-
-		/* get number of registers (up to BAR5) */
-		vfio_res->nb_maps = RTE_MIN((int) device_info.num_regions,
-				VFIO_PCI_BAR5_REGION_INDEX + 1);
-	} else {
-		/* if we're in a secondary process, just find our tailq entry */
-		TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-			if (rte_eal_compare_pci_addr(&vfio_res->pci_addr,
-						     &dev->addr))
-				continue;
-			break;
-		}
-		/* if we haven't found our tailq entry, something's wrong */
-		if (vfio_res == NULL) {
-			RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
-					pci_addr);
-			close(vfio_dev_fd);
-			return -1;
-		}
-	}
-
-	/* map BARs */
-	maps = vfio_res->maps;
-
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-		struct vfio_region_info reg = { .argsz = sizeof(reg) };
-		void *bar_addr;
-		struct memreg {
-			unsigned long offset, size;
-		} memreg[2] = {};
-
-		reg.index = i;
-
-		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg);
-
-		if (ret) {
-			RTE_LOG(ERR, EAL, "  %s cannot get device region info "
-					"error %i (%s)\n", pci_addr, errno, strerror(errno));
-			close(vfio_dev_fd);
-			if (internal_config.process_type == RTE_PROC_PRIMARY)
-				rte_free(vfio_res);
-			return -1;
-		}
-
-		/* chk for io port region */
-		ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar),
-			      VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX)
-			      + PCI_BASE_ADDRESS_0 + i*4);
-
-		if (ret != sizeof(ioport_bar)) {
-			RTE_LOG(ERR, EAL,
-				"Cannot read command (%x) from config space!\n",
-				PCI_BASE_ADDRESS_0 + i*4);
-			return -1;
-		}
-
-		if (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) {
-			RTE_LOG(INFO, EAL,
-				"Ignore mapping IO port bar(%d) addr: %x\n",
-				 i, ioport_bar);
-			continue;
-		}
-
-		/* skip non-mmapable BARs */
-		if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0)
-			continue;
-
-		if (i == msix_bar) {
-			/*
-			 * VFIO will not let us map the MSI-X table,
-			 * but we can map around it.
-			 */
-			uint32_t table_start = msix_table_offset;
-			uint32_t table_end = table_start + msix_table_size;
-			table_end = (table_end + ~PAGE_MASK) & PAGE_MASK;
-			table_start &= PAGE_MASK;
-
-			if (table_start == 0 && table_end >= reg.size) {
-				/* Cannot map this BAR */
-				RTE_LOG(DEBUG, EAL, "Skipping BAR %d\n", i);
-				continue;
-			} else {
-				memreg[0].offset = reg.offset;
-				memreg[0].size = table_start;
-				memreg[1].offset = reg.offset + table_end;
-				memreg[1].size = reg.size - table_end;
-
-				RTE_LOG(DEBUG, EAL,
-					"Trying to map BAR %d that contains the MSI-X "
-					"table. Trying offsets: "
-					"0x%04lx:0x%04lx, 0x%04lx:0x%04lx\n", i,
-					memreg[0].offset, memreg[0].size,
-					memreg[1].offset, memreg[1].size);
-			}
-		} else {
-			memreg[0].offset = reg.offset;
-			memreg[0].size = reg.size;
-		}
-
-		/* try to figure out an address */
-		if (internal_config.process_type == RTE_PROC_PRIMARY) {
-			/* try mapping somewhere close to the end of hugepages */
-			if (pci_map_addr == NULL)
-				pci_map_addr = pci_find_max_end_va();
-
-			bar_addr = pci_map_addr;
-			pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
-		} else {
-			bar_addr = maps[i].addr;
-		}
-
-		/* reserve the address using an inaccessible mapping */
-		bar_addr = mmap(bar_addr, reg.size, 0, MAP_PRIVATE |
-				MAP_ANONYMOUS, -1, 0);
-		if (bar_addr != MAP_FAILED) {
-			void *map_addr = NULL;
-			if (memreg[0].size) {
-				/* actual map of first part */
-				map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
-							    memreg[0].offset,
-							    memreg[0].size,
-							    MAP_FIXED);
-			}
-
-			/* if there's a second part, try to map it */
-			if (map_addr != MAP_FAILED
-			    && memreg[1].offset && memreg[1].size) {
-				void *second_addr = RTE_PTR_ADD(bar_addr,
-								memreg[1].offset -
-								(uintptr_t)reg.offset);
-				map_addr = pci_map_resource(second_addr,
-							    vfio_dev_fd, memreg[1].offset,
-							    memreg[1].size,
-							    MAP_FIXED);
-			}
-
-			if (map_addr == MAP_FAILED || !map_addr) {
-				munmap(bar_addr, reg.size);
-				bar_addr = MAP_FAILED;
-			}
-		}
-
-		if (bar_addr == MAP_FAILED ||
-				(internal_config.process_type == RTE_PROC_SECONDARY &&
-						bar_addr != maps[i].addr)) {
-			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n", pci_addr, i,
-					strerror(errno));
-			close(vfio_dev_fd);
-			if (internal_config.process_type == RTE_PROC_PRIMARY)
-				rte_free(vfio_res);
-			return -1;
-		}
-
-		maps[i].addr = bar_addr;
-		maps[i].offset = reg.offset;
-		maps[i].size = reg.size;
-		maps[i].path = NULL; /* vfio doesn't have per-resource paths */
-		dev->mem_resource[i].addr = bar_addr;
-	}
-
-	/* if secondary process, do not set up interrupts */
-	if (internal_config.process_type == RTE_PROC_PRIMARY) {
-		if (pci_vfio_setup_interrupts(dev, vfio_dev_fd) != 0) {
-			RTE_LOG(ERR, EAL, "  %s error setting up interrupts!\n", pci_addr);
-			close(vfio_dev_fd);
-			rte_free(vfio_res);
-			return -1;
-		}
-
-		/* set bus mastering for the device */
-		if (pci_vfio_set_bus_master(vfio_dev_fd, true)) {
-			RTE_LOG(ERR, EAL, "  %s cannot set up bus mastering!\n", pci_addr);
-			close(vfio_dev_fd);
-			rte_free(vfio_res);
-			return -1;
-		}
-
-		/* Reset the device */
-		ioctl(vfio_dev_fd, VFIO_DEVICE_RESET);
-	}
-
-	if (internal_config.process_type == RTE_PROC_PRIMARY)
-		TAILQ_INSERT_TAIL(vfio_res_list, vfio_res, next);
-
-	return 0;
-}
-
-int
-pci_vfio_unmap_resource(struct rte_pci_device *dev)
-{
-	char pci_addr[PATH_MAX] = {0};
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list;
-
-	struct pci_map *maps;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-
-	if (close(dev->intr_handle.fd) < 0) {
-		RTE_LOG(INFO, EAL, "Error when closing eventfd file descriptor for %s\n",
-			pci_addr);
-		return -1;
-	}
-
-	if (pci_vfio_set_bus_master(dev->intr_handle.vfio_dev_fd, false)) {
-		RTE_LOG(ERR, EAL, "  %s cannot unset bus mastering for PCI device!\n",
-				pci_addr);
-		return -1;
-	}
-
-	ret = vfio_release_device(pci_get_sysfs_path(), pci_addr,
-				  dev->intr_handle.vfio_dev_fd);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot release device\n", __func__);
-		return ret;
-	}
-
-	vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-	/* Get vfio_res */
-	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-		if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
-			continue;
-		break;
-	}
-	/* if we haven't found our tailq entry, something's wrong */
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
-				pci_addr);
-		return -1;
-	}
-
-	/* unmap BARs */
-	maps = vfio_res->maps;
-
-	RTE_LOG(INFO, EAL, "Releasing pci mapped resource for %s\n",
-		pci_addr);
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-
-		/*
-		 * We do not need to be aware of MSI-X table BAR mappings as
-		 * when mapping. Just using current maps array is enough
-		 */
-		if (maps[i].addr) {
-			RTE_LOG(INFO, EAL, "Calling pci_unmap_resource for %s at %p\n",
-				pci_addr, maps[i].addr);
-			pci_unmap_resource(maps[i].addr, maps[i].size);
-		}
-	}
-
-	TAILQ_REMOVE(vfio_res_list, vfio_res, next);
-
-	return 0;
-}
-
-int
-pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
-		    struct rte_pci_ioport *p)
-{
-	if (bar < VFIO_PCI_BAR0_REGION_INDEX ||
-	    bar > VFIO_PCI_BAR5_REGION_INDEX) {
-		RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar);
-		return -1;
-	}
-
-	p->dev = dev;
-	p->base = VFIO_GET_REGION_ADDR(bar);
-	return 0;
-}
-
-void
-pci_vfio_ioport_read(struct rte_pci_ioport *p,
-		     void *data, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
-
-	if (pread64(intr_handle->vfio_dev_fd, data,
-		    len, p->base + offset) <= 0)
-		RTE_LOG(ERR, EAL,
-			"Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n",
-			VFIO_GET_REGION_IDX(p->base), (int)offset);
-}
-
-void
-pci_vfio_ioport_write(struct rte_pci_ioport *p,
-		      const void *data, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
-
-	if (pwrite64(intr_handle->vfio_dev_fd, data,
-		     len, p->base + offset) <= 0)
-		RTE_LOG(ERR, EAL,
-			"Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n",
-			VFIO_GET_REGION_IDX(p->base), (int)offset);
-}
-
-int
-pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
-{
-	RTE_SET_USED(p);
-	return -1;
-}
-
-int
-pci_vfio_enable(void)
-{
-	return vfio_enable("vfio_pci");
-}
-
-int
-pci_vfio_is_enabled(void)
-{
-	return vfio_is_enabled("vfio_pci");
-}
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
deleted file mode 100644
index 7e8095c..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <pthread.h>
-
-/* sys/un.h with __USE_MISC uses strlen, which is unsafe */
-#ifdef __USE_MISC
-#define REMOVED_USE_MISC
-#undef __USE_MISC
-#endif
-#include <sys/un.h>
-/* make sure we redefine __USE_MISC only if it was previously undefined */
-#ifdef REMOVED_USE_MISC
-#define __USE_MISC
-#undef REMOVED_USE_MISC
-#endif
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-#include "eal_thread.h"
-
-/**
- * @file
- * VFIO socket for communication between primary and secondary processes.
- *
- * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
- */
-
-#ifdef VFIO_PRESENT
-
-#define SOCKET_PATH_FMT "%s/.%s_mp_socket"
-#define CMSGLEN (CMSG_LEN(sizeof(int)))
-#define FD_TO_CMSGHDR(fd, chdr) \
-		do {\
-			(chdr).cmsg_len = CMSGLEN;\
-			(chdr).cmsg_level = SOL_SOCKET;\
-			(chdr).cmsg_type = SCM_RIGHTS;\
-			memcpy((chdr).__cmsg_data, &(fd), sizeof(fd));\
-		} while (0)
-#define CMSGHDR_TO_FD(chdr, fd) \
-			memcpy(&(fd), (chdr).__cmsg_data, sizeof(fd))
-
-static pthread_t socket_thread;
-static int mp_socket_fd;
-
-
-/* get socket path (/var/run if root, $HOME otherwise) */
-static void
-get_socket_path(char *buffer, int bufsz)
-{
-	const char *dir = "/var/run";
-	const char *home_dir = getenv("HOME");
-
-	if (getuid() != 0 && home_dir != NULL)
-		dir = home_dir;
-
-	/* use current prefix as file path */
-	snprintf(buffer, bufsz, SOCKET_PATH_FMT, dir,
-			internal_config.hugefile_prefix);
-}
-
-
-
-/*
- * data flow for socket comm protocol:
- * 1. client sends SOCKET_REQ_CONTAINER or SOCKET_REQ_GROUP
- * 1a. in case of SOCKET_REQ_GROUP, client also then sends group number
- * 2. server receives message
- * 2a. in case of invalid group, SOCKET_ERR is sent back to client
- * 2b. in case of unbound group, SOCKET_NO_FD is sent back to client
- * 2c. in case of valid group, SOCKET_OK is sent and immediately followed by fd
- *
- * in case of any error, socket is closed.
- */
-
-/* send a request, return -1 on error */
-int
-vfio_mp_sync_send_request(int socket, int req)
-{
-	struct msghdr hdr;
-	struct iovec iov;
-	int buf;
-	int ret;
-
-	memset(&hdr, 0, sizeof(hdr));
-
-	buf = req;
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-
-	ret = sendmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-	return 0;
-}
-
-/* receive a request and return it */
-int
-vfio_mp_sync_receive_request(int socket)
-{
-	int buf;
-	struct msghdr hdr;
-	struct iovec iov;
-	int ret, req;
-
-	memset(&hdr, 0, sizeof(hdr));
-
-	buf = SOCKET_ERR;
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-
-	ret = recvmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-
-	req = buf;
-
-	return req;
-}
-
-/* send OK in message, fd in control message */
-int
-vfio_mp_sync_send_fd(int socket, int fd)
-{
-	int buf;
-	struct msghdr hdr;
-	struct cmsghdr *chdr;
-	char chdr_buf[CMSGLEN];
-	struct iovec iov;
-	int ret;
-
-	chdr = (struct cmsghdr *) chdr_buf;
-	memset(chdr, 0, sizeof(chdr_buf));
-	memset(&hdr, 0, sizeof(hdr));
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-	hdr.msg_control = chdr;
-	hdr.msg_controllen = CMSGLEN;
-
-	buf = SOCKET_OK;
-	FD_TO_CMSGHDR(fd, *chdr);
-
-	ret = sendmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-	return 0;
-}
-
-/* receive OK in message, fd in control message */
-int
-vfio_mp_sync_receive_fd(int socket)
-{
-	int buf;
-	struct msghdr hdr;
-	struct cmsghdr *chdr;
-	char chdr_buf[CMSGLEN];
-	struct iovec iov;
-	int ret, req, fd;
-
-	buf = SOCKET_ERR;
-
-	chdr = (struct cmsghdr *) chdr_buf;
-	memset(chdr, 0, sizeof(chdr_buf));
-	memset(&hdr, 0, sizeof(hdr));
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-	hdr.msg_control = chdr;
-	hdr.msg_controllen = CMSGLEN;
-
-	ret = recvmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-
-	req = buf;
-
-	if (req != SOCKET_OK)
-		return -1;
-
-	CMSGHDR_TO_FD(*chdr, fd);
-
-	return fd;
-}
-
-/* connect socket_fd in secondary process to the primary process's socket */
-int
-vfio_mp_sync_connect_to_primary(void)
-{
-	struct sockaddr_un addr;
-	socklen_t sockaddr_len;
-	int socket_fd;
-
-	/* set up a socket */
-	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-	if (socket_fd < 0) {
-		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
-		return -1;
-	}
-
-	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
-	addr.sun_family = AF_UNIX;
-
-	sockaddr_len = sizeof(struct sockaddr_un);
-
-	if (connect(socket_fd, (struct sockaddr *) &addr, sockaddr_len) == 0)
-		return socket_fd;
-
-	/* if connect failed */
-	close(socket_fd);
-	return -1;
-}
-
-
-
-/*
- * socket listening thread for primary process
- */
-static __attribute__((noreturn)) void *
-vfio_mp_sync_thread(void __rte_unused * arg)
-{
-	int ret, fd, vfio_data;
-
-	/* wait for requests on the socket */
-	for (;;) {
-		int conn_sock;
-		struct sockaddr_un addr;
-		socklen_t sockaddr_len = sizeof(addr);
-
-		/* this is a blocking call */
-		conn_sock = accept(mp_socket_fd, (struct sockaddr *) &addr,
-				&sockaddr_len);
-
-		/* just restart on error */
-		if (conn_sock == -1)
-			continue;
-
-		/* set socket to linger after close */
-		struct linger l;
-		l.l_onoff = 1;
-		l.l_linger = 60;
-
-		if (setsockopt(conn_sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0)
-			RTE_LOG(WARNING, EAL, "Cannot set SO_LINGER option "
-					"on listen socket (%s)\n", strerror(errno));
-
-		ret = vfio_mp_sync_receive_request(conn_sock);
-
-		switch (ret) {
-		case SOCKET_REQ_CONTAINER:
-			fd = vfio_get_container_fd();
-			if (fd < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			else
-				vfio_mp_sync_send_fd(conn_sock, fd);
-			close(fd);
-			break;
-		case SOCKET_REQ_GROUP:
-			/* wait for group number */
-			vfio_data = vfio_mp_sync_receive_request(conn_sock);
-			if (vfio_data < 0) {
-				close(conn_sock);
-				continue;
-			}
-
-			fd = vfio_get_group_fd(vfio_data);
-
-			if (fd < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			/* if VFIO group exists but isn't bound to VFIO driver */
-			else if (fd == 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
-			/* if group exists and is bound to VFIO driver */
-			else {
-				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
-				vfio_mp_sync_send_fd(conn_sock, fd);
-			}
-			break;
-		case SOCKET_CLR_GROUP:
-			/* wait for group fd */
-			vfio_data = vfio_mp_sync_receive_request(conn_sock);
-			if (vfio_data < 0) {
-				close(conn_sock);
-				continue;
-			}
-
-			ret = clear_group(vfio_data);
-
-			if (ret < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
-			else
-				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
-			break;
-		default:
-			vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			break;
-		}
-		close(conn_sock);
-	}
-}
-
-static int
-vfio_mp_sync_socket_setup(void)
-{
-	int ret, socket_fd;
-	struct sockaddr_un addr;
-	socklen_t sockaddr_len;
-
-	/* set up a socket */
-	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-	if (socket_fd < 0) {
-		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
-		return -1;
-	}
-
-	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
-	addr.sun_family = AF_UNIX;
-
-	sockaddr_len = sizeof(struct sockaddr_un);
-
-	unlink(addr.sun_path);
-
-	ret = bind(socket_fd, (struct sockaddr *) &addr, sockaddr_len);
-	if (ret) {
-		RTE_LOG(ERR, EAL, "Failed to bind socket: %s!\n", strerror(errno));
-		close(socket_fd);
-		return -1;
-	}
-
-	ret = listen(socket_fd, 50);
-	if (ret) {
-		RTE_LOG(ERR, EAL, "Failed to listen: %s!\n", strerror(errno));
-		close(socket_fd);
-		return -1;
-	}
-
-	/* save the socket in local configuration */
-	mp_socket_fd = socket_fd;
-
-	return 0;
-}
-
-/*
- * set up a local socket and tell it to listen for incoming connections
- */
-int
-vfio_mp_sync_setup(void)
-{
-	int ret;
-	char thread_name[RTE_MAX_THREAD_NAME_LEN];
-
-	if (vfio_mp_sync_socket_setup() < 0) {
-		RTE_LOG(ERR, EAL, "Failed to set up local socket!\n");
-		return -1;
-	}
-
-	ret = pthread_create(&socket_thread, NULL,
-			vfio_mp_sync_thread, NULL);
-	if (ret) {
-		RTE_LOG(ERR, EAL,
-			"Failed to create thread for communication with secondary processes!\n");
-		close(mp_socket_fd);
-		return -1;
-	}
-
-	/* Set thread_name for aid in debugging. */
-	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "vfio-sync");
-	ret = rte_thread_setname(socket_thread, thread_name);
-	if (ret)
-		RTE_LOG(DEBUG, EAL,
-			"Failed to set thread name for secondary processes!\n");
-
-	return 0;
-}
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 18bce25..466dad3 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -174,21 +174,6 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_pci_detach;
-	rte_pci_dump;
-	rte_pci_ioport_map;
-	rte_pci_ioport_read;
-	rte_pci_ioport_unmap;
-	rte_pci_ioport_write;
-	rte_pci_map_device;
-	rte_pci_probe;
-	rte_pci_probe_one;
-	rte_pci_read_config;
-	rte_pci_register;
-	rte_pci_scan;
-	rte_pci_unmap_device;
-	rte_pci_unregister;
-	rte_pci_write_config;
 	rte_vdev_init;
 	rte_vdev_register;
 	rte_vdev_uninit;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 99cdd54..af7af0a 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1076,8 +1076,6 @@ TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
 	} \
 } while (0)
 
-#define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
-
 /**
  * l2 tunnel configuration.
  */
diff --git a/lib/librte_pci/Makefile b/lib/librte_pci/Makefile
new file mode 100644
index 0000000..fc2fadb
--- /dev/null
+++ b/lib/librte_pci/Makefile
@@ -0,0 +1,48 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_pci.a
+
+CFLAGS := -I$(SRCDIR)/include -I$(SRCDIR) $(CFLAGS)
+CFLAGS += $(WERROR_FLAGS) -O3
+
+EXPORT_MAP := rte_pci_version.map
+
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_PCI) += rte_pci.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI)-include += include/rte_pci.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
new file mode 100644
index 0000000..3858e80
--- /dev/null
+++ b/lib/librte_pci/include/rte_pci.h
@@ -0,0 +1,279 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_PCI_H_
+#define _RTE_PCI_H_
+
+/**
+ * @file
+ *
+ * RTE PCI Library
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+
+/** Formatting string for PCI device identifier: Ex: 0000:00:01.0 */
+#define PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+#define PCI_PRI_STR_SIZE sizeof("XXXXXXXX:XX:XX.X")
+
+/** Short formatting string, without domain, for PCI device: Ex: 00:01.0 */
+#define PCI_SHORT_PRI_FMT "%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+
+/** Nb. of values in PCI device identifier format string. */
+#define PCI_FMT_NVAL 4
+
+/** Nb. of values in PCI resource format. */
+#define PCI_RESOURCE_FMT_NVAL 3
+
+/** Maximum number of PCI resources. */
+#define PCI_MAX_RESOURCE 6
+
+/**
+ * A structure describing an ID for a PCI driver. Each driver provides a
+ * table of these IDs for each device that it supports.
+ */
+struct rte_pci_id {
+	uint32_t class_id;            /**< Class ID or RTE_CLASS_ANY_ID. */
+	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
+	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
+	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
+	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
+};
+
+/**
+ * A structure describing the location of a PCI device.
+ */
+struct rte_pci_addr {
+	uint32_t domain;                /**< Device domain */
+	uint8_t bus;                    /**< Device bus */
+	uint8_t devid;                  /**< Device ID */
+	uint8_t function;               /**< Device function. */
+};
+
+/** Any PCI device identifier (vendor, device, ...) */
+#define PCI_ANY_ID (0xffff)
+#define RTE_CLASS_ANY_ID (0xffffff)
+
+/**
+ * A structure describing a PCI mapping.
+ */
+struct pci_map {
+	void *addr;
+	char *path;
+	uint64_t offset;
+	uint64_t size;
+	uint64_t phaddr;
+};
+
+/**
+ * A structure describing a mapped PCI resource.
+ * For multi-process we need to reproduce all PCI mappings in secondary
+ * processes, so save them in a tailq.
+ */
+struct mapped_pci_resource {
+	TAILQ_ENTRY(mapped_pci_resource) next;
+
+	struct rte_pci_addr pci_addr;
+	char path[PATH_MAX];
+	int nb_maps;
+	struct pci_map maps[PCI_MAX_RESOURCE];
+};
+
+/** mapped pci device list */
+TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
+
+/**< Internal use only - Macro used by pci addr parsing functions **/
+#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
+do {                                                               \
+	unsigned long val;                                      \
+	char *end;                                              \
+	errno = 0;                                              \
+	val = strtoul((in), &end, 16);                          \
+	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
+		return -EINVAL;                                 \
+	(fd) = (typeof (fd))val;                                \
+	(in) = end + 1;                                         \
+} while(0)
+
+/**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided without
+ * a domain prefix (i.e. domain returned is always 0)
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned. Domain will always be
+ *	returned as 0
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	dev_addr->domain = 0;
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+/**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided including
+ * a domain prefix.
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XXXX:XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+#undef GET_PCIADDR_FIELD
+
+/**
+ * Utility function to write a pci device name, this device name can later be
+ * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
+ * BDF helpers.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ */
+static inline void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+		char *output, size_t size)
+{
+	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+			    addr->domain, addr->bus,
+			    addr->devid, addr->function) >= 0);
+}
+
+/* Compare two PCI device addresses. */
+/**
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
+static inline int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			 const struct rte_pci_addr *addr2)
+{
+	uint64_t dev_addr, dev_addr2;
+
+	if ((addr == NULL) || (addr2 == NULL))
+		return -1;
+
+	dev_addr = ((uint64_t)addr->domain << 24) |
+		(addr->bus << 16) | (addr->devid << 8) | addr->function;
+	dev_addr2 = ((uint64_t)addr2->domain << 24) |
+		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+	if (dev_addr > dev_addr2)
+		return 1;
+	else if (dev_addr < dev_addr2)
+		return -1;
+	else
+		return 0;
+}
+
+/**
+ * Map a particular resource from a file.
+ *
+ * @param requested_addr
+ *      The starting address for the new mapping range.
+ * @param fd
+ *      The file descriptor.
+ * @param offset
+ *      The offset for the mapping range.
+ * @param size
+ *      The size for the mapping range.
+ * @param additional_flags
+ *      The additional flags for the mapping range.
+ * @return
+ *   - On success, the function returns a pointer to the mapped area.
+ *   - On error, the value MAP_FAILED is returned.
+ */
+void *pci_map_resource(void *requested_addr, int fd, off_t offset,
+		size_t size, int additional_flags);
+
+/**
+ * Unmap a particular resource.
+ *
+ * @param requested_addr
+ *      The address for the unmapping range.
+ * @param size
+ *      The size for the unmapping range.
+ */
+void pci_unmap_resource(void *requested_addr, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PCI_H_ */
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
new file mode 100644
index 0000000..9dfdd3f
--- /dev/null
+++ b/lib/librte_pci/rte_pci.c
@@ -0,0 +1,92 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+
+#include "rte_pci.h"
+
+/* map a particular resource from a file */
+void *
+pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+		 int additional_flags)
+{
+	void *mapaddr;
+
+	/* Map the PCI memory resource of device */
+	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+			MAP_SHARED | additional_flags, fd, offset);
+	if (mapaddr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
+			__func__, fd, requested_addr,
+			(unsigned long)size, (unsigned long)offset,
+			strerror(errno), mapaddr);
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
+
+	return mapaddr;
+}
+
+/* unmap a particular resource */
+void
+pci_unmap_resource(void *requested_addr, size_t size)
+{
+	if (requested_addr == NULL)
+		return;
+
+	/* Unmap the PCI memory resource of device */
+	if (munmap(requested_addr, size)) {
+		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+			__func__, requested_addr, (unsigned long)size,
+			strerror(errno));
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
+				requested_addr);
+}
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
new file mode 100644
index 0000000..64dec54
--- /dev/null
+++ b/lib/librte_pci/rte_pci_version.map
@@ -0,0 +1,8 @@
+DPDK_17.11 {
+	global:
+
+	pci_map_resource;
+	pci_unmap_resource;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index c25fdd9..f93618f 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -96,6 +96,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI)            += -lrte_pci
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
@@ -104,6 +105,8 @@ ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
 endif
 
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI_BUS)        += -lrte_bus_pci
+
 ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
 # plugins (link only if static libraries)
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v3 05/13] lib: include rte_bus_pci
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
                       ` (3 preceding siblings ...)
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 04/13] pci: introduce PCI lib and bus Gaetan Rivet
@ 2017-09-25 15:24     ` Gaetan Rivet
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 06/13] drivers: " Gaetan Rivet
                       ` (8 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-25 15:24 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update the libraries, as structuraly unsound as it may be.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ether/rte_ethdev_pci.h          | 1 +
 lib/librte_eventdev/rte_eventdev_pmd_pci.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h
index 56b1072..722075e 100644
--- a/lib/librte_ether/rte_ethdev_pci.h
+++ b/lib/librte_ether/rte_ethdev_pci.h
@@ -36,6 +36,7 @@
 
 #include <rte_malloc.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 
 /**
diff --git a/lib/librte_eventdev/rte_eventdev_pmd_pci.h b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
index b6bd731..ade32b5 100644
--- a/lib/librte_eventdev/rte_eventdev_pmd_pci.h
+++ b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
@@ -50,6 +50,7 @@ extern "C" {
 #include <rte_eal.h>
 #include <rte_lcore.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "rte_eventdev_pmd.h"
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v3 06/13] drivers: include rte_bus_pci
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
                       ` (4 preceding siblings ...)
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 05/13] lib: include rte_bus_pci Gaetan Rivet
@ 2017-09-25 15:24     ` Gaetan Rivet
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 07/13] test: " Gaetan Rivet
                       ` (7 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-25 15:24 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update drivers.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/bus/pci/bsd/rte_pci.c            | 1 +
 drivers/bus/pci/linux/rte_pci.c          | 1 +
 drivers/bus/pci/linux/rte_pci_uio.c      | 1 +
 drivers/bus/pci/linux/rte_pci_vfio.c     | 1 +
 drivers/bus/pci/linux/rte_vfio_mp_sync.c | 1 +
 drivers/bus/pci/private.h                | 1 +
 drivers/bus/pci/rte_pci_common.c         | 1 +
 drivers/bus/pci/rte_pci_common_uio.c     | 1 +
 drivers/crypto/qat/qat_qp.c              | 1 +
 drivers/event/octeontx/ssovf_probe.c     | 1 +
 drivers/net/ark/ark_ethdev.c             | 1 +
 drivers/net/avp/avp_ethdev.c             | 2 ++
 drivers/net/bnxt/bnxt.h                  | 1 +
 drivers/net/bonding/rte_eth_bond_args.c  | 1 +
 drivers/net/cxgbe/base/adapter.h         | 1 +
 drivers/net/cxgbe/cxgbe_ethdev.c         | 1 +
 drivers/net/e1000/em_ethdev.c            | 1 +
 drivers/net/e1000/igb_ethdev.c           | 1 +
 drivers/net/e1000/igb_pf.c               | 1 +
 drivers/net/ena/ena_ethdev.h             | 1 +
 drivers/net/enic/base/vnic_dev.h         | 4 +++-
 drivers/net/enic/enic_ethdev.c           | 1 +
 drivers/net/enic/enic_main.c             | 1 +
 drivers/net/i40e/i40e_ethdev.c           | 1 +
 drivers/net/i40e/i40e_ethdev_vf.c        | 1 +
 drivers/net/ixgbe/ixgbe_ethdev.c         | 1 +
 drivers/net/ixgbe/ixgbe_ethdev.h         | 1 +
 drivers/net/mlx5/mlx5.c                  | 1 +
 drivers/net/mlx5/mlx5_ethdev.c           | 1 +
 drivers/net/sfc/sfc.h                    | 1 +
 drivers/net/sfc/sfc_ethdev.c             | 1 +
 drivers/net/thunderx/nicvf_ethdev.c      | 1 +
 drivers/net/virtio/virtio_ethdev.c       | 1 +
 drivers/net/virtio/virtio_pci.h          | 1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c     | 1 +
 35 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/pci/bsd/rte_pci.c b/drivers/bus/pci/bsd/rte_pci.c
index 5bd0f4b..6c7ab81 100644
--- a/drivers/bus/pci/bsd/rte_pci.c
+++ b/drivers/bus/pci/bsd/rte_pci.c
@@ -57,6 +57,7 @@
 #include <rte_interrupts.h>
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_common.h>
 #include <rte_launch.h>
 #include <rte_memory.h>
diff --git a/drivers/bus/pci/linux/rte_pci.c b/drivers/bus/pci/linux/rte_pci.c
index c2ac82b..ba32d8b 100644
--- a/drivers/bus/pci/linux/rte_pci.c
+++ b/drivers/bus/pci/linux/rte_pci.c
@@ -37,6 +37,7 @@
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 #include <rte_devargs.h>
diff --git a/drivers/bus/pci/linux/rte_pci_uio.c b/drivers/bus/pci/linux/rte_pci_uio.c
index eed6d0f..1f0dacd 100644
--- a/drivers/bus/pci/linux/rte_pci_uio.c
+++ b/drivers/bus/pci/linux/rte_pci_uio.c
@@ -47,6 +47,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_common.h>
 #include <rte_malloc.h>
diff --git a/drivers/bus/pci/linux/rte_pci_vfio.c b/drivers/bus/pci/linux/rte_pci_vfio.c
index 81b67c9..ab63423 100644
--- a/drivers/bus/pci/linux/rte_pci_vfio.c
+++ b/drivers/bus/pci/linux/rte_pci_vfio.c
@@ -42,6 +42,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 
diff --git a/drivers/bus/pci/linux/rte_vfio_mp_sync.c b/drivers/bus/pci/linux/rte_vfio_mp_sync.c
index 2c1654d..d24eba1 100644
--- a/drivers/bus/pci/linux/rte_vfio_mp_sync.c
+++ b/drivers/bus/pci/linux/rte_vfio_mp_sync.c
@@ -50,6 +50,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 7ff1fc4..fdc2c81 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -37,6 +37,7 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 struct rte_pci_driver;
 struct rte_pci_device;
diff --git a/drivers/bus/pci/rte_pci_common.c b/drivers/bus/pci/rte_pci_common.c
index c37b85b..459ae42 100644
--- a/drivers/bus/pci/rte_pci_common.c
+++ b/drivers/bus/pci/rte_pci_common.c
@@ -45,6 +45,7 @@
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_per_lcore.h>
 #include <rte_memory.h>
 #include <rte_memzone.h>
diff --git a/drivers/bus/pci/rte_pci_common_uio.c b/drivers/bus/pci/rte_pci_common_uio.c
index 4365660..544c606 100644
--- a/drivers/bus/pci/rte_pci_common_uio.c
+++ b/drivers/bus/pci/rte_pci_common_uio.c
@@ -40,6 +40,7 @@
 
 #include <rte_eal.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tailq.h>
 #include <rte_log.h>
 #include <rte_malloc.h>
diff --git a/drivers/crypto/qat/qat_qp.c b/drivers/crypto/qat/qat_qp.c
index 5048d21..a22d6ef 100644
--- a/drivers/crypto/qat/qat_qp.c
+++ b/drivers/crypto/qat/qat_qp.c
@@ -37,6 +37,7 @@
 #include <rte_memzone.h>
 #include <rte_cryptodev_pmd.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_prefetch.h>
 
diff --git a/drivers/event/octeontx/ssovf_probe.c b/drivers/event/octeontx/ssovf_probe.c
index e1c0c6d..1cac4bc 100644
--- a/drivers/event/octeontx/ssovf_probe.c
+++ b/drivers/event/octeontx/ssovf_probe.c
@@ -35,6 +35,7 @@
 #include <rte_eal.h>
 #include <rte_io.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "ssovf_evdev.h"
 
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 6db362b..78a4d79 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -35,6 +35,7 @@
 #include <sys/stat.h>
 #include <dlfcn.h>
 
+#include <rte_bus_pci.h>
 #include <rte_ethdev_pci.h>
 #include <rte_kvargs.h>
 
diff --git a/drivers/net/avp/avp_ethdev.c b/drivers/net/avp/avp_ethdev.c
index c746a0e..194aadb 100644
--- a/drivers/net/avp/avp_ethdev.c
+++ b/drivers/net/avp/avp_ethdev.c
@@ -36,6 +36,7 @@
 #include <errno.h>
 #include <unistd.h>
 
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_memcpy.h>
@@ -45,6 +46,7 @@
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 405d94d..d7409a8 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -39,6 +39,7 @@
 #include <sys/queue.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_memory.h>
 #include <rte_lcore.h>
diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index bb634c6..2b7b464 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -33,6 +33,7 @@
 
 #include <rte_devargs.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 
 #include <cmdline_parse.h>
diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index 5e5f221..f2057af 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -36,6 +36,7 @@
 #ifndef __T4_ADAPTER_H__
 #define __T4_ADAPTER_H__
 
+#include <rte_bus_pci.h>
 #include <rte_mbuf.h>
 #include <rte_io.h>
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 7bca456..dc322da 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 3d4ab93..c52e5f7 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index e4f7a9f..36385cf 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/e1000/igb_pf.c b/drivers/net/e1000/igb_pf.c
index 6809d30..cd6ae2f 100644
--- a/drivers/net/e1000/igb_pf.c
+++ b/drivers/net/e1000/igb_pf.c
@@ -39,6 +39,7 @@
 #include <stdarg.h>
 #include <inttypes.h>
 
+#include <rte_bus_pci.h>
 #include <rte_interrupts.h>
 #include <rte_log.h>
 #include <rte_debug.h>
diff --git a/drivers/net/ena/ena_ethdev.h b/drivers/net/ena/ena_ethdev.h
index dc3080f..be8bc9f 100644
--- a/drivers/net/ena/ena_ethdev.h
+++ b/drivers/net/ena/ena_ethdev.h
@@ -35,6 +35,7 @@
 #define _ENA_ETHDEV_H_
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "ena_com.h"
 
diff --git a/drivers/net/enic/base/vnic_dev.h b/drivers/net/enic/base/vnic_dev.h
index 9a9e691..c9ca25b 100644
--- a/drivers/net/enic/base/vnic_dev.h
+++ b/drivers/net/enic/base/vnic_dev.h
@@ -35,8 +35,10 @@
 #ifndef _VNIC_DEV_H_
 #define _VNIC_DEV_H_
 
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+
 #include "enic_compat.h"
-#include "rte_pci.h"
 #include "vnic_resource.h"
 #include "vnic_devcmd.h"
 
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index da8fec2..681efb2 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -37,6 +37,7 @@
 
 #include <rte_dev.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_string_fns.h>
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 40dbec7..b35ad5d 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -40,6 +40,7 @@
 #include <libgen.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_memzone.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index f12aefa..88b6e50 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_eal.h>
 #include <rte_string_fns.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 73c315a..a7aff37 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -47,6 +47,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 9ca5cbc..a2d73a1 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index caa50c8..383ec71 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -41,6 +41,7 @@
 #include <rte_time.h>
 #include <rte_hash.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tm_driver.h>
 
 /* need update link, bit flag */
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b7e5046..968599e 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -58,6 +58,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_common.h>
 #include <rte_kvargs.h>
 #ifdef PEDANTIC
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index b0eb3cd..c2dc1f1 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -56,6 +56,7 @@
 #endif
 #include <rte_atomic.h>
 #include <rte_ethdev.h>
+#include <rte_bus_pci.h>
 #include <rte_mbuf.h>
 #include <rte_common.h>
 #include <rte_interrupts.h>
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 286d1ac..5944103 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -35,6 +35,7 @@
 #include <stdbool.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_kvargs.h>
 #include <rte_spinlock.h>
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 12bcd6f..74e2486 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -33,6 +33,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_errno.h>
 
 #include "efx.h"
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index edc17f1..e63dc4e 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -61,6 +61,7 @@
 #include <rte_malloc.h>
 #include <rte_random.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tailq.h>
 
 #include "base/nicvf_plat.h"
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index e320811..9a6850d 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -46,6 +46,7 @@
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_common.h>
 #include <rte_errno.h>
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 18caebd..c8261b7 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -37,6 +37,7 @@
 #include <stdint.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 
 struct virtqueue;
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 3910991..bf4900d 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v3 07/13] test: include rte_bus_pci
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
                       ` (5 preceding siblings ...)
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 06/13] drivers: " Gaetan Rivet
@ 2017-09-25 15:24     ` Gaetan Rivet
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 08/13] app/testpmd: " Gaetan Rivet
                       ` (6 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-25 15:24 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update test applications.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 test/test/test_kni.c    | 1 +
 test/test/virtual_pmd.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/test/test/test_kni.c b/test/test/test_kni.c
index db17fdf..b2f05ec 100644
--- a/test/test/test_kni.c
+++ b/test/test/test_kni.c
@@ -42,6 +42,7 @@
 #include <rte_string_fns.h>
 #include <rte_mempool.h>
 #include <rte_ethdev.h>
+#include <rte_bus_pci.h>
 #include <rte_cycles.h>
 #include <rte_kni.h>
 
diff --git a/test/test/virtual_pmd.c b/test/test/virtual_pmd.c
index 9d46ad5..72e784a 100644
--- a/test/test/virtual_pmd.c
+++ b/test/test/virtual_pmd.c
@@ -34,6 +34,7 @@
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_memory.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v3 08/13] app/testpmd: include rte_bus_pci
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
                       ` (6 preceding siblings ...)
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 07/13] test: " Gaetan Rivet
@ 2017-09-25 15:24     ` Gaetan Rivet
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 09/13] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
                       ` (5 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-25 15:24 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update applications.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 app/test-pmd/testpmd.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 1d1ee75..d0613b5 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -35,6 +35,7 @@
 #define _TESTPMD_H_
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_gro.h>
 
 #define RTE_PORT_ALL            (~(portid_t)0x0)
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v3 09/13] cryptodev: move PCI specific helpers to drivers/crypto
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
                       ` (7 preceding siblings ...)
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 08/13] app/testpmd: " Gaetan Rivet
@ 2017-09-25 15:24     ` Gaetan Rivet
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 10/13] pci: avoid inlining functions Gaetan Rivet
                       ` (4 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-25 15:24 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Those helpers rely on the PCI bus driver implementation.
Other similar libraries relied on the bus-specifics being handled in
inlined functions, to be compiled on demand by drivers, once the proper
PCI dependency has been settled. This seems unsafe.

Move the PCI-specific helpers out of the lib directory to the
drivers/crypto directory, properly following the dependency hierarchy.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/Makefile                                 |   2 +-
 drivers/crypto/Makefile                          |   4 +-
 drivers/crypto/pci/Makefile                      |  52 +++++++++
 drivers/crypto/pci/rte_cryptodev_pci.c           | 128 +++++++++++++++++++++++
 drivers/crypto/pci/rte_cryptodev_pci.h           |  94 +++++++++++++++++
 drivers/crypto/pci/rte_cryptodev_pci_version.map |   7 ++
 lib/librte_cryptodev/Makefile                    |   1 -
 lib/librte_cryptodev/rte_cryptodev_pci.h         |  92 ----------------
 lib/librte_cryptodev/rte_cryptodev_pmd.c         |  94 -----------------
 lib/librte_cryptodev/rte_cryptodev_version.map   |   2 -
 10 files changed, 285 insertions(+), 191 deletions(-)
 create mode 100644 drivers/crypto/pci/Makefile
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.c
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.h
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci_version.map
 delete mode 100644 lib/librte_cryptodev/rte_cryptodev_pci.h

diff --git a/drivers/Makefile b/drivers/Makefile
index 7fef66d..a5d3fa0 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -37,7 +37,7 @@ DEPDIRS-mempool := bus
 DIRS-y += net
 DEPDIRS-net := bus mempool
 DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
-DEPDIRS-crypto := mempool
+DEPDIRS-crypto := bus mempool
 DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += event
 DEPDIRS-event := bus
 
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 7a719b9..cfd6cb6 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_cryptodev
 
+DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
+DEPDIRS-pci = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm
 DEPDIRS-aesni_gcm = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb
@@ -42,7 +44,7 @@ DEPDIRS-armv8 = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_OPENSSL) += openssl
 DEPDIRS-openssl = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat
-DEPDIRS-qat = $(core-libs)
+DEPDIRS-qat = $(core-libs) librte_cryptodev_pci
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER) += scheduler
 DEPDIRS-scheduler = $(core-libs) librte_kvargs librte_reorder
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += snow3g
diff --git a/drivers/crypto/pci/Makefile b/drivers/crypto/pci/Makefile
new file mode 100644
index 0000000..da819f2
--- /dev/null
+++ b/drivers/crypto/pci/Makefile
@@ -0,0 +1,52 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A. All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND S.A. nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_cryptodev_pci.a
+
+# library version
+LIBABIVER := 1
+
+# build flags
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# library source files
+SRCS-y += rte_cryptodev_pci.c
+
+# export include files
+SYMLINK-y-include += rte_cryptodev_pci.h
+
+# versioning export map
+EXPORT_MAP := rte_cryptodev_pci_version.map
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/crypto/pci/rte_cryptodev_pci.c b/drivers/crypto/pci/rte_cryptodev_pci.c
new file mode 100644
index 0000000..a2a1366
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci.c
@@ -0,0 +1,128 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of the copyright holder nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_malloc.h>
+
+#include "rte_cryptodev_pci.h"
+
+int
+rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
+			size_t private_data_size,
+			cryptodev_pci_init_t dev_init)
+{
+	struct rte_cryptodev *cryptodev;
+
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+
+	int retval;
+
+	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name, rte_socket_id());
+	if (cryptodev == NULL)
+		return -ENOMEM;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc_socket(
+						"cryptodev private structure",
+						private_data_size,
+						RTE_CACHE_LINE_SIZE,
+						rte_socket_id());
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private "
+					"device data");
+	}
+
+	cryptodev->device = &pci_dev->device;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	/* Invoke PMD device initialization function */
+	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
+	retval = dev_init(cryptodev);
+	if (retval == 0)
+		return 0;
+
+	CDEV_LOG_ERR("driver %s: crypto_dev_init(vendor_id=0x%x device_id=0x%x)"
+			" failed", pci_dev->device.driver->name,
+			(unsigned int) pci_dev->id.vendor_id,
+			(unsigned int) pci_dev->id.device_id);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	return -ENXIO;
+}
+
+int
+rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
+		cryptodev_pci_uninit_t dev_uninit)
+{
+	struct rte_cryptodev *cryptodev;
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+	int ret;
+
+	if (pci_dev == NULL)
+		return -EINVAL;
+
+	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
+	if (cryptodev == NULL)
+		return -ENODEV;
+
+	/* Invoke PMD device uninit function */
+	if (dev_uninit) {
+		ret = dev_uninit(cryptodev);
+		if (ret)
+			return ret;
+	}
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->device = NULL;
+	cryptodev->data = NULL;
+
+	return 0;
+}
diff --git a/drivers/crypto/pci/rte_cryptodev_pci.h b/drivers/crypto/pci/rte_cryptodev_pci.h
new file mode 100644
index 0000000..97b6f1e
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci.h
@@ -0,0 +1,94 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of the copyright holder nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_CRYPTODEV_PCI_H_
+#define _RTE_CRYPTODEV_PCI_H_
+
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
+
+/**
+ * Initialisation function of a crypto driver invoked for each matching
+ * crypto PCI device detected during the PCI probing phase.
+ *
+ * @param	dev	The dev pointer is the address of the *rte_cryptodev*
+ *			structure associated with the matching device and which
+ *			has been [automatically] allocated in the
+ *			*rte_crypto_devices* array.
+ *
+ * @return
+ *   - 0: Success, the device is properly initialised by the driver.
+ *        In particular, the driver MUST have set up the *dev_ops* pointer
+ *        of the *dev* structure.
+ *   - <0: Error code of the device initialisation failure.
+ */
+typedef int (*cryptodev_pci_init_t)(struct rte_cryptodev *dev);
+
+/**
+ * Finalisation function of a driver invoked for each matching
+ * PCI device detected during the PCI closing phase.
+ *
+ * @param	dev	The dev pointer is the address of the *rte_cryptodev*
+ *			structure associated with the matching device and which
+ *			has been [automatically] allocated in the
+ *			*rte_crypto_devices* array.
+ *
+ *  * @return
+ *   - 0: Success, the device is properly finalised by the driver.
+ *        In particular, the driver MUST free the *dev_ops* pointer
+ *        of the *dev* structure.
+ *   - <0: Error code of the device initialisation failure.
+ */
+typedef int (*cryptodev_pci_uninit_t)(struct rte_cryptodev *dev);
+
+/**
+ * @internal
+ * Wrapper for use by pci drivers as a .probe function to attach to a crypto
+ * interface.
+ */
+int
+rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
+			size_t private_data_size,
+			cryptodev_pci_init_t dev_init);
+
+/**
+ * @internal
+ * Wrapper for use by pci drivers as a .remove function to detach a crypto
+ * interface.
+ */
+int
+rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
+		cryptodev_pci_uninit_t dev_uninit);
+
+#endif /* _RTE_CRYPTODEV_PCI_H_ */
diff --git a/drivers/crypto/pci/rte_cryptodev_pci_version.map b/drivers/crypto/pci/rte_cryptodev_pci_version.map
new file mode 100644
index 0000000..0510fef
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci_version.map
@@ -0,0 +1,7 @@
+DPDK_17.11 {
+	global:
+
+	rte_cryptodev_pci_generic_probe;
+	rte_cryptodev_pci_generic_remove;
+
+};
diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index 6ac331b..bd94cf7 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -49,7 +49,6 @@ SYMLINK-y-include += rte_crypto_sym.h
 SYMLINK-y-include += rte_cryptodev.h
 SYMLINK-y-include += rte_cryptodev_pmd.h
 SYMLINK-y-include += rte_cryptodev_vdev.h
-SYMLINK-y-include += rte_cryptodev_pci.h
 
 # versioning export map
 EXPORT_MAP := rte_cryptodev_version.map
diff --git a/lib/librte_cryptodev/rte_cryptodev_pci.h b/lib/librte_cryptodev/rte_cryptodev_pci.h
deleted file mode 100644
index 67eda96..0000000
--- a/lib/librte_cryptodev/rte_cryptodev_pci.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2017 Intel Corporation. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of the copyright holder nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_CRYPTODEV_PCI_H_
-#define _RTE_CRYPTODEV_PCI_H_
-
-#include <rte_pci.h>
-#include "rte_cryptodev.h"
-
-/**
- * Initialisation function of a crypto driver invoked for each matching
- * crypto PCI device detected during the PCI probing phase.
- *
- * @param	dev	The dev pointer is the address of the *rte_cryptodev*
- *			structure associated with the matching device and which
- *			has been [automatically] allocated in the
- *			*rte_crypto_devices* array.
- *
- * @return
- *   - 0: Success, the device is properly initialised by the driver.
- *        In particular, the driver MUST have set up the *dev_ops* pointer
- *        of the *dev* structure.
- *   - <0: Error code of the device initialisation failure.
- */
-typedef int (*cryptodev_pci_init_t)(struct rte_cryptodev *dev);
-
-/**
- * Finalisation function of a driver invoked for each matching
- * PCI device detected during the PCI closing phase.
- *
- * @param	dev	The dev pointer is the address of the *rte_cryptodev*
- *			structure associated with the matching device and which
- *			has been [automatically] allocated in the
- *			*rte_crypto_devices* array.
- *
- *  * @return
- *   - 0: Success, the device is properly finalised by the driver.
- *        In particular, the driver MUST free the *dev_ops* pointer
- *        of the *dev* structure.
- *   - <0: Error code of the device initialisation failure.
- */
-typedef int (*cryptodev_pci_uninit_t)(struct rte_cryptodev *dev);
-
-/**
- * @internal
- * Wrapper for use by pci drivers as a .probe function to attach to a crypto
- * interface.
- */
-int
-rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
-			size_t private_data_size,
-			cryptodev_pci_init_t dev_init);
-
-/**
- * @internal
- * Wrapper for use by pci drivers as a .remove function to detach a crypto
- * interface.
- */
-int
-rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
-		cryptodev_pci_uninit_t dev_uninit);
-
-#endif /* _RTE_CRYPTODEV_PCI_H_ */
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.c b/lib/librte_cryptodev/rte_cryptodev_pmd.c
index a57faad..ec5c33b 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.c
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.c
@@ -33,7 +33,6 @@
 #include <rte_malloc.h>
 
 #include "rte_cryptodev_vdev.h"
-#include "rte_cryptodev_pci.h"
 #include "rte_cryptodev_pmd.h"
 
 /**
@@ -154,96 +153,3 @@ rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
 	rte_kvargs_free(kvlist);
 	return ret;
 }
-
-int
-rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
-			size_t private_data_size,
-			cryptodev_pci_init_t dev_init)
-{
-	struct rte_cryptodev *cryptodev;
-
-	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
-
-	int retval;
-
-	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
-			sizeof(cryptodev_name));
-
-	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name, rte_socket_id());
-	if (cryptodev == NULL)
-		return -ENOMEM;
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-		cryptodev->data->dev_private =
-				rte_zmalloc_socket(
-						"cryptodev private structure",
-						private_data_size,
-						RTE_CACHE_LINE_SIZE,
-						rte_socket_id());
-
-		if (cryptodev->data->dev_private == NULL)
-			rte_panic("Cannot allocate memzone for private "
-					"device data");
-	}
-
-	cryptodev->device = &pci_dev->device;
-
-	/* init user callbacks */
-	TAILQ_INIT(&(cryptodev->link_intr_cbs));
-
-	/* Invoke PMD device initialization function */
-	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
-	retval = dev_init(cryptodev);
-	if (retval == 0)
-		return 0;
-
-	CDEV_LOG_ERR("driver %s: crypto_dev_init(vendor_id=0x%x device_id=0x%x)"
-			" failed", pci_dev->device.driver->name,
-			(unsigned int) pci_dev->id.vendor_id,
-			(unsigned int) pci_dev->id.device_id);
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-		rte_free(cryptodev->data->dev_private);
-
-	/* free crypto device */
-	rte_cryptodev_pmd_release_device(cryptodev);
-
-	return -ENXIO;
-}
-
-int
-rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
-		cryptodev_pci_uninit_t dev_uninit)
-{
-	struct rte_cryptodev *cryptodev;
-	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
-	int ret;
-
-	if (pci_dev == NULL)
-		return -EINVAL;
-
-	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
-			sizeof(cryptodev_name));
-
-	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
-	if (cryptodev == NULL)
-		return -ENODEV;
-
-	/* Invoke PMD device uninit function */
-	if (dev_uninit) {
-		ret = dev_uninit(cryptodev);
-		if (ret)
-			return ret;
-	}
-
-	/* free crypto device */
-	rte_cryptodev_pmd_release_device(cryptodev);
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-		rte_free(cryptodev->data->dev_private);
-
-	cryptodev->device = NULL;
-	cryptodev->data = NULL;
-
-	return 0;
-}
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index e9ba88a..496253d 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -68,8 +68,6 @@ DPDK_17.08 {
 	rte_cryptodev_get_aead_algo_enum;
 	rte_cryptodev_get_header_session_size;
 	rte_cryptodev_get_private_session_size;
-	rte_cryptodev_pci_generic_probe;
-	rte_cryptodev_pci_generic_remove;
 	rte_cryptodev_sym_capability_check_aead;
 	rte_cryptodev_sym_session_init;
 	rte_cryptodev_sym_session_clear;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v3 10/13] pci: avoid inlining functions
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
                       ` (8 preceding siblings ...)
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 09/13] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
@ 2017-09-25 15:24     ` Gaetan Rivet
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 11/13] pci: avoid over-complicated macro Gaetan Rivet
                       ` (3 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-25 15:24 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Parsing operations should not happen in performance critical sections.
Headers should not propose implementations unless duly required.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_pci/include/rte_pci.h   | 69 ++++----------------------------------
 lib/librte_pci/rte_pci.c           | 65 +++++++++++++++++++++++++++++++++++
 lib/librte_pci/rte_pci_version.map |  4 +++
 3 files changed, 75 insertions(+), 63 deletions(-)

diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
index 3858e80..09a609a 100644
--- a/lib/librte_pci/include/rte_pci.h
+++ b/lib/librte_pci/include/rte_pci.h
@@ -126,19 +126,6 @@ struct mapped_pci_resource {
 /** mapped pci device list */
 TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 
-/**< Internal use only - Macro used by pci addr parsing functions **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
-do {                                                               \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
-
 /**
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided without
@@ -152,15 +139,7 @@ do {                                                               \
  * @return
  *  0 on success, negative on error.
  */
-static inline int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
+int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to produce a PCI Bus-Device-Function value
@@ -174,16 +153,7 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
  * @return
  *  0 on success, negative on error.
  */
-static inline int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-#undef GET_PCIADDR_FIELD
+int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to write a pci device name, this device name can later be
@@ -197,17 +167,9 @@ eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
  * @param size
  *	The output buffer size
  */
-static inline void
-rte_pci_device_name(const struct rte_pci_addr *addr,
-		char *output, size_t size)
-{
-	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
-	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
-			    addr->domain, addr->bus,
-			    addr->devid, addr->function) >= 0);
-}
+void rte_pci_device_name(const struct rte_pci_addr *addr,
+			 char *output, size_t size);
 
-/* Compare two PCI device addresses. */
 /**
  * Utility function to compare two PCI device addresses.
  *
@@ -220,27 +182,8 @@ rte_pci_device_name(const struct rte_pci_addr *addr,
  *	Positive on addr is greater than addr2.
  *	Negative on addr is less than addr2, or error.
  */
-static inline int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			 const struct rte_pci_addr *addr2)
-{
-	uint64_t dev_addr, dev_addr2;
-
-	if ((addr == NULL) || (addr2 == NULL))
-		return -1;
-
-	dev_addr = ((uint64_t)addr->domain << 24) |
-		(addr->bus << 16) | (addr->devid << 8) | addr->function;
-	dev_addr2 = ((uint64_t)addr2->domain << 24) |
-		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
-
-	if (dev_addr > dev_addr2)
-		return 1;
-	else if (dev_addr < dev_addr2)
-		return -1;
-	else
-		return 0;
-}
+int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			     const struct rte_pci_addr *addr2);
 
 /**
  * Map a particular resource from a file.
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index 9dfdd3f..8584b55 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -53,6 +53,71 @@
 
 #include "rte_pci.h"
 
+/* Macro used by pci addr parsing functions. **/
+#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                     \
+do {                                                            \
+	unsigned long val;                                      \
+	char *end;                                              \
+	errno = 0;                                              \
+	val = strtoul((in), &end, 16);                          \
+	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
+		return -EINVAL;                                 \
+	(fd) = (typeof (fd))val;                                \
+	(in) = end + 1;                                         \
+} while(0)
+
+int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	dev_addr->domain = 0;
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+		    char *output, size_t size)
+{
+	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+			    addr->domain, addr->bus,
+			    addr->devid, addr->function) >= 0);
+}
+
+int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			 const struct rte_pci_addr *addr2)
+{
+	uint64_t dev_addr, dev_addr2;
+
+	if ((addr == NULL) || (addr2 == NULL))
+		return -1;
+
+	dev_addr = ((uint64_t)addr->domain << 24) |
+		(addr->bus << 16) | (addr->devid << 8) | addr->function;
+	dev_addr2 = ((uint64_t)addr2->domain << 24) |
+		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+	if (dev_addr > dev_addr2)
+		return 1;
+	else if (dev_addr < dev_addr2)
+		return -1;
+	else
+		return 0;
+}
+
 /* map a particular resource from a file */
 void *
 pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index 64dec54..a940259 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -1,8 +1,12 @@
 DPDK_17.11 {
 	global:
 
+	eal_parse_pci_BDF;
+	eal_parse_pci_DomBDF;
 	pci_map_resource;
 	pci_unmap_resource;
+	rte_eal_compare_pci_addr;
+	rte_pci_device_name;
 
 	local: *;
 };
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v3 11/13] pci: avoid over-complicated macro
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
                       ` (9 preceding siblings ...)
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 10/13] pci: avoid inlining functions Gaetan Rivet
@ 2017-09-25 15:24     ` Gaetan Rivet
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 12/13] pci: deprecate misnamed functions Gaetan Rivet
                       ` (2 subsequent siblings)
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-25 15:24 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Using a macro helps writing the code to the detriment of the reader in
this case. This is backward. Write once, read many.

The few LOCs gained is not worth the opacity of the implementation.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_pci/rte_pci.c | 65 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 46 insertions(+), 19 deletions(-)

diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index 8584b55..cbb5359 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -53,36 +53,63 @@
 
 #include "rte_pci.h"
 
-/* Macro used by pci addr parsing functions. **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                     \
-do {                                                            \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
+static inline const char *
+get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
+{
+	unsigned long val;
+	uint8_t *u8 = _u8;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != dlm || val > UINT8_MAX) {
+		errno = errno ? errno : EINVAL;
+		return NULL;
+	}
+	*u8 = (uint8_t)val;
+	return end + 1;
+}
 
 int
 eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	const char *in = input;
+
 	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
 	return 0;
 }
 
 int
 eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
 {
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	const char *in = input;
+	unsigned long val;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != ':' || val > UINT16_MAX)
+		return -EINVAL;
+	dev_addr->domain = (uint16_t)val;
+	in = end + 1;
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
 	return 0;
 }
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v3 12/13] pci: deprecate misnamed functions
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
                       ` (10 preceding siblings ...)
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 11/13] pci: avoid over-complicated macro Gaetan Rivet
@ 2017-09-25 15:24     ` Gaetan Rivet
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 13/13] doc: add notes on EAL PCI API update Gaetan Rivet
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-25 15:24 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Rename misnamed functions and describe the change in a deprecation
notice.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst | 10 ++++++
 lib/librte_pci/include/rte_pci.h     | 63 ++++++++++++++++++++++++++++++++++++
 lib/librte_pci/rte_pci.c             | 26 +++++++++++++++
 lib/librte_pci/rte_pci_version.map   |  4 +++
 4 files changed, 103 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 3362f33..1828e57 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -120,3 +120,13 @@ Deprecation Notices
   The non-"do-sig" versions of the hash tables will be removed
   (including the ``signature_offset`` parameter)
   and the "do-sig" versions renamed accordingly.
+
+* pci: Several exposed functions are misnamed.
+  The following functions are deprecated starting from v17.11 and are replaced:
+
+  - ``eal_parse_pci_BDF`` replaced by ``pci_parse_BDF``
+  - ``eal_parse_pci_DomBDF`` replaced by ``pci_parse_DomBDF``
+  - ``rte_eal_compare_pci_addr`` replaced by ``pci_addr_cmp``
+  - ``rte_pci_device_name`` replaced by ``pci_device_name``
+
+  The functions are only renamed. Their behavior is not affected.
diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
index 09a609a..224cea0 100644
--- a/lib/librte_pci/include/rte_pci.h
+++ b/lib/librte_pci/include/rte_pci.h
@@ -127,6 +127,7 @@ struct mapped_pci_resource {
 TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 
 /**
+ * @deprecated
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided without
  * a domain prefix (i.e. domain returned is always 0)
@@ -143,6 +144,22 @@ int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided without
+ * a domain prefix (i.e. domain returned is always 0)
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned. Domain will always be
+ *	returned as 0
+ * @return
+ *  0 on success, negative on error.
+ */
+int pci_parse_BDF(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
+ * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided including
  * a domain prefix.
  *
@@ -156,6 +173,21 @@ int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided including
+ * a domain prefix.
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XXXX:XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned
+ * @return
+ *  0 on success, negative on error.
+ */
+int pci_parse_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
  * Utility function to write a pci device name, this device name can later be
  * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
  * BDF helpers.
@@ -171,6 +203,22 @@ void rte_pci_device_name(const struct rte_pci_addr *addr,
 			 char *output, size_t size);
 
 /**
+ * Utility function to write a pci device name, this device name can later be
+ * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
+ * BDF helpers.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ */
+void pci_device_name(const struct rte_pci_addr *addr,
+		     char *output, size_t size);
+
+/**
+ * @deprecated
  * Utility function to compare two PCI device addresses.
  *
  * @param addr
@@ -186,6 +234,21 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 			     const struct rte_pci_addr *addr2);
 
 /**
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
+int pci_addr_cmp(const struct rte_pci_addr *addr,
+		 const struct rte_pci_addr *addr2);
+
+/**
  * Map a particular resource from a file.
  *
  * @param requested_addr
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index cbb5359..54ce10d 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -73,6 +73,12 @@ get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
 int
 eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	return pci_parse_BDF(input, dev_addr);
+}
+
+int
+pci_parse_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
 	const char *in = input;
 
 	dev_addr->domain = 0;
@@ -91,6 +97,12 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 int
 eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	return pci_parse_DomBDF(input, dev_addr);
+}
+
+int
+pci_parse_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
 	const char *in = input;
 	unsigned long val;
 	char *end;
@@ -117,6 +129,13 @@ void
 rte_pci_device_name(const struct rte_pci_addr *addr,
 		    char *output, size_t size)
 {
+	pci_device_name(addr, output, size);
+}
+
+void
+pci_device_name(const struct rte_pci_addr *addr,
+		char *output, size_t size)
+{
 	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
 	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
 			    addr->domain, addr->bus,
@@ -127,6 +146,13 @@ int
 rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 			 const struct rte_pci_addr *addr2)
 {
+	return pci_addr_cmp(addr, addr2);
+}
+
+int
+pci_addr_cmp(const struct rte_pci_addr *addr,
+	     const struct rte_pci_addr *addr2)
+{
 	uint64_t dev_addr, dev_addr2;
 
 	if ((addr == NULL) || (addr2 == NULL))
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index a940259..541769f 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -3,7 +3,11 @@ DPDK_17.11 {
 
 	eal_parse_pci_BDF;
 	eal_parse_pci_DomBDF;
+	pci_addr_cmp;
+	pci_device_name;
 	pci_map_resource;
+	pci_parse_BDF;
+	pci_parse_DomBDF;
 	pci_unmap_resource;
 	rte_eal_compare_pci_addr;
 	rte_pci_device_name;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v3 13/13] doc: add notes on EAL PCI API update
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
                       ` (11 preceding siblings ...)
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 12/13] pci: deprecate misnamed functions Gaetan Rivet
@ 2017-09-25 15:24     ` Gaetan Rivet
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
  13 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-09-25 15:24 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Add a section related to EAL API changes to 17.11 release notes.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/rel_notes/release_17_11.rst | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 8bf91bd..d5546ba 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -130,6 +130,34 @@ API Changes
   * Rework start and stop APIs into ``rte_service_runstate_set``
   * Added API to set runstate of service implementation to indicate readyness
 
+* **PCI bus API moved outside of the EAL**
+
+  The PCI bus previously implemented within the EAL has been moved.
+  A first part has been added as an RTE library providing PCI helpers to
+  parse device locations or other such utilities.
+  A second part consisting in the actual bus driver has been moved to its
+  proper subdirectory, without changing its functionalities.
+
+  As such, several PCI-related functions are not proposed by the EAL anymore:
+
+  * rte_pci_detach
+  * rte_pci_dump
+  * rte_pci_ioport_map
+  * rte_pci_ioport_read
+  * rte_pci_ioport_unmap
+  * rte_pci_ioport_write
+  * rte_pci_map_device
+  * rte_pci_probe
+  * rte_pci_probe_one
+  * rte_pci_read_config
+  * rte_pci_register
+  * rte_pci_scan
+  * rte_pci_unmap_device
+  * rte_pci_unregister
+  * rte_pci_write_config
+
+  These functions are made available either as part of ``librte_pci`` or
+  ``librte_bus_pci``.
 
 ABI Changes
 -----------
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL
  2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
                     ` (14 preceding siblings ...)
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
@ 2017-10-11 14:19   ` Doherty, Declan
  2017-10-11 14:32     ` Gaëtan Rivet
  15 siblings, 1 reply; 156+ messages in thread
From: Doherty, Declan @ 2017-10-11 14:19 UTC (permalink / raw)
  To: Gaetan Rivet, dev

On 18/09/2017 10:31 AM, Gaetan Rivet wrote:
> Hi all,
> 
> Here is a new version of the PCI bus move out of the EAL.
> 
> The EAL PCI implementation is divided in two parts:
> 
>    - librte_pci: library offering helpers to handle PCI objects
>    - librte_bus_pci: bus driver for PCI devices
> 
> This allows other libraries / tools to use PCI elements (location, mappings,
> parsing operations, etc) without forcing a dependency on a bus driver.
> 
> The latter should not have to export helpers that others might need. It
> is focused on defining the rte_pci_device, rte_pci_driver objects and
> their handling.
> 
> The cryptodev library has hard dependencies on rte_pci_devices (used by
> generic probe function). Other similar libs (ether and eventdev) avoided
> the issue by inlining such functions and expecting users to include the
> relevant headers once the PCI bus has already been built.
> 
> @Declan:
> I proposed a solution that would avoid inlining those functions,
> which does not feel right. Let me know what you think of it or if you
> think of a better solution. I think it would be best to have cryptodev
> completely independent from PCI / vdev as far as the lib in concerned
> (the vdev bus will move as well).
> 


Hey Gaetan, apologies for the delay in getting back to you on this, I 
had been looking at this but got sidelined onto other issues before 
usersapce and I'm only getting back to it now. I think that while your 
solution works it just highlights the dependency which probably 
shouldn't be there between the cryptodev library and PCI devices. I've 
had a look, and the functions in the cryptodev which you moved don't 
really provide that much useful functionality. I done some testing and 
completely removed them and just update the QAT PMD which is the only 
crypto PMD which was using them and it seems much cleaner to me. I'll 
push a patch for this change later today and it will allow you to drop 
the patch "cryptodev: move PCI specific helpers to drivers/crypto" from 
this set.

Regards
Declan



> v2:
> 
>    + Made rte_eal_using_phys_addrs common to both linux and bsd interfaces.
>    + Added documentation of EAL API changes in release note.
>    + Fixed a few rebase-related mistakes.
>    + Fixed parallel build race condition reported by Luca Boccassi.
>    + Grouped together commits breaking compilation:
> 
>      -> pci: introduce PCI lib and bus
>      -> lib: include rte_bus_pci
>      -> drivers: include rte_bus_pci
>      -> test: include rte_bus_pci
>      -> app/testpmd: include rte_bus_pci
>      -> cryptodev: move PCI specific helpers to drivers/crypto
> 
>    Until all of them have been applied, compilation is broken.
>    I am currently wondering whether merging some of them might
>    be sensible.
> 
>    + Not included in this series:
> 
>      Several filesystem-related functions are currently
>      private to the EAL and directly linked. This is not good,
>      but the solution seems to be to have a new lib offering an FS abstraction.
>      This seems an overreach for this patchset and should probably come in a
>      second step.
> 
> Gaetan Rivet (14):
>    eal: expose rte_eal_using_phys_addrs
>    ethdev: remove useless PCI dependency
>    bus: properly include rte_debug
>    eal: remove references to PCI
>    pci: introduce PCI lib and bus
>    lib: include rte_bus_pci
>    drivers: include rte_bus_pci
>    test: include rte_bus_pci
>    app/testpmd: include rte_bus_pci
>    cryptodev: move PCI specific helpers to drivers/crypto
>    pci: avoid inlining functions
>    pci: avoid over-complicated macro
>    pci: deprecate misnamed functions
>    doc: add notes on EAL PCI API update
> 
>   app/test-pmd/testpmd.h                           |   1 +
>   config/common_base                               |  10 +
>   doc/guides/rel_notes/deprecation.rst             |  10 +
>   doc/guides/rel_notes/release_17_11.rst           |  28 +
>   drivers/Makefile                                 |   2 +-
>   drivers/bus/Makefile                             |   2 +
>   drivers/bus/pci/Makefile                         |  59 ++
>   drivers/bus/pci/bsd/Makefile                     |  32 +
>   drivers/bus/pci/bsd/rte_pci.c                    | 671 +++++++++++++++++++++
>   drivers/bus/pci/include/rte_bus_pci.h            | 387 ++++++++++++
>   drivers/bus/pci/linux/Makefile                   |  37 ++
>   drivers/bus/pci/linux/rte_pci.c                  | 723 +++++++++++++++++++++++
>   drivers/bus/pci/linux/rte_pci_init.h             |  97 +++
>   drivers/bus/pci/linux/rte_pci_uio.c              | 568 ++++++++++++++++++
>   drivers/bus/pci/linux/rte_pci_vfio.c             | 675 +++++++++++++++++++++
>   drivers/bus/pci/linux/rte_vfio_mp_sync.c         | 425 +++++++++++++
>   drivers/bus/pci/private.h                        | 174 ++++++
>   drivers/bus/pci/rte_bus_pci_version.map          |  21 +
>   drivers/bus/pci/rte_pci_common.c                 | 543 +++++++++++++++++
>   drivers/bus/pci/rte_pci_common_uio.c             | 235 ++++++++
>   drivers/crypto/Makefile                          |   4 +-
>   drivers/crypto/pci/Makefile                      |  52 ++
>   drivers/crypto/pci/rte_cryptodev_pci.c           | 128 ++++
>   drivers/crypto/pci/rte_cryptodev_pci.h           |  94 +++
>   drivers/crypto/pci/rte_cryptodev_pci_version.map |   7 +
>   drivers/crypto/qat/qat_qp.c                      |   1 +
>   drivers/event/octeontx/ssovf_probe.c             |   1 +
>   drivers/net/ark/ark_ethdev.c                     |   1 +
>   drivers/net/avp/avp_ethdev.c                     |   2 +
>   drivers/net/bnxt/bnxt.h                          |   1 +
>   drivers/net/bonding/rte_eth_bond_args.c          |   1 +
>   drivers/net/cxgbe/base/adapter.h                 |   1 +
>   drivers/net/cxgbe/cxgbe_ethdev.c                 |   1 +
>   drivers/net/e1000/em_ethdev.c                    |   1 +
>   drivers/net/e1000/igb_ethdev.c                   |   1 +
>   drivers/net/e1000/igb_pf.c                       |   1 +
>   drivers/net/ena/ena_ethdev.h                     |   1 +
>   drivers/net/enic/base/vnic_dev.h                 |   4 +-
>   drivers/net/enic/enic_ethdev.c                   |   1 +
>   drivers/net/enic/enic_main.c                     |   1 +
>   drivers/net/i40e/i40e_ethdev.c                   |   1 +
>   drivers/net/i40e/i40e_ethdev_vf.c                |   1 +
>   drivers/net/ixgbe/ixgbe_ethdev.c                 |   1 +
>   drivers/net/ixgbe/ixgbe_ethdev.h                 |   1 +
>   drivers/net/mlx5/mlx5.c                          |   1 +
>   drivers/net/mlx5/mlx5_ethdev.c                   |   1 +
>   drivers/net/sfc/sfc.h                            |   1 +
>   drivers/net/sfc/sfc_ethdev.c                     |   1 +
>   drivers/net/thunderx/nicvf_ethdev.c              |   1 +
>   drivers/net/virtio/virtio_ethdev.c               |   1 +
>   drivers/net/virtio/virtio_pci.h                  |   1 +
>   drivers/net/vmxnet3/vmxnet3_ethdev.c             |   1 +
>   lib/Makefile                                     |   2 +
>   lib/librte_cryptodev/Makefile                    |   1 -
>   lib/librte_cryptodev/rte_cryptodev_pci.h         |  92 ---
>   lib/librte_cryptodev/rte_cryptodev_pmd.c         |  94 ---
>   lib/librte_cryptodev/rte_cryptodev_version.map   |   2 -
>   lib/librte_eal/bsdapp/eal/Makefile               |   3 -
>   lib/librte_eal/bsdapp/eal/eal.c                  |   1 -
>   lib/librte_eal/bsdapp/eal/eal_memory.c           |   6 +
>   lib/librte_eal/bsdapp/eal/eal_pci.c              | 670 ---------------------
>   lib/librte_eal/bsdapp/eal/rte_eal_version.map    |  16 +-
>   lib/librte_eal/common/Makefile                   |   2 +-
>   lib/librte_eal/common/eal_common_bus.c           |   1 +
>   lib/librte_eal/common/eal_common_pci.c           | 580 ------------------
>   lib/librte_eal/common/eal_common_pci_uio.c       | 233 --------
>   lib/librte_eal/common/eal_private.h              | 143 -----
>   lib/librte_eal/common/include/rte_memory.h       |  11 +
>   lib/librte_eal/common/include/rte_pci.h          | 598 -------------------
>   lib/librte_eal/linuxapp/eal/Makefile             |  10 -
>   lib/librte_eal/linuxapp/eal/eal.c                |   1 -
>   lib/librte_eal/linuxapp/eal/eal_interrupts.c     |   1 -
>   lib/librte_eal/linuxapp/eal/eal_memory.c         |   2 +-
>   lib/librte_eal/linuxapp/eal/eal_pci.c            | 722 ----------------------
>   lib/librte_eal/linuxapp/eal/eal_pci_init.h       |  97 ---
>   lib/librte_eal/linuxapp/eal/eal_pci_uio.c        | 567 ------------------
>   lib/librte_eal/linuxapp/eal/eal_pci_vfio.c       | 674 ---------------------
>   lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c   | 424 -------------
>   lib/librte_eal/linuxapp/eal/rte_eal_version.map  |  16 +-
>   lib/librte_ether/rte_ethdev.c                    |   1 -
>   lib/librte_ether/rte_ethdev.h                    |   2 -
>   lib/librte_ether/rte_ethdev_pci.h                |   1 +
>   lib/librte_eventdev/rte_eventdev_pmd_pci.h       |   1 +
>   lib/librte_pci/Makefile                          |  48 ++
>   lib/librte_pci/include/rte_pci.h                 | 285 +++++++++
>   lib/librte_pci/rte_pci.c                         | 210 +++++++
>   lib/librte_pci/rte_pci_version.map               |  16 +
>   mk/rte.app.mk                                    |   3 +
>   test/test/test_kni.c                             |   1 +
>   test/test/virtual_pmd.c                          |   1 +
>   90 files changed, 5603 insertions(+), 4951 deletions(-)
>   create mode 100644 drivers/bus/pci/Makefile
>   create mode 100644 drivers/bus/pci/bsd/Makefile
>   create mode 100644 drivers/bus/pci/bsd/rte_pci.c
>   create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
>   create mode 100644 drivers/bus/pci/linux/Makefile
>   create mode 100644 drivers/bus/pci/linux/rte_pci.c
>   create mode 100644 drivers/bus/pci/linux/rte_pci_init.h
>   create mode 100644 drivers/bus/pci/linux/rte_pci_uio.c
>   create mode 100644 drivers/bus/pci/linux/rte_pci_vfio.c
>   create mode 100644 drivers/bus/pci/linux/rte_vfio_mp_sync.c
>   create mode 100644 drivers/bus/pci/private.h
>   create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
>   create mode 100644 drivers/bus/pci/rte_pci_common.c
>   create mode 100644 drivers/bus/pci/rte_pci_common_uio.c
>   create mode 100644 drivers/crypto/pci/Makefile
>   create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.c
>   create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.h
>   create mode 100644 drivers/crypto/pci/rte_cryptodev_pci_version.map
>   delete mode 100644 lib/librte_cryptodev/rte_cryptodev_pci.h
>   delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
>   delete mode 100644 lib/librte_eal/common/eal_common_pci.c
>   delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
>   delete mode 100644 lib/librte_eal/common/include/rte_pci.h
>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
>   delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
>   create mode 100644 lib/librte_pci/Makefile
>   create mode 100644 lib/librte_pci/include/rte_pci.h
>   create mode 100644 lib/librte_pci/rte_pci.c
>   create mode 100644 lib/librte_pci/rte_pci_version.map
> 

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL
  2017-10-11 14:19   ` [dpdk-dev] [PATCH v2 00/14] " Doherty, Declan
@ 2017-10-11 14:32     ` Gaëtan Rivet
  2017-10-23  8:44       ` De Lara Guarch, Pablo
  0 siblings, 1 reply; 156+ messages in thread
From: Gaëtan Rivet @ 2017-10-11 14:32 UTC (permalink / raw)
  To: Doherty, Declan; +Cc: dev

On Wed, Oct 11, 2017 at 03:19:31PM +0100, Doherty, Declan wrote:
> On 18/09/2017 10:31 AM, Gaetan Rivet wrote:
> >Hi all,
> >
> >Here is a new version of the PCI bus move out of the EAL.
> >
> >The EAL PCI implementation is divided in two parts:
> >
> >   - librte_pci: library offering helpers to handle PCI objects
> >   - librte_bus_pci: bus driver for PCI devices
> >
> >This allows other libraries / tools to use PCI elements (location, mappings,
> >parsing operations, etc) without forcing a dependency on a bus driver.
> >
> >The latter should not have to export helpers that others might need. It
> >is focused on defining the rte_pci_device, rte_pci_driver objects and
> >their handling.
> >
> >The cryptodev library has hard dependencies on rte_pci_devices (used by
> >generic probe function). Other similar libs (ether and eventdev) avoided
> >the issue by inlining such functions and expecting users to include the
> >relevant headers once the PCI bus has already been built.
> >
> >@Declan:
> >I proposed a solution that would avoid inlining those functions,
> >which does not feel right. Let me know what you think of it or if you
> >think of a better solution. I think it would be best to have cryptodev
> >completely independent from PCI / vdev as far as the lib in concerned
> >(the vdev bus will move as well).
> >
> 
> 
> Hey Gaetan, apologies for the delay in getting back to you on this, I had
> been looking at this but got sidelined onto other issues before usersapce
> and I'm only getting back to it now. I think that while your solution works
> it just highlights the dependency which probably shouldn't be there between
> the cryptodev library and PCI devices. I've had a look, and the functions in
> the cryptodev which you moved don't really provide that much useful
> functionality. I done some testing and completely removed them and just
> update the QAT PMD which is the only crypto PMD which was using them and it
> seems much cleaner to me. I'll push a patch for this change later today and
> it will allow you to drop the patch "cryptodev: move PCI specific helpers to
> drivers/crypto" from this set.
> 
> Regards
> Declan
> 
> 
> 

Hi Declan,

All right, seems good from my PoV. I will rebase onto your patch once
it is sent.

> >v2:
> >
> >   + Made rte_eal_using_phys_addrs common to both linux and bsd interfaces.
> >   + Added documentation of EAL API changes in release note.
> >   + Fixed a few rebase-related mistakes.
> >   + Fixed parallel build race condition reported by Luca Boccassi.
> >   + Grouped together commits breaking compilation:
> >
> >     -> pci: introduce PCI lib and bus
> >     -> lib: include rte_bus_pci
> >     -> drivers: include rte_bus_pci
> >     -> test: include rte_bus_pci
> >     -> app/testpmd: include rte_bus_pci
> >     -> cryptodev: move PCI specific helpers to drivers/crypto
> >
> >   Until all of them have been applied, compilation is broken.
> >   I am currently wondering whether merging some of them might
> >   be sensible.
> >
> >   + Not included in this series:
> >
> >     Several filesystem-related functions are currently
> >     private to the EAL and directly linked. This is not good,
> >     but the solution seems to be to have a new lib offering an FS abstraction.
> >     This seems an overreach for this patchset and should probably come in a
> >     second step.
> >
> >Gaetan Rivet (14):
> >   eal: expose rte_eal_using_phys_addrs
> >   ethdev: remove useless PCI dependency
> >   bus: properly include rte_debug
> >   eal: remove references to PCI
> >   pci: introduce PCI lib and bus
> >   lib: include rte_bus_pci
> >   drivers: include rte_bus_pci
> >   test: include rte_bus_pci
> >   app/testpmd: include rte_bus_pci
> >   cryptodev: move PCI specific helpers to drivers/crypto
> >   pci: avoid inlining functions
> >   pci: avoid over-complicated macro
> >   pci: deprecate misnamed functions
> >   doc: add notes on EAL PCI API update
> >
> >  app/test-pmd/testpmd.h                           |   1 +
> >  config/common_base                               |  10 +
> >  doc/guides/rel_notes/deprecation.rst             |  10 +
> >  doc/guides/rel_notes/release_17_11.rst           |  28 +
> >  drivers/Makefile                                 |   2 +-
> >  drivers/bus/Makefile                             |   2 +
> >  drivers/bus/pci/Makefile                         |  59 ++
> >  drivers/bus/pci/bsd/Makefile                     |  32 +
> >  drivers/bus/pci/bsd/rte_pci.c                    | 671 +++++++++++++++++++++
> >  drivers/bus/pci/include/rte_bus_pci.h            | 387 ++++++++++++
> >  drivers/bus/pci/linux/Makefile                   |  37 ++
> >  drivers/bus/pci/linux/rte_pci.c                  | 723 +++++++++++++++++++++++
> >  drivers/bus/pci/linux/rte_pci_init.h             |  97 +++
> >  drivers/bus/pci/linux/rte_pci_uio.c              | 568 ++++++++++++++++++
> >  drivers/bus/pci/linux/rte_pci_vfio.c             | 675 +++++++++++++++++++++
> >  drivers/bus/pci/linux/rte_vfio_mp_sync.c         | 425 +++++++++++++
> >  drivers/bus/pci/private.h                        | 174 ++++++
> >  drivers/bus/pci/rte_bus_pci_version.map          |  21 +
> >  drivers/bus/pci/rte_pci_common.c                 | 543 +++++++++++++++++
> >  drivers/bus/pci/rte_pci_common_uio.c             | 235 ++++++++
> >  drivers/crypto/Makefile                          |   4 +-
> >  drivers/crypto/pci/Makefile                      |  52 ++
> >  drivers/crypto/pci/rte_cryptodev_pci.c           | 128 ++++
> >  drivers/crypto/pci/rte_cryptodev_pci.h           |  94 +++
> >  drivers/crypto/pci/rte_cryptodev_pci_version.map |   7 +
> >  drivers/crypto/qat/qat_qp.c                      |   1 +
> >  drivers/event/octeontx/ssovf_probe.c             |   1 +
> >  drivers/net/ark/ark_ethdev.c                     |   1 +
> >  drivers/net/avp/avp_ethdev.c                     |   2 +
> >  drivers/net/bnxt/bnxt.h                          |   1 +
> >  drivers/net/bonding/rte_eth_bond_args.c          |   1 +
> >  drivers/net/cxgbe/base/adapter.h                 |   1 +
> >  drivers/net/cxgbe/cxgbe_ethdev.c                 |   1 +
> >  drivers/net/e1000/em_ethdev.c                    |   1 +
> >  drivers/net/e1000/igb_ethdev.c                   |   1 +
> >  drivers/net/e1000/igb_pf.c                       |   1 +
> >  drivers/net/ena/ena_ethdev.h                     |   1 +
> >  drivers/net/enic/base/vnic_dev.h                 |   4 +-
> >  drivers/net/enic/enic_ethdev.c                   |   1 +
> >  drivers/net/enic/enic_main.c                     |   1 +
> >  drivers/net/i40e/i40e_ethdev.c                   |   1 +
> >  drivers/net/i40e/i40e_ethdev_vf.c                |   1 +
> >  drivers/net/ixgbe/ixgbe_ethdev.c                 |   1 +
> >  drivers/net/ixgbe/ixgbe_ethdev.h                 |   1 +
> >  drivers/net/mlx5/mlx5.c                          |   1 +
> >  drivers/net/mlx5/mlx5_ethdev.c                   |   1 +
> >  drivers/net/sfc/sfc.h                            |   1 +
> >  drivers/net/sfc/sfc_ethdev.c                     |   1 +
> >  drivers/net/thunderx/nicvf_ethdev.c              |   1 +
> >  drivers/net/virtio/virtio_ethdev.c               |   1 +
> >  drivers/net/virtio/virtio_pci.h                  |   1 +
> >  drivers/net/vmxnet3/vmxnet3_ethdev.c             |   1 +
> >  lib/Makefile                                     |   2 +
> >  lib/librte_cryptodev/Makefile                    |   1 -
> >  lib/librte_cryptodev/rte_cryptodev_pci.h         |  92 ---
> >  lib/librte_cryptodev/rte_cryptodev_pmd.c         |  94 ---
> >  lib/librte_cryptodev/rte_cryptodev_version.map   |   2 -
> >  lib/librte_eal/bsdapp/eal/Makefile               |   3 -
> >  lib/librte_eal/bsdapp/eal/eal.c                  |   1 -
> >  lib/librte_eal/bsdapp/eal/eal_memory.c           |   6 +
> >  lib/librte_eal/bsdapp/eal/eal_pci.c              | 670 ---------------------
> >  lib/librte_eal/bsdapp/eal/rte_eal_version.map    |  16 +-
> >  lib/librte_eal/common/Makefile                   |   2 +-
> >  lib/librte_eal/common/eal_common_bus.c           |   1 +
> >  lib/librte_eal/common/eal_common_pci.c           | 580 ------------------
> >  lib/librte_eal/common/eal_common_pci_uio.c       | 233 --------
> >  lib/librte_eal/common/eal_private.h              | 143 -----
> >  lib/librte_eal/common/include/rte_memory.h       |  11 +
> >  lib/librte_eal/common/include/rte_pci.h          | 598 -------------------
> >  lib/librte_eal/linuxapp/eal/Makefile             |  10 -
> >  lib/librte_eal/linuxapp/eal/eal.c                |   1 -
> >  lib/librte_eal/linuxapp/eal/eal_interrupts.c     |   1 -
> >  lib/librte_eal/linuxapp/eal/eal_memory.c         |   2 +-
> >  lib/librte_eal/linuxapp/eal/eal_pci.c            | 722 ----------------------
> >  lib/librte_eal/linuxapp/eal/eal_pci_init.h       |  97 ---
> >  lib/librte_eal/linuxapp/eal/eal_pci_uio.c        | 567 ------------------
> >  lib/librte_eal/linuxapp/eal/eal_pci_vfio.c       | 674 ---------------------
> >  lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c   | 424 -------------
> >  lib/librte_eal/linuxapp/eal/rte_eal_version.map  |  16 +-
> >  lib/librte_ether/rte_ethdev.c                    |   1 -
> >  lib/librte_ether/rte_ethdev.h                    |   2 -
> >  lib/librte_ether/rte_ethdev_pci.h                |   1 +
> >  lib/librte_eventdev/rte_eventdev_pmd_pci.h       |   1 +
> >  lib/librte_pci/Makefile                          |  48 ++
> >  lib/librte_pci/include/rte_pci.h                 | 285 +++++++++
> >  lib/librte_pci/rte_pci.c                         | 210 +++++++
> >  lib/librte_pci/rte_pci_version.map               |  16 +
> >  mk/rte.app.mk                                    |   3 +
> >  test/test/test_kni.c                             |   1 +
> >  test/test/virtual_pmd.c                          |   1 +
> >  90 files changed, 5603 insertions(+), 4951 deletions(-)
> >  create mode 100644 drivers/bus/pci/Makefile
> >  create mode 100644 drivers/bus/pci/bsd/Makefile
> >  create mode 100644 drivers/bus/pci/bsd/rte_pci.c
> >  create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
> >  create mode 100644 drivers/bus/pci/linux/Makefile
> >  create mode 100644 drivers/bus/pci/linux/rte_pci.c
> >  create mode 100644 drivers/bus/pci/linux/rte_pci_init.h
> >  create mode 100644 drivers/bus/pci/linux/rte_pci_uio.c
> >  create mode 100644 drivers/bus/pci/linux/rte_pci_vfio.c
> >  create mode 100644 drivers/bus/pci/linux/rte_vfio_mp_sync.c
> >  create mode 100644 drivers/bus/pci/private.h
> >  create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
> >  create mode 100644 drivers/bus/pci/rte_pci_common.c
> >  create mode 100644 drivers/bus/pci/rte_pci_common_uio.c
> >  create mode 100644 drivers/crypto/pci/Makefile
> >  create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.c
> >  create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.h
> >  create mode 100644 drivers/crypto/pci/rte_cryptodev_pci_version.map
> >  delete mode 100644 lib/librte_cryptodev/rte_cryptodev_pci.h
> >  delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
> >  delete mode 100644 lib/librte_eal/common/eal_common_pci.c
> >  delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
> >  delete mode 100644 lib/librte_eal/common/include/rte_pci.h
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
> >  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
> >  create mode 100644 lib/librte_pci/Makefile
> >  create mode 100644 lib/librte_pci/include/rte_pci.h
> >  create mode 100644 lib/librte_pci/rte_pci.c
> >  create mode 100644 lib/librte_pci/rte_pci_version.map
> >
> 

-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL
  2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
                       ` (12 preceding siblings ...)
  2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 13/13] doc: add notes on EAL PCI API update Gaetan Rivet
@ 2017-10-12  8:17     ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 01/16] eal: include debug header in bus source Gaetan Rivet
                         ` (16 more replies)
  13 siblings, 17 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Hi all,

Here is a new version of the PCI bus move out of the EAL.

The EAL PCI implementation is divided in two parts:

  - librte_pci: library offering helpers to handle PCI objects
  - librte_bus_pci: bus driver for PCI devices

This allows other libraries / tools to use PCI elements (location, mappings,
parsing operations, etc) without forcing a dependency on a bus driver.

The latter should not have to export helpers that others might need. It
is focused on defining the rte_pci_device, rte_pci_driver objects and
their handling.

The cryptodev library has hard dependencies on rte_pci_devices (used by
generic probe function). Other similar libs (ether and eventdev) avoided
the issue by inlining such functions and expecting users to include the
relevant headers once the PCI bus has already been built.

After review from Declan, he proposed to submit a patch removing this dependency.
Once this patch is submitted, the relevant commit will be dropped from this
patchset.

v2:

  + Made rte_eal_using_phys_addrs common to both linux and bsd interfaces.
  + Added documentation of EAL API changes in release note.
  + Fixed a few rebase-related mistakes.
  + Fixed parallel build race condition reported by Luca Boccassi.
  + Grouped together commits breaking compilation:

    -> pci: introduce PCI lib and bus
    -> lib: include rte_bus_pci
    -> drivers: include rte_bus_pci
    -> test: include rte_bus_pci
    -> app/testpmd: include rte_bus_pci
    -> cryptodev: move PCI specific helpers to drivers/crypto

  Until all of them have been applied, compilation is broken.
  I am currently wondering whether merging some of them might
  be sensible.

  + Not included in this series:

    Several filesystem-related functions are currently
    private to the EAL and directly linked. This is not good,
    but the solution seems to be to have a new lib offering an FS abstraction.
    This seems an overreach for this patchset and should probably come in a
    second step.

v3:

  + Fixed .map versioning
  + merged one commit breaking the build into the main commit moving
    code around.

    Other such commits are still present, as they only break specific subsystems
    (lib, drivers, apps, cryptodev). Merging them all within the one main commit
    does not seem right.

    As such, build is still broken from

       * pci: introduce PCI lib and bus

    until

       * cryptodev: move PCI specific helpers to drivers/crypto

v4:

  + Rebased unto master, with new PCI functionalities integrated.
  + Removed the exposition of private EAL functions.
    While one commit did deal with this for one function, the issue is more
    widespread and should be fixed in a more generic way.
  + Introduced new PCI address parsing function,
    deprecating the old ones.
  + Fix conflict with bonding PMD regarding pci_addr_cmp function name.

    Compilation is still broken from

       * pci: introduce PCI lib and bus

    until

       * net/bonding: use local prefix for local function

Gaetan Rivet (16):
  eal: include debug header in bus source
  ethdev: remove useless PCI dependency
  pci: introduce PCI lib and bus
  lib: include PCI bus header
  drivers: include PCI bus header
  test: include PCI bus header
  app/testpmd: include PCI bus header
  cryptodev: move PCI specific helpers to drivers/crypto
  net/bonding: use local prefix for local function
  pci: avoid inlining functions
  pci: avoid over-complicated macro
  pci: deprecate misnamed functions
  pci: introduce PCI address parsing function
  pci: make specialized parsing functions private
  bus/pci: use new PCI addr parsing function
  doc: add notes on EAL PCI API update

 app/test-pmd/testpmd.h                           |   1 +
 config/common_base                               |  10 +
 doc/guides/rel_notes/deprecation.rst             |  10 +
 doc/guides/rel_notes/release_17_11.rst           |  28 +
 drivers/bus/Makefile                             |   2 +
 drivers/bus/pci/Makefile                         |  59 ++
 drivers/bus/pci/bsd/Makefile                     |  32 +
 drivers/bus/pci/bsd/pci.c                        | 681 +++++++++++++++++++
 drivers/bus/pci/include/rte_bus_pci.h            | 415 ++++++++++++
 drivers/bus/pci/linux/Makefile                   |  37 +
 drivers/bus/pci/linux/pci.c                      | 821 +++++++++++++++++++++++
 drivers/bus/pci/linux/pci_init.h                 |  97 +++
 drivers/bus/pci/linux/pci_uio.c                  | 568 ++++++++++++++++
 drivers/bus/pci/linux/pci_vfio.c                 | 757 +++++++++++++++++++++
 drivers/bus/pci/linux/vfio_mp_sync.c             | 426 ++++++++++++
 drivers/bus/pci/pci_common.c                     | 535 +++++++++++++++
 drivers/bus/pci/pci_common_uio.c                 | 235 +++++++
 drivers/bus/pci/private.h                        | 174 +++++
 drivers/bus/pci/rte_bus_pci_version.map          |  21 +
 drivers/crypto/Makefile                          |   4 +-
 drivers/crypto/pci/Makefile                      |  52 ++
 drivers/crypto/pci/rte_cryptodev_pci.c           | 128 ++++
 drivers/crypto/pci/rte_cryptodev_pci.h           |  94 +++
 drivers/crypto/pci/rte_cryptodev_pci_version.map |   7 +
 drivers/crypto/qat/qat_qp.c                      |   1 +
 drivers/event/octeontx/ssovf_probe.c             |   1 +
 drivers/mempool/octeontx/octeontx_fpavf.c        |   2 +-
 drivers/net/ark/ark_ethdev.c                     |   1 +
 drivers/net/avp/avp_ethdev.c                     |   2 +
 drivers/net/bnxt/bnxt.h                          |   1 +
 drivers/net/bonding/rte_eth_bond_args.c          |   5 +-
 drivers/net/cxgbe/base/adapter.h                 |   1 +
 drivers/net/cxgbe/cxgbe_ethdev.c                 |   1 +
 drivers/net/e1000/em_ethdev.c                    |   1 +
 drivers/net/e1000/igb_ethdev.c                   |   1 +
 drivers/net/e1000/igb_pf.c                       |   1 +
 drivers/net/ena/ena_ethdev.h                     |   1 +
 drivers/net/enic/base/vnic_dev.h                 |   4 +-
 drivers/net/enic/enic_ethdev.c                   |   1 +
 drivers/net/enic/enic_main.c                     |   1 +
 drivers/net/i40e/i40e_ethdev.c                   |   1 +
 drivers/net/i40e/i40e_ethdev_vf.c                |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c                 |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.h                 |   1 +
 drivers/net/mlx4/mlx4_ethdev.c                   |   2 +-
 drivers/net/mlx5/mlx5.c                          |   1 +
 drivers/net/mlx5/mlx5_ethdev.c                   |   1 +
 drivers/net/nfp/nfp_nfpu.c                       |   2 +-
 drivers/net/nfp/nfp_nfpu.h                       |   2 +-
 drivers/net/octeontx/base/octeontx_pkivf.c       |   2 +-
 drivers/net/octeontx/base/octeontx_pkovf.c       |   2 +-
 drivers/net/sfc/sfc.h                            |   1 +
 drivers/net/sfc/sfc_ethdev.c                     |   1 +
 drivers/net/thunderx/nicvf_ethdev.c              |   1 +
 drivers/net/virtio/virtio_ethdev.c               |   1 +
 drivers/net/virtio/virtio_pci.h                  |   1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c             |   1 +
 lib/Makefile                                     |   2 +
 lib/librte_cryptodev/Makefile                    |   1 -
 lib/librte_cryptodev/rte_cryptodev_pci.h         |  92 ---
 lib/librte_cryptodev/rte_cryptodev_pmd.c         |  94 ---
 lib/librte_cryptodev/rte_cryptodev_version.map   |   2 -
 lib/librte_eal/bsdapp/eal/Makefile               |   3 -
 lib/librte_eal/bsdapp/eal/eal.c                  |   1 -
 lib/librte_eal/bsdapp/eal/eal_pci.c              | 680 -------------------
 lib/librte_eal/bsdapp/eal/rte_eal_version.map    |  15 -
 lib/librte_eal/common/Makefile                   |   2 +-
 lib/librte_eal/common/eal_common_bus.c           |   1 +
 lib/librte_eal/common/eal_common_pci.c           | 573 ----------------
 lib/librte_eal/common/eal_common_pci_uio.c       | 233 -------
 lib/librte_eal/common/eal_private.h              | 132 ----
 lib/librte_eal/common/include/rte_pci.h          | 633 -----------------
 lib/librte_eal/linuxapp/eal/Makefile             |  10 -
 lib/librte_eal/linuxapp/eal/eal.c                |   1 -
 lib/librte_eal/linuxapp/eal/eal_interrupts.c     |   1 -
 lib/librte_eal/linuxapp/eal/eal_pci.c            | 818 ----------------------
 lib/librte_eal/linuxapp/eal/eal_pci_init.h       |  97 ---
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c        | 567 ----------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c       | 756 ---------------------
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c   | 425 ------------
 lib/librte_eal/linuxapp/eal/rte_eal_version.map  |  15 -
 lib/librte_ether/rte_ethdev.c                    |   1 -
 lib/librte_ether/rte_ethdev.h                    |   2 -
 lib/librte_ether/rte_ethdev_pci.h                |   1 +
 lib/librte_eventdev/rte_eventdev_pmd_pci.h       |   1 +
 lib/librte_pci/Makefile                          |  48 ++
 lib/librte_pci/include/rte_pci.h                 | 279 ++++++++
 lib/librte_pci/rte_pci.c                         | 220 ++++++
 lib/librte_pci/rte_pci_version.map               |  15 +
 mk/rte.app.mk                                    |   3 +
 test/test/test_kni.c                             |   1 +
 test/test/virtual_pmd.c                          |   1 +
 92 files changed, 5804 insertions(+), 5163 deletions(-)
 create mode 100644 drivers/bus/pci/Makefile
 create mode 100644 drivers/bus/pci/bsd/Makefile
 create mode 100644 drivers/bus/pci/bsd/pci.c
 create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
 create mode 100644 drivers/bus/pci/linux/Makefile
 create mode 100644 drivers/bus/pci/linux/pci.c
 create mode 100644 drivers/bus/pci/linux/pci_init.h
 create mode 100644 drivers/bus/pci/linux/pci_uio.c
 create mode 100644 drivers/bus/pci/linux/pci_vfio.c
 create mode 100644 drivers/bus/pci/linux/vfio_mp_sync.c
 create mode 100644 drivers/bus/pci/pci_common.c
 create mode 100644 drivers/bus/pci/pci_common_uio.c
 create mode 100644 drivers/bus/pci/private.h
 create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
 create mode 100644 drivers/crypto/pci/Makefile
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.c
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.h
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci_version.map
 delete mode 100644 lib/librte_cryptodev/rte_cryptodev_pci.h
 delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
 delete mode 100644 lib/librte_eal/common/include/rte_pci.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
 create mode 100644 lib/librte_pci/Makefile
 create mode 100644 lib/librte_pci/include/rte_pci.h
 create mode 100644 lib/librte_pci/rte_pci.c
 create mode 100644 lib/librte_pci/rte_pci_version.map

-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 01/16] eal: include debug header in bus source
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 02/16] ethdev: remove useless PCI dependency Gaetan Rivet
                         ` (15 subsequent siblings)
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

This header is included through rte_pci.h, which will be removed once
the PCI bus is moved out of the EAL.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_bus.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
index c3c77f4..3c66a02 100644
--- a/lib/librte_eal/common/eal_common_bus.c
+++ b/lib/librte_eal/common/eal_common_bus.c
@@ -35,6 +35,7 @@
 #include <sys/queue.h>
 
 #include <rte_bus.h>
+#include <rte_debug.h>
 
 #include "eal_private.h"
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 02/16] ethdev: remove useless PCI dependency
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 01/16] eal: include debug header in bus source Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 03/16] pci: introduce PCI lib and bus Gaetan Rivet
                         ` (14 subsequent siblings)
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ether/rte_ethdev.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 9460161..bb08204 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -47,7 +47,6 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_interrupts.h>
-#include <rte_pci.h>
 #include <rte_memory.h>
 #include <rte_memcpy.h>
 #include <rte_memzone.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 03/16] pci: introduce PCI lib and bus
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 01/16] eal: include debug header in bus source Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 02/16] ethdev: remove useless PCI dependency Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 04/16] lib: include PCI bus header Gaetan Rivet
                         ` (13 subsequent siblings)
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

The PCI lib defines the types and methods allowing to use PCI elements.

The PCI bus implements a bus driver for PCI devices by constructing
rte_bus elements using the PCI lib.

Move the relevant code out of the EAL to its expected place.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 config/common_base                              |  10 +
 drivers/bus/Makefile                            |   2 +
 drivers/bus/pci/Makefile                        |  59 ++
 drivers/bus/pci/bsd/Makefile                    |  32 +
 drivers/bus/pci/bsd/pci.c                       | 680 ++++++++++++++++++++
 drivers/bus/pci/include/rte_bus_pci.h           | 415 ++++++++++++
 drivers/bus/pci/linux/Makefile                  |  37 ++
 drivers/bus/pci/linux/pci.c                     | 820 ++++++++++++++++++++++++
 drivers/bus/pci/linux/pci_init.h                |  97 +++
 drivers/bus/pci/linux/pci_uio.c                 | 567 ++++++++++++++++
 drivers/bus/pci/linux/pci_vfio.c                | 756 ++++++++++++++++++++++
 drivers/bus/pci/linux/vfio_mp_sync.c            | 425 ++++++++++++
 drivers/bus/pci/pci_common.c                    | 535 ++++++++++++++++
 drivers/bus/pci/pci_common_uio.c                | 234 +++++++
 drivers/bus/pci/private.h                       | 173 +++++
 drivers/bus/pci/rte_bus_pci_version.map         |  21 +
 lib/Makefile                                    |   2 +
 lib/librte_eal/bsdapp/eal/Makefile              |   3 -
 lib/librte_eal/bsdapp/eal/eal.c                 |   1 -
 lib/librte_eal/bsdapp/eal/eal_pci.c             | 680 --------------------
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  15 -
 lib/librte_eal/common/Makefile                  |   2 +-
 lib/librte_eal/common/eal_common_pci.c          | 573 -----------------
 lib/librte_eal/common/eal_common_pci_uio.c      | 233 -------
 lib/librte_eal/common/eal_private.h             | 132 ----
 lib/librte_eal/common/include/rte_pci.h         | 633 ------------------
 lib/librte_eal/linuxapp/eal/Makefile            |  10 -
 lib/librte_eal/linuxapp/eal/eal.c               |   1 -
 lib/librte_eal/linuxapp/eal/eal_interrupts.c    |   1 -
 lib/librte_eal/linuxapp/eal/eal_pci.c           | 818 -----------------------
 lib/librte_eal/linuxapp/eal/eal_pci_init.h      |  97 ---
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c       | 567 ----------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c      | 756 ----------------------
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c  | 425 ------------
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  15 -
 lib/librte_ether/rte_ethdev.h                   |   2 -
 lib/librte_pci/Makefile                         |  48 ++
 lib/librte_pci/include/rte_pci.h                | 287 +++++++++
 lib/librte_pci/rte_pci.c                        |  92 +++
 lib/librte_pci/rte_pci_version.map              |   8 +
 mk/rte.app.mk                                   |   3 +
 41 files changed, 5304 insertions(+), 4963 deletions(-)
 create mode 100644 drivers/bus/pci/Makefile
 create mode 100644 drivers/bus/pci/bsd/Makefile
 create mode 100644 drivers/bus/pci/bsd/pci.c
 create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
 create mode 100644 drivers/bus/pci/linux/Makefile
 create mode 100644 drivers/bus/pci/linux/pci.c
 create mode 100644 drivers/bus/pci/linux/pci_init.h
 create mode 100644 drivers/bus/pci/linux/pci_uio.c
 create mode 100644 drivers/bus/pci/linux/pci_vfio.c
 create mode 100644 drivers/bus/pci/linux/vfio_mp_sync.c
 create mode 100644 drivers/bus/pci/pci_common.c
 create mode 100644 drivers/bus/pci/pci_common_uio.c
 create mode 100644 drivers/bus/pci/private.h
 create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
 delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
 delete mode 100644 lib/librte_eal/common/include/rte_pci.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
 create mode 100644 lib/librte_pci/Makefile
 create mode 100644 lib/librte_pci/include/rte_pci.h
 create mode 100644 lib/librte_pci/rte_pci.c
 create mode 100644 lib/librte_pci/rte_pci_version.map

diff --git a/config/common_base b/config/common_base
index dc4da9a..39ec7f0 100644
--- a/config/common_base
+++ b/config/common_base
@@ -123,6 +123,11 @@ CONFIG_RTE_EAL_PMD_PATH=""
 CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
 
 #
+# Compile the PCI library
+#
+CONFIG_RTE_LIBRTE_PCI=y
+
+#
 # Compile the argument parser library
 #
 CONFIG_RTE_LIBRTE_KVARGS=y
@@ -148,6 +153,11 @@ CONFIG_RTE_ETHDEV_PROFILE_ITT_WASTED_RX_ITERATIONS=n
 CONFIG_RTE_ETHDEV_TX_PREPARE_NOOP=n
 
 #
+# Compile PCI bus driver
+#
+CONFIG_RTE_LIBRTE_PCI_BUS=y
+
+#
 # Compile burst-oriented Amazon ENA PMD driver
 #
 CONFIG_RTE_LIBRTE_ENA_PMD=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 6cb6466..40b9e96 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -37,5 +37,7 @@ DEPDIRS-dpaa = $(core-libs)
 
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DEPDIRS-fslmc = $(core-libs)
+DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
+DEPDIRS-pci = $(core-libs)
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/pci/Makefile b/drivers/bus/pci/Makefile
new file mode 100644
index 0000000..2260dd4
--- /dev/null
+++ b/drivers/bus/pci/Makefile
@@ -0,0 +1,59 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+LIB = librte_bus_pci.a
+LIBABIVER := 1
+EXPORT_MAP := rte_bus_pci_version.map
+
+CFLAGS := -I$(SRCDIR)/include -I$(SRCDIR) $(CFLAGS)
+CFLAGS += -O3 $(WERROR_FLAGS)
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),)
+SYSTEM := linux
+endif
+ifneq ($(CONFIG_RTE_EXEC_ENV_BSDAPP),)
+SYSTEM := bsd
+endif
+
+CFLAGS += -I$(RTE_SDK)/drivers/bus/pci/$(SYSTEM)
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/$(SYSTEM)app/eal
+
+include $(RTE_SDK)/drivers/bus/pci/$(SYSTEM)/Makefile
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) := $(addprefix $(SYSTEM)/,$(SRCS))
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci_common.c
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci_common_uio.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI_BUS)-include += include/rte_bus_pci.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/pci/bsd/Makefile b/drivers/bus/pci/bsd/Makefile
new file mode 100644
index 0000000..4450913
--- /dev/null
+++ b/drivers/bus/pci/bsd/Makefile
@@ -0,0 +1,32 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += pci.c
diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
new file mode 100644
index 0000000..599519a
--- /dev/null
+++ b/drivers/bus/pci/bsd/pci.c
@@ -0,0 +1,680 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/pciio.h>
+#include <dev/pci/pcireg.h>
+
+#if defined(RTE_ARCH_X86)
+#include <machine/cpufunc.h>
+#endif
+
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_common.h>
+#include <rte_launch.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+#include <rte_debug.h>
+#include <rte_devargs.h>
+
+#include "eal_filesystem.h"
+#include "private.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in
+ * sysfs. Moreover, when a registered driver matches a device, the
+ * kernel driver currently using it is unloaded and replaced by
+ * igb_uio module, which is a very minimal userland driver for Intel
+ * network card, only providing access to PCI BAR to applications, and
+ * enabling bus master.
+ */
+
+extern struct rte_pci_bus rte_pci_bus;
+
+/* Map pci device */
+int
+rte_pci_map_device(struct rte_pci_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources */
+	switch (dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		/* map resources for devices that use uio */
+		ret = pci_uio_map_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+/* Unmap pci device */
+void
+rte_pci_unmap_device(struct rte_pci_device *dev)
+{
+	/* try unmapping the NIC resources */
+	switch (dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		/* unmap resources for devices that use uio */
+		pci_uio_unmap_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+void
+pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res)
+{
+	rte_free(uio_res);
+
+	if (dev->intr_handle.fd) {
+		close(dev->intr_handle.fd);
+		dev->intr_handle.fd = -1;
+		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	}
+}
+
+int
+pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res)
+{
+	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+
+	snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
+			dev->addr.bus, dev->addr.devid, dev->addr.function);
+
+	if (access(devname, O_RDWR) < 0) {
+		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+		return 1;
+	}
+
+	/* save fd if in primary process */
+	dev->intr_handle.fd = open(devname, O_RDWR);
+	if (dev->intr_handle.fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			devname, strerror(errno));
+		goto error;
+	}
+	dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+
+	/* allocate the mapping details for secondary processes*/
+	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
+	if (*uio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto error;
+	}
+
+	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
+	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
+
+	return 0;
+
+error:
+	pci_uio_free_resource(dev, *uio_res);
+	return -1;
+}
+
+int
+pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx)
+{
+	int fd;
+	char *devname;
+	void *mapaddr;
+	uint64_t offset;
+	uint64_t pagesz;
+	struct pci_map *maps;
+
+	maps = uio_res->maps;
+	devname = uio_res->path;
+	pagesz = sysconf(_SC_PAGESIZE);
+
+	/* allocate memory to keep path */
+	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+	if (maps[map_idx].path == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+				strerror(errno));
+		return -1;
+	}
+
+	/*
+	 * open resource file, to mmap it
+	 */
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				devname, strerror(errno));
+		goto error;
+	}
+
+	/* if matching map is found, then use it */
+	offset = res_idx * pagesz;
+	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
+			(size_t)dev->mem_resource[res_idx].len, 0);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		goto error;
+
+	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+	maps[map_idx].size = dev->mem_resource[res_idx].len;
+	maps[map_idx].addr = mapaddr;
+	maps[map_idx].offset = offset;
+	strcpy(maps[map_idx].path, devname);
+	dev->mem_resource[res_idx].addr = mapaddr;
+
+	return 0;
+
+error:
+	rte_free(maps[map_idx].path);
+	return -1;
+}
+
+static int
+pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
+{
+	struct rte_pci_device *dev;
+	struct pci_bar_io bar;
+	unsigned i, max;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL) {
+		return -1;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr.domain = conf->pc_sel.pc_domain;
+	dev->addr.bus = conf->pc_sel.pc_bus;
+	dev->addr.devid = conf->pc_sel.pc_dev;
+	dev->addr.function = conf->pc_sel.pc_func;
+
+	/* get vendor id */
+	dev->id.vendor_id = conf->pc_vendor;
+
+	/* get device id */
+	dev->id.device_id = conf->pc_device;
+
+	/* get subsystem_vendor id */
+	dev->id.subsystem_vendor_id = conf->pc_subvendor;
+
+	/* get subsystem_device id */
+	dev->id.subsystem_device_id = conf->pc_subdevice;
+
+	/* get class id */
+	dev->id.class_id = (conf->pc_class << 16) |
+			   (conf->pc_subclass << 8) |
+			   (conf->pc_progif);
+
+	/* TODO: get max_vfs */
+	dev->max_vfs = 0;
+
+	/* FreeBSD has no NUMA support (yet) */
+	dev->device.numa_node = 0;
+
+	pci_name_set(dev);
+
+	/* FreeBSD has only one pass through driver */
+	dev->kdrv = RTE_KDRV_NIC_UIO;
+
+	/* parse resources */
+	switch (conf->pc_hdr & PCIM_HDRTYPE) {
+	case PCIM_HDRTYPE_NORMAL:
+		max = PCIR_MAX_BAR_0;
+		break;
+	case PCIM_HDRTYPE_BRIDGE:
+		max = PCIR_MAX_BAR_1;
+		break;
+	case PCIM_HDRTYPE_CARDBUS:
+		max = PCIR_MAX_BAR_2;
+		break;
+	default:
+		goto skipdev;
+	}
+
+	for (i = 0; i <= max; i++) {
+		bar.pbi_sel = conf->pc_sel;
+		bar.pbi_reg = PCIR_BAR(i);
+		if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
+			continue;
+
+		dev->mem_resource[i].len = bar.pbi_length;
+		if (PCI_BAR_IO(bar.pbi_base)) {
+			dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
+			continue;
+		}
+		dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
+	}
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
+		rte_pci_add_device(dev);
+	}
+	else {
+		struct rte_pci_device *dev2 = NULL;
+		int ret;
+
+		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
+			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+			else if (ret < 0) {
+				rte_pci_insert_device(dev2, dev);
+			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->max_vfs = dev->max_vfs;
+				pci_name_set(dev2);
+				memmove(dev2->mem_resource,
+					dev->mem_resource,
+					sizeof(dev->mem_resource));
+				free(dev);
+			}
+			return 0;
+		}
+		rte_pci_add_device(dev);
+	}
+
+	return 0;
+
+skipdev:
+	free(dev);
+	return 0;
+}
+
+/*
+ * Scan the content of the PCI bus, and add the devices in the devices
+ * list. Call pci_scan_one() for each pci entry found.
+ */
+int
+rte_pci_scan(void)
+{
+	int fd;
+	unsigned dev_count = 0;
+	struct pci_conf matches[16];
+	struct pci_conf_io conf_io = {
+			.pat_buf_len = 0,
+			.num_patterns = 0,
+			.patterns = NULL,
+			.match_buf_len = sizeof(matches),
+			.matches = &matches[0],
+	};
+
+	/* for debug purposes, PCI can be disabled */
+	if (internal_config.no_pci)
+		return 0;
+
+	fd = open("/dev/pci", O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	do {
+		unsigned i;
+		if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+			RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+					__func__, strerror(errno));
+			goto error;
+		}
+
+		for (i = 0; i < conf_io.num_matches; i++)
+			if (pci_scan_one(fd, &matches[i]) < 0)
+				goto error;
+
+		dev_count += conf_io.num_matches;
+	} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
+
+	close(fd);
+
+	RTE_LOG(DEBUG, EAL, "PCI scan found %u devices\n", dev_count);
+	return 0;
+
+error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/*
+ * Get iommu class of PCI devices on the bus.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void)
+{
+	/* Supports only RTE_KDRV_NIC_UIO */
+	return RTE_IOVA_PA;
+}
+
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+	int fd;
+	struct pci_conf matches[2];
+	struct pci_match_conf match = {
+		.pc_sel = {
+			.pc_domain = addr->domain,
+			.pc_bus = addr->bus,
+			.pc_dev = addr->devid,
+			.pc_func = addr->function,
+		},
+	};
+	struct pci_conf_io conf_io = {
+		.pat_buf_len = 0,
+		.num_patterns = 1,
+		.patterns = &match,
+		.match_buf_len = sizeof(matches),
+		.matches = &matches[0],
+	};
+
+	fd = open("/dev/pci", O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+				__func__, strerror(errno));
+		goto error;
+	}
+
+	if (conf_io.num_matches != 1)
+		goto error;
+
+	if (pci_scan_one(fd, &matches[0]) < 0)
+		goto error;
+
+	close(fd);
+
+	return 0;
+
+error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/* Read PCI config space. */
+int rte_pci_read_config(const struct rte_pci_device *dev,
+		void *buf, size_t len, off_t offset)
+{
+	int fd = -1;
+	int size;
+	struct pci_io pi = {
+		.pi_sel = {
+			.pc_domain = dev->addr.domain,
+			.pc_bus = dev->addr.bus,
+			.pc_dev = dev->addr.devid,
+			.pc_func = dev->addr.function,
+		},
+		.pi_reg = offset,
+	};
+
+	fd = open("/dev/pci", O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	while (len > 0) {
+		size = (len >= 4) ? 4 : ((len >= 2) ? 2 : 1);
+		pi.pi_width = size;
+
+		if (ioctl(fd, PCIOCREAD, &pi) < 0)
+			goto error;
+		memcpy(buf, &pi.pi_data, size);
+
+		buf = (char *)buf + size;
+		pi.pi_reg += size;
+		len -= size;
+	}
+	close(fd);
+
+	return 0;
+
+ error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/* Write PCI config space. */
+int rte_pci_write_config(const struct rte_pci_device *dev,
+		const void *buf, size_t len, off_t offset)
+{
+	int fd = -1;
+
+	struct pci_io pi = {
+		.pi_sel = {
+			.pc_domain = dev->addr.domain,
+			.pc_bus = dev->addr.bus,
+			.pc_dev = dev->addr.devid,
+			.pc_func = dev->addr.function,
+		},
+		.pi_reg = offset,
+		.pi_data = *(const uint32_t *)buf,
+		.pi_width = len,
+	};
+
+	if (len == 3 || len > sizeof(pi.pi_data)) {
+		RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__);
+		goto error;
+	}
+
+	memcpy(&pi.pi_data, buf, len);
+
+	fd = open("/dev/pci", O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	if (ioctl(fd, PCIOCWRITE, &pi) < 0)
+		goto error;
+
+	close(fd);
+	return 0;
+
+ error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+int
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p)
+{
+	int ret;
+
+	switch (dev->kdrv) {
+#if defined(RTE_ARCH_X86)
+	case RTE_KDRV_NIC_UIO:
+		if ((uintptr_t) dev->mem_resource[bar].addr <= UINT16_MAX) {
+			p->base = (uintptr_t)dev->mem_resource[bar].addr;
+			ret = 0;
+		} else
+			ret = -1;
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	if (!ret)
+		p->dev = dev;
+
+	return ret;
+}
+
+static void
+pci_uio_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+#if defined(RTE_ARCH_X86)
+	uint8_t *d;
+	int size;
+	unsigned short reg = p->base + offset;
+
+	for (d = data; len > 0; d += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+			*(uint32_t *)d = inl(reg);
+		} else if (len >= 2) {
+			size = 2;
+			*(uint16_t *)d = inw(reg);
+		} else {
+			size = 1;
+			*d = inb(reg);
+		}
+	}
+#else
+	RTE_SET_USED(p);
+	RTE_SET_USED(data);
+	RTE_SET_USED(len);
+	RTE_SET_USED(offset);
+#endif
+}
+
+void
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+pci_uio_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+#if defined(RTE_ARCH_X86)
+	const uint8_t *s;
+	int size;
+	unsigned short reg = p->base + offset;
+
+	for (s = data; len > 0; s += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+			outl(reg, *(const uint32_t *)s);
+		} else if (len >= 2) {
+			size = 2;
+			outw(reg, *(const uint16_t *)s);
+		} else {
+			size = 1;
+			outb(reg, *s);
+		}
+	}
+#else
+	RTE_SET_USED(p);
+	RTE_SET_USED(data);
+	RTE_SET_USED(len);
+	RTE_SET_USED(offset);
+#endif
+}
+
+void
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	default:
+		break;
+	}
+}
+
+int
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
+{
+	int ret;
+
+	switch (p->dev->kdrv) {
+#if defined(RTE_ARCH_X86)
+	case RTE_KDRV_NIC_UIO:
+		ret = 0;
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/bus/pci/include/rte_bus_pci.h b/drivers/bus/pci/include/rte_bus_pci.h
new file mode 100644
index 0000000..e6a7998
--- /dev/null
+++ b/drivers/bus/pci/include/rte_bus_pci.h
@@ -0,0 +1,415 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_BUS_PCI_H_
+#define _RTE_BUS_PCI_H_
+
+/**
+ * @file
+ *
+ * RTE PCI Bus Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+
+/** Pathname of PCI devices directory. */
+const char *pci_get_sysfs_path(void);
+
+/* Forward declarations */
+struct rte_pci_device;
+struct rte_pci_driver;
+
+/** List of PCI devices */
+TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
+/** List of PCI drivers */
+TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
+
+/* PCI Bus iterators */
+#define FOREACH_DEVICE_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
+
+#define FOREACH_DRIVER_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
+
+struct rte_devargs;
+
+/**
+ * A structure describing a PCI device.
+ */
+struct rte_pci_device {
+	TAILQ_ENTRY(rte_pci_device) next;   /**< Next probed PCI device. */
+	struct rte_device device;           /**< Inherit core device */
+	struct rte_pci_addr addr;           /**< PCI location. */
+	struct rte_pci_id id;               /**< PCI ID. */
+	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
+					    /**< PCI Memory Resource */
+	struct rte_intr_handle intr_handle; /**< Interrupt handle */
+	struct rte_pci_driver *driver;      /**< Associated driver */
+	uint16_t max_vfs;                   /**< sriov enable if not zero */
+	enum rte_kernel_driver kdrv;        /**< Kernel driver passthrough */
+	char name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_pci_device.
+ */
+#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
+
+#define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
+
+/** Any PCI device identifier (vendor, device, ...) */
+#define PCI_ANY_ID (0xffff)
+#define RTE_CLASS_ANY_ID (0xffffff)
+
+#ifdef __cplusplus
+/** C++ macro used to help building up tables of device IDs */
+#define RTE_PCI_DEVICE(vend, dev) \
+	RTE_CLASS_ANY_ID,         \
+	(vend),                   \
+	(dev),                    \
+	PCI_ANY_ID,               \
+	PCI_ANY_ID
+#else
+/** Macro used to help building up tables of device IDs */
+#define RTE_PCI_DEVICE(vend, dev)          \
+	.class_id = RTE_CLASS_ANY_ID,      \
+	.vendor_id = (vend),               \
+	.device_id = (dev),                \
+	.subsystem_vendor_id = PCI_ANY_ID, \
+	.subsystem_device_id = PCI_ANY_ID
+#endif
+
+/**
+ * Initialisation function for the driver called during PCI probing.
+ */
+typedef int (pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
+
+/**
+ * Uninitialisation function for the driver called during hotplugging.
+ */
+typedef int (pci_remove_t)(struct rte_pci_device *);
+
+/**
+ * A structure describing a PCI driver.
+ */
+struct rte_pci_driver {
+	TAILQ_ENTRY(rte_pci_driver) next;  /**< Next in list. */
+	struct rte_driver driver;          /**< Inherit core driver. */
+	struct rte_pci_bus *bus;           /**< PCI bus reference. */
+	pci_probe_t *probe;                /**< Device Probe function. */
+	pci_remove_t *remove;              /**< Device Remove function. */
+	const struct rte_pci_id *id_table; /**< ID table, NULL terminated. */
+	uint32_t drv_flags;                /**< Flags contolling handling of device. */
+};
+
+/**
+ * Structure describing the PCI bus
+ */
+struct rte_pci_bus {
+	struct rte_bus bus;               /**< Inherit the generic class */
+	struct rte_pci_device_list device_list;  /**< List of PCI devices */
+	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
+};
+
+/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
+#define RTE_PCI_DRV_NEED_MAPPING 0x0001
+/** Device driver supports link state interrupt */
+#define RTE_PCI_DRV_INTR_LSC	0x0008
+/** Device driver supports device removal interrupt */
+#define RTE_PCI_DRV_INTR_RMV 0x0010
+/** Device driver needs to keep mapped resources if unsupported dev detected */
+#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
+/** Device driver supports IOVA as VA */
+#define RTE_PCI_DRV_IOVA_AS_VA 0X0040
+
+/**
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ *
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_pci_scan(void);
+
+/**
+ * Probe the PCI bus
+ *
+ * @return
+ *   - 0 on success.
+ *   - !0 on error.
+ */
+int
+rte_pci_probe(void);
+
+/*
+ * Match the PCI Driver and Device using the ID Table
+ *
+ * @param pci_drv
+ *      PCI driver from which ID table would be extracted
+ * @param pci_dev
+ *      PCI device to match against the driver
+ * @return
+ *      1 for successful match
+ *      0 for unsuccessful match
+ */
+int
+rte_pci_match(const struct rte_pci_driver *pci_drv,
+	      const struct rte_pci_device *pci_dev);
+
+
+/**
+ * Get iommu class of PCI devices on the bus.
+ * And return their preferred iova mapping mode.
+ *
+ * @return
+ *   - enum rte_iova_mode.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void);
+
+/**
+ * Map the PCI device resources in user space virtual memory address
+ *
+ * Note that driver should not call this function when flag
+ * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for
+ * you when it's on.
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ *
+ * @return
+ *   0 on success, negative on error and positive if no driver
+ *   is found for the device.
+ */
+int rte_pci_map_device(struct rte_pci_device *dev);
+
+/**
+ * Unmap this device
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ */
+void rte_pci_unmap_device(struct rte_pci_device *dev);
+
+/**
+ * Probe the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the probe() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to probe.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_probe_one(const struct rte_pci_addr *addr);
+
+/**
+ * Close the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the remove() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_detach(const struct rte_pci_addr *addr);
+
+/**
+ * Dump the content of the PCI bus.
+ *
+ * @param f
+ *   A pointer to a file for output
+ */
+void rte_pci_dump(FILE *f);
+
+/**
+ * Register a PCI driver.
+ *
+ * @param driver
+ *   A pointer to a rte_pci_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_pci_register(struct rte_pci_driver *driver);
+
+/** Helper for PCI device registration from driver (eth, crypto) instance */
+#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
+RTE_INIT(pciinitfn_ ##nm); \
+static void pciinitfn_ ##nm(void) \
+{\
+	(pci_drv).driver.name = RTE_STR(nm);\
+	rte_pci_register(&pci_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a PCI driver.
+ *
+ * @param driver
+ *   A pointer to a rte_pci_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_pci_unregister(struct rte_pci_driver *driver);
+
+/**
+ * Read PCI config space.
+ *
+ * @param device
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ * @param buf
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into PCI config space
+ */
+int rte_pci_read_config(const struct rte_pci_device *device,
+		void *buf, size_t len, off_t offset);
+
+/**
+ * Write PCI config space.
+ *
+ * @param device
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ * @param buf
+ *   A data buffer containing the bytes should be written
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into PCI config space
+ */
+int rte_pci_write_config(const struct rte_pci_device *device,
+		const void *buf, size_t len, off_t offset);
+
+/**
+ * A structure used to access io resources for a pci device.
+ * rte_pci_ioport is arch, os, driver specific, and should not be used outside
+ * of pci ioport api.
+ */
+struct rte_pci_ioport {
+	struct rte_pci_device *dev;
+	uint64_t base;
+	uint64_t len; /* only filled for memory mapped ports */
+};
+
+/**
+ * Initialize a rte_pci_ioport object for a pci device io resource.
+ *
+ * This object is then used to gain access to those io resources (see below).
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use.
+ * @param bar
+ *   Index of the io pci resource we want to access.
+ * @param p
+ *   The rte_pci_ioport object to be initialized.
+ * @return
+ *  0 on success, negative on error.
+ */
+int rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p);
+
+/**
+ * Release any resources used in a rte_pci_ioport object.
+ *
+ * @param p
+ *   The rte_pci_ioport object to be uninitialized.
+ * @return
+ *  0 on success, negative on error.
+ */
+int rte_pci_ioport_unmap(struct rte_pci_ioport *p);
+
+/**
+ * Read from a io pci resource.
+ *
+ * @param p
+ *   The rte_pci_ioport object from which we want to read.
+ * @param data
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into the pci io resource.
+ */
+void rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset);
+
+/**
+ * Write to a io pci resource.
+ *
+ * @param p
+ *   The rte_pci_ioport object to which we want to write.
+ * @param data
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into the pci io resource.
+ */
+void rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_BUS_PCI_H_ */
diff --git a/drivers/bus/pci/linux/Makefile b/drivers/bus/pci/linux/Makefile
new file mode 100644
index 0000000..5410566
--- /dev/null
+++ b/drivers/bus/pci/linux/Makefile
@@ -0,0 +1,37 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += pci.c
+SRCS += pci_uio.c
+SRCS += pci_vfio.c
+SRCS += vfio_mp_sync.c
+
+CFLAGS += -D_GNU_SOURCE
diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c
new file mode 100644
index 0000000..c1fcc56
--- /dev/null
+++ b/drivers/bus/pci/linux/pci.c
@@ -0,0 +1,820 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <dirent.h>
+
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+#include <rte_devargs.h>
+#include <rte_memcpy.h>
+
+#include "eal_private.h"
+#include "eal_filesystem.h"
+#include "eal_vfio.h"
+
+#include "private.h"
+#include "pci_init.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in sysfs.
+ * When a registered device matches a driver, it is then initialized with
+ * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
+ */
+
+extern struct rte_pci_bus rte_pci_bus;
+
+static int
+pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
+{
+	int count;
+	char path[PATH_MAX];
+	char *name;
+
+	if (!filename || !dri_name)
+		return -1;
+
+	count = readlink(filename, path, PATH_MAX);
+	if (count >= PATH_MAX)
+		return -1;
+
+	/* For device does not have a driver */
+	if (count < 0)
+		return 1;
+
+	path[count] = '\0';
+
+	name = strrchr(path, '/');
+	if (name) {
+		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
+		return 0;
+	}
+
+	return -1;
+}
+
+/* Map pci device */
+int
+rte_pci_map_device(struct rte_pci_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_map_resource(dev);
+#endif
+		break;
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+		if (rte_eal_using_phys_addrs()) {
+			/* map resources for devices that use uio */
+			ret = pci_uio_map_resource(dev);
+		}
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+/* Unmap pci device */
+void
+rte_pci_unmap_device(struct rte_pci_device *dev)
+{
+	/* try unmapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+		if (pci_vfio_is_enabled())
+			pci_vfio_unmap_resource(dev);
+#endif
+		break;
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+		/* unmap resources for devices that use uio */
+		pci_uio_unmap_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+void *
+pci_find_max_end_va(void)
+{
+	const struct rte_memseg *seg = rte_eal_get_physmem_layout();
+	const struct rte_memseg *last = seg;
+	unsigned i = 0;
+
+	for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
+		if (seg->addr == NULL)
+			break;
+
+		if (seg->addr > last->addr)
+			last = seg;
+
+	}
+	return RTE_PTR_ADD(last->addr, last->len);
+}
+
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int
+pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+	uint64_t *end_addr, uint64_t *flags)
+{
+	union pci_resource_info {
+		struct {
+			char *phys_addr;
+			char *end_addr;
+			char *flags;
+		};
+		char *ptrs[PCI_RESOURCE_FMT_NVAL];
+	} res_info;
+
+	if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
+		RTE_LOG(ERR, EAL,
+			"%s(): bad resource format\n", __func__);
+		return -1;
+	}
+	errno = 0;
+	*phys_addr = strtoull(res_info.phys_addr, NULL, 16);
+	*end_addr = strtoull(res_info.end_addr, NULL, 16);
+	*flags = strtoull(res_info.flags, NULL, 16);
+	if (errno != 0) {
+		RTE_LOG(ERR, EAL,
+			"%s(): bad resource format\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
+
+/* parse the "resource" sysfs file */
+static int
+pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
+{
+	FILE *f;
+	char buf[BUFSIZ];
+	int i;
+	uint64_t phys_addr, end_addr, flags;
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
+		return -1;
+	}
+
+	for (i = 0; i<PCI_MAX_RESOURCE; i++) {
+
+		if (fgets(buf, sizeof(buf), f) == NULL) {
+			RTE_LOG(ERR, EAL,
+				"%s(): cannot read resource\n", __func__);
+			goto error;
+		}
+		if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+				&end_addr, &flags) < 0)
+			goto error;
+
+		if (flags & IORESOURCE_MEM) {
+			dev->mem_resource[i].phys_addr = phys_addr;
+			dev->mem_resource[i].len = end_addr - phys_addr + 1;
+			/* not mapped for now */
+			dev->mem_resource[i].addr = NULL;
+		}
+	}
+	fclose(f);
+	return 0;
+
+error:
+	fclose(f);
+	return -1;
+}
+
+/* Scan one pci sysfs entry, and fill the devices list from it. */
+static int
+pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
+{
+	char filename[PATH_MAX];
+	unsigned long tmp;
+	struct rte_pci_device *dev;
+	char driver[PATH_MAX];
+	int ret;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL)
+		return -1;
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr = *addr;
+
+	/* get vendor id */
+	snprintf(filename, sizeof(filename), "%s/vendor", dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.vendor_id = (uint16_t)tmp;
+
+	/* get device id */
+	snprintf(filename, sizeof(filename), "%s/device", dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.device_id = (uint16_t)tmp;
+
+	/* get subsystem_vendor id */
+	snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.subsystem_vendor_id = (uint16_t)tmp;
+
+	/* get subsystem_device id */
+	snprintf(filename, sizeof(filename), "%s/subsystem_device",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.subsystem_device_id = (uint16_t)tmp;
+
+	/* get class_id */
+	snprintf(filename, sizeof(filename), "%s/class",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	/* the least 24 bits are valid: class, subclass, program interface */
+	dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
+
+	/* get max_vfs */
+	dev->max_vfs = 0;
+	snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
+	if (!access(filename, F_OK) &&
+	    eal_parse_sysfs_value(filename, &tmp) == 0)
+		dev->max_vfs = (uint16_t)tmp;
+	else {
+		/* for non igb_uio driver, need kernel version >= 3.8 */
+		snprintf(filename, sizeof(filename),
+			 "%s/sriov_numvfs", dirname);
+		if (!access(filename, F_OK) &&
+		    eal_parse_sysfs_value(filename, &tmp) == 0)
+			dev->max_vfs = (uint16_t)tmp;
+	}
+
+	/* get numa node, default to 0 if not present */
+	snprintf(filename, sizeof(filename), "%s/numa_node",
+		 dirname);
+
+	if (access(filename, F_OK) != -1) {
+		if (eal_parse_sysfs_value(filename, &tmp) == 0)
+			dev->device.numa_node = tmp;
+		else
+			dev->device.numa_node = -1;
+	} else {
+		dev->device.numa_node = 0;
+	}
+
+	pci_name_set(dev);
+
+	/* parse resources */
+	snprintf(filename, sizeof(filename), "%s/resource", dirname);
+	if (pci_parse_sysfs_resource(filename, dev) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
+		free(dev);
+		return -1;
+	}
+
+	/* parse driver */
+	snprintf(filename, sizeof(filename), "%s/driver", dirname);
+	ret = pci_get_kernel_driver_by_path(filename, driver);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
+		free(dev);
+		return -1;
+	}
+
+	if (!ret) {
+		if (!strcmp(driver, "vfio-pci"))
+			dev->kdrv = RTE_KDRV_VFIO;
+		else if (!strcmp(driver, "igb_uio"))
+			dev->kdrv = RTE_KDRV_IGB_UIO;
+		else if (!strcmp(driver, "uio_pci_generic"))
+			dev->kdrv = RTE_KDRV_UIO_GENERIC;
+		else
+			dev->kdrv = RTE_KDRV_UNKNOWN;
+	} else
+		dev->kdrv = RTE_KDRV_NONE;
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
+		rte_pci_add_device(dev);
+	} else {
+		struct rte_pci_device *dev2;
+		int ret;
+
+		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
+			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+
+			if (ret < 0) {
+				rte_pci_insert_device(dev2, dev);
+			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->max_vfs = dev->max_vfs;
+				pci_name_set(dev2);
+				memmove(dev2->mem_resource, dev->mem_resource,
+					sizeof(dev->mem_resource));
+				free(dev);
+			}
+			return 0;
+		}
+
+		rte_pci_add_device(dev);
+	}
+
+	return 0;
+}
+
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+	char filename[PATH_MAX];
+
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
+		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
+		 addr->function);
+
+	return pci_scan_one(filename, addr);
+}
+
+/*
+ * split up a pci address into its constituent parts.
+ */
+static int
+parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
+{
+	/* first split on ':' */
+	union splitaddr {
+		struct {
+			char *domain;
+			char *bus;
+			char *devid;
+			char *function;
+		};
+		char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
+	} splitaddr;
+
+	char *buf_copy = strndup(buf, bufsize);
+	if (buf_copy == NULL)
+		return -1;
+
+	if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
+			!= PCI_FMT_NVAL - 1)
+		goto error;
+	/* final split is on '.' between devid and function */
+	splitaddr.function = strchr(splitaddr.devid,'.');
+	if (splitaddr.function == NULL)
+		goto error;
+	*splitaddr.function++ = '\0';
+
+	/* now convert to int values */
+	errno = 0;
+	addr->domain = strtoul(splitaddr.domain, NULL, 16);
+	addr->bus = strtoul(splitaddr.bus, NULL, 16);
+	addr->devid = strtoul(splitaddr.devid, NULL, 16);
+	addr->function = strtoul(splitaddr.function, NULL, 10);
+	if (errno != 0)
+		goto error;
+
+	free(buf_copy); /* free the copy made with strdup */
+	return 0;
+error:
+	free(buf_copy);
+	return -1;
+}
+
+/*
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ */
+int
+rte_pci_scan(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+	struct rte_pci_addr addr;
+
+	/* for debug purposes, PCI can be disabled */
+	if (internal_config.no_pci)
+		return 0;
+
+	dir = opendir(pci_get_sysfs_path());
+	if (dir == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
+			continue;
+
+		snprintf(dirname, sizeof(dirname), "%s/%s",
+				pci_get_sysfs_path(), e->d_name);
+
+		if (pci_scan_one(dirname, &addr) < 0)
+			goto error;
+	}
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
+
+/*
+ * Is pci device bound to any kdrv
+ */
+static inline int
+pci_one_device_is_bound(void)
+{
+	struct rte_pci_device *dev = NULL;
+	int ret = 0;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (dev->kdrv == RTE_KDRV_UNKNOWN ||
+		    dev->kdrv == RTE_KDRV_NONE) {
+			continue;
+		} else {
+			ret = 1;
+			break;
+		}
+	}
+	return ret;
+}
+
+/*
+ * Any one of the device bound to uio
+ */
+static inline int
+pci_one_device_bound_uio(void)
+{
+	struct rte_pci_device *dev = NULL;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (dev->kdrv == RTE_KDRV_IGB_UIO ||
+		   dev->kdrv == RTE_KDRV_UIO_GENERIC) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * Any one of the device has iova as va
+ */
+static inline int
+pci_one_device_has_iova_va(void)
+{
+	struct rte_pci_device *dev = NULL;
+	struct rte_pci_driver *drv = NULL;
+
+	FOREACH_DRIVER_ON_PCIBUS(drv) {
+		if (drv && drv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) {
+			FOREACH_DEVICE_ON_PCIBUS(dev) {
+				if (dev->kdrv == RTE_KDRV_VFIO &&
+				    rte_pci_match(drv, dev))
+					return 1;
+			}
+		}
+	}
+	return 0;
+}
+
+/*
+ * Get iommu class of PCI devices on the bus.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void)
+{
+	bool is_bound;
+	bool is_vfio_noiommu_enabled = true;
+	bool has_iova_va;
+	bool is_bound_uio;
+
+	is_bound = pci_one_device_is_bound();
+	if (!is_bound)
+		return RTE_IOVA_DC;
+
+	has_iova_va = pci_one_device_has_iova_va();
+	is_bound_uio = pci_one_device_bound_uio();
+#ifdef VFIO_PRESENT
+	is_vfio_noiommu_enabled = vfio_noiommu_is_enabled() == true ?
+					true : false;
+#endif
+
+	if (has_iova_va && !is_bound_uio && !is_vfio_noiommu_enabled)
+		return RTE_IOVA_VA;
+
+	if (has_iova_va) {
+		RTE_LOG(WARNING, EAL, "Some devices want iova as va but pa will be used because.. ");
+		if (is_vfio_noiommu_enabled)
+			RTE_LOG(WARNING, EAL, "vfio-noiommu mode configured\n");
+		if (is_bound_uio)
+			RTE_LOG(WARNING, EAL, "few device bound to UIO\n");
+	}
+
+	return RTE_IOVA_PA;
+}
+
+/* Read PCI config space. */
+int rte_pci_read_config(const struct rte_pci_device *device,
+		void *buf, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &device->intr_handle;
+
+	switch (intr_handle->type) {
+	case RTE_INTR_HANDLE_UIO:
+	case RTE_INTR_HANDLE_UIO_INTX:
+		return pci_uio_read_config(intr_handle, buf, len, offset);
+
+#ifdef VFIO_PRESENT
+	case RTE_INTR_HANDLE_VFIO_MSIX:
+	case RTE_INTR_HANDLE_VFIO_MSI:
+	case RTE_INTR_HANDLE_VFIO_LEGACY:
+		return pci_vfio_read_config(intr_handle, buf, len, offset);
+#endif
+	default:
+		RTE_LOG(ERR, EAL,
+			"Unknown handle type of fd %d\n",
+					intr_handle->fd);
+		return -1;
+	}
+}
+
+/* Write PCI config space. */
+int rte_pci_write_config(const struct rte_pci_device *device,
+		const void *buf, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &device->intr_handle;
+
+	switch (intr_handle->type) {
+	case RTE_INTR_HANDLE_UIO:
+	case RTE_INTR_HANDLE_UIO_INTX:
+		return pci_uio_write_config(intr_handle, buf, len, offset);
+
+#ifdef VFIO_PRESENT
+	case RTE_INTR_HANDLE_VFIO_MSIX:
+	case RTE_INTR_HANDLE_VFIO_MSI:
+	case RTE_INTR_HANDLE_VFIO_LEGACY:
+		return pci_vfio_write_config(intr_handle, buf, len, offset);
+#endif
+	default:
+		RTE_LOG(ERR, EAL,
+			"Unknown handle type of fd %d\n",
+					intr_handle->fd);
+		return -1;
+	}
+}
+
+#if defined(RTE_ARCH_X86)
+static int
+pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
+		struct rte_pci_ioport *p)
+{
+	uint16_t start, end;
+	FILE *fp;
+	char *line = NULL;
+	char pci_id[16];
+	int found = 0;
+	size_t linesz;
+
+	snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
+		 dev->addr.domain, dev->addr.bus,
+		 dev->addr.devid, dev->addr.function);
+
+	fp = fopen("/proc/ioports", "r");
+	if (fp == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);
+		return -1;
+	}
+
+	while (getdelim(&line, &linesz, '\n', fp) > 0) {
+		char *ptr = line;
+		char *left;
+		int n;
+
+		n = strcspn(ptr, ":");
+		ptr[n] = 0;
+		left = &ptr[n + 1];
+
+		while (*left && isspace(*left))
+			left++;
+
+		if (!strncmp(left, pci_id, strlen(pci_id))) {
+			found = 1;
+
+			while (*ptr && isspace(*ptr))
+				ptr++;
+
+			sscanf(ptr, "%04hx-%04hx", &start, &end);
+
+			break;
+		}
+	}
+
+	free(line);
+	fclose(fp);
+
+	if (!found)
+		return -1;
+
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	p->base = start;
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
+
+	return 0;
+}
+#endif
+
+int
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p)
+{
+	int ret = -1;
+
+	switch (dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_ioport_map(dev, bar, p);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		ret = pci_uio_ioport_map(dev, bar, p);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+		ret = pci_ioport_map(dev, bar, p);
+#else
+		ret = pci_uio_ioport_map(dev, bar, p);
+#endif
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		ret = pci_ioport_map(dev, bar, p);
+#endif
+		break;
+	default:
+		break;
+	}
+
+	if (!ret)
+		p->dev = dev;
+
+	return ret;
+}
+
+void
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		pci_vfio_ioport_read(p, data, len, offset);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		pci_uio_ioport_read(p, data, len, offset);
+#endif
+		break;
+	default:
+		break;
+	}
+}
+
+void
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		pci_vfio_ioport_write(p, data, len, offset);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		pci_uio_ioport_write(p, data, len, offset);
+#endif
+		break;
+	default:
+		break;
+	}
+}
+
+int
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
+{
+	int ret = -1;
+
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_ioport_unmap(p);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		ret = pci_uio_ioport_unmap(p);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+		ret = 0;
+#else
+		ret = pci_uio_ioport_unmap(p);
+#endif
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		ret = 0;
+#endif
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/bus/pci/linux/pci_init.h b/drivers/bus/pci/linux/pci_init.h
new file mode 100644
index 0000000..ae2980d
--- /dev/null
+++ b/drivers/bus/pci/linux/pci_init.h
@@ -0,0 +1,97 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EAL_PCI_INIT_H_
+#define EAL_PCI_INIT_H_
+
+#include "eal_vfio.h"
+
+/** IO resource type: */
+#define IORESOURCE_IO         0x00000100
+#define IORESOURCE_MEM        0x00000200
+
+/*
+ * Helper function to map PCI resources right after hugepages in virtual memory
+ */
+extern void *pci_map_addr;
+void *pci_find_max_end_va(void);
+
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+	uint64_t *end_addr, uint64_t *flags);
+
+int pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res);
+void pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res);
+int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx);
+
+int pci_uio_read_config(const struct rte_intr_handle *intr_handle,
+			void *buf, size_t len, off_t offs);
+int pci_uio_write_config(const struct rte_intr_handle *intr_handle,
+			 const void *buf, size_t len, off_t offs);
+
+int pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		       struct rte_pci_ioport *p);
+void pci_uio_ioport_read(struct rte_pci_ioport *p,
+			 void *data, size_t len, off_t offset);
+void pci_uio_ioport_write(struct rte_pci_ioport *p,
+			  const void *data, size_t len, off_t offset);
+int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
+
+#ifdef VFIO_PRESENT
+
+/* access config space */
+int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
+			 void *buf, size_t len, off_t offs);
+int pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
+			  const void *buf, size_t len, off_t offs);
+
+int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
+		        struct rte_pci_ioport *p);
+void pci_vfio_ioport_read(struct rte_pci_ioport *p,
+			  void *data, size_t len, off_t offset);
+void pci_vfio_ioport_write(struct rte_pci_ioport *p,
+			   const void *data, size_t len, off_t offset);
+int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
+
+/* map/unmap VFIO resource prototype */
+int pci_vfio_map_resource(struct rte_pci_device *dev);
+int pci_vfio_unmap_resource(struct rte_pci_device *dev);
+
+#endif
+
+#endif /* EAL_PCI_INIT_H_ */
diff --git a/drivers/bus/pci/linux/pci_uio.c b/drivers/bus/pci/linux/pci_uio.c
new file mode 100644
index 0000000..d3f0556
--- /dev/null
+++ b/drivers/bus/pci/linux/pci_uio.c
@@ -0,0 +1,567 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/sysmacros.h>
+#include <linux/pci_regs.h>
+
+#if defined(RTE_ARCH_X86)
+#include <sys/io.h>
+#endif
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_common.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "pci_init.h"
+
+void *pci_map_addr = NULL;
+
+#define OFF_MAX              ((uint64_t)(off_t)-1)
+
+int
+pci_uio_read_config(const struct rte_intr_handle *intr_handle,
+		    void *buf, size_t len, off_t offset)
+{
+	return pread(intr_handle->uio_cfg_fd, buf, len, offset);
+}
+
+int
+pci_uio_write_config(const struct rte_intr_handle *intr_handle,
+		     const void *buf, size_t len, off_t offset)
+{
+	return pwrite(intr_handle->uio_cfg_fd, buf, len, offset);
+}
+
+static int
+pci_uio_set_bus_master(int dev_fd)
+{
+	uint16_t reg;
+	int ret;
+
+	ret = pread(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL,
+			"Cannot read command from PCI config space!\n");
+		return -1;
+	}
+
+	/* return if bus mastering is already on */
+	if (reg & PCI_COMMAND_MASTER)
+		return 0;
+
+	reg |= PCI_COMMAND_MASTER;
+
+	ret = pwrite(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL,
+			"Cannot write command to PCI config space!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
+{
+	FILE *f;
+	char filename[PATH_MAX];
+	int ret;
+	unsigned major, minor;
+	dev_t dev;
+
+	/* get the name of the sysfs file that contains the major and minor
+	 * of the uio device and read its content */
+	snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path);
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n",
+			__func__);
+		return -1;
+	}
+
+	ret = fscanf(f, "%u:%u", &major, &minor);
+	if (ret != 2) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n",
+			__func__);
+		fclose(f);
+		return -1;
+	}
+	fclose(f);
+
+	/* create the char device "mknod /dev/uioX c major minor" */
+	snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
+	dev = makedev(major, minor);
+	ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
+	if (ret != 0) {
+		RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	return ret;
+}
+
+/*
+ * Return the uioX char device used for a pci device. On success, return
+ * the UIO number and fill dstbuf string with the path of the device in
+ * sysfs. On error, return a negative value. In this case dstbuf is
+ * invalid.
+ */
+static int
+pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
+			   unsigned int buflen, int create)
+{
+	struct rte_pci_addr *loc = &dev->addr;
+	int uio_num = -1;
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+
+	/* depending on kernel version, uio can be located in uio/uioX
+	 * or uio:uioX */
+
+	snprintf(dirname, sizeof(dirname),
+			"%s/" PCI_PRI_FMT "/uio", pci_get_sysfs_path(),
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	dir = opendir(dirname);
+	if (dir == NULL) {
+		/* retry with the parent directory */
+		snprintf(dirname, sizeof(dirname),
+				"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
+				loc->domain, loc->bus, loc->devid, loc->function);
+		dir = opendir(dirname);
+
+		if (dir == NULL) {
+			RTE_LOG(ERR, EAL, "Cannot opendir %s\n", dirname);
+			return -1;
+		}
+	}
+
+	/* take the first file starting with "uio" */
+	while ((e = readdir(dir)) != NULL) {
+		/* format could be uio%d ...*/
+		int shortprefix_len = sizeof("uio") - 1;
+		/* ... or uio:uio%d */
+		int longprefix_len = sizeof("uio:uio") - 1;
+		char *endptr;
+
+		if (strncmp(e->d_name, "uio", 3) != 0)
+			continue;
+
+		/* first try uio%d */
+		errno = 0;
+		uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
+		if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
+			snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
+			break;
+		}
+
+		/* then try uio:uio%d */
+		errno = 0;
+		uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
+		if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
+			snprintf(dstbuf, buflen, "%s/uio:uio%u", dirname, uio_num);
+			break;
+		}
+	}
+	closedir(dir);
+
+	/* No uio resource found */
+	if (e == NULL)
+		return -1;
+
+	/* create uio device if we've been asked to */
+	if (internal_config.create_uio_dev && create &&
+			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
+		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
+
+	return uio_num;
+}
+
+void
+pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res)
+{
+	rte_free(uio_res);
+
+	if (dev->intr_handle.uio_cfg_fd >= 0) {
+		close(dev->intr_handle.uio_cfg_fd);
+		dev->intr_handle.uio_cfg_fd = -1;
+	}
+	if (dev->intr_handle.fd >= 0) {
+		close(dev->intr_handle.fd);
+		dev->intr_handle.fd = -1;
+		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	}
+}
+
+int
+pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res)
+{
+	char dirname[PATH_MAX];
+	char cfgname[PATH_MAX];
+	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	int uio_num;
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+
+	/* find uio resource */
+	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 1);
+	if (uio_num < 0) {
+		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+		return 1;
+	}
+	snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
+
+	/* save fd if in primary process */
+	dev->intr_handle.fd = open(devname, O_RDWR);
+	if (dev->intr_handle.fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			devname, strerror(errno));
+		goto error;
+	}
+
+	snprintf(cfgname, sizeof(cfgname),
+			"/sys/class/uio/uio%u/device/config", uio_num);
+	dev->intr_handle.uio_cfg_fd = open(cfgname, O_RDWR);
+	if (dev->intr_handle.uio_cfg_fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			cfgname, strerror(errno));
+		goto error;
+	}
+
+	if (dev->kdrv == RTE_KDRV_IGB_UIO)
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+	else {
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
+
+		/* set bus master that is not done by uio_pci_generic */
+		if (pci_uio_set_bus_master(dev->intr_handle.uio_cfg_fd)) {
+			RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
+			goto error;
+		}
+	}
+
+	/* allocate the mapping details for secondary processes*/
+	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
+	if (*uio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto error;
+	}
+
+	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
+	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
+
+	return 0;
+
+error:
+	pci_uio_free_resource(dev, *uio_res);
+	return -1;
+}
+
+int
+pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx)
+{
+	int fd;
+	char devname[PATH_MAX];
+	void *mapaddr;
+	struct rte_pci_addr *loc;
+	struct pci_map *maps;
+
+	loc = &dev->addr;
+	maps = uio_res->maps;
+
+	/* update devname for mmap  */
+	snprintf(devname, sizeof(devname),
+			"%s/" PCI_PRI_FMT "/resource%d",
+			pci_get_sysfs_path(),
+			loc->domain, loc->bus, loc->devid,
+			loc->function, res_idx);
+
+	/* allocate memory to keep path */
+	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+	if (maps[map_idx].path == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+				strerror(errno));
+		return -1;
+	}
+
+	/*
+	 * open resource file, to mmap it
+	 */
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				devname, strerror(errno));
+		goto error;
+	}
+
+	/* try mapping somewhere close to the end of hugepages */
+	if (pci_map_addr == NULL)
+		pci_map_addr = pci_find_max_end_va();
+
+	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
+			(size_t)dev->mem_resource[res_idx].len, 0);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		goto error;
+
+	pci_map_addr = RTE_PTR_ADD(mapaddr,
+			(size_t)dev->mem_resource[res_idx].len);
+
+	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+	maps[map_idx].size = dev->mem_resource[res_idx].len;
+	maps[map_idx].addr = mapaddr;
+	maps[map_idx].offset = 0;
+	strcpy(maps[map_idx].path, devname);
+	dev->mem_resource[res_idx].addr = mapaddr;
+
+	return 0;
+
+error:
+	rte_free(maps[map_idx].path);
+	return -1;
+}
+
+#if defined(RTE_ARCH_X86)
+int
+pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		   struct rte_pci_ioport *p)
+{
+	char dirname[PATH_MAX];
+	char filename[PATH_MAX];
+	int uio_num;
+	unsigned long start;
+
+	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 0);
+	if (uio_num < 0)
+		return -1;
+
+	/* get portio start */
+	snprintf(filename, sizeof(filename),
+		 "%s/portio/port%d/start", dirname, bar);
+	if (eal_parse_sysfs_value(filename, &start) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
+			__func__);
+		return -1;
+	}
+	/* ensure we don't get anything funny here, read/write will cast to
+	 * uin16_t */
+	if (start > UINT16_MAX)
+		return -1;
+
+	/* FIXME only for primary process ? */
+	if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {
+
+		snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
+		dev->intr_handle.fd = open(filename, O_RDWR);
+		if (dev->intr_handle.fd < 0) {
+			RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				filename, strerror(errno));
+			return -1;
+		}
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+	}
+
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);
+
+	p->base = start;
+	p->len = 0;
+	return 0;
+}
+#else
+int
+pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		   struct rte_pci_ioport *p)
+{
+	FILE *f;
+	char buf[BUFSIZ];
+	char filename[PATH_MAX];
+	uint64_t phys_addr, end_addr, flags;
+	int fd, i;
+	void *addr;
+
+	/* open and read addresses of the corresponding resource in sysfs */
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
+		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function);
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",
+			strerror(errno));
+		return -1;
+	}
+	for (i = 0; i < bar + 1; i++) {
+		if (fgets(buf, sizeof(buf), f) == NULL) {
+			RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");
+			goto error;
+		}
+	}
+	if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+			&end_addr, &flags) < 0)
+		goto error;
+	if ((flags & IORESOURCE_IO) == 0) {
+		RTE_LOG(ERR, EAL, "BAR %d is not an IO resource\n", bar);
+		goto error;
+	}
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
+		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function, bar);
+
+	/* mmap the pci resource */
+	fd = open(filename, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
+			strerror(errno));
+		goto error;
+	}
+	addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
+		MAP_SHARED, fd, 0);
+	close(fd);
+	if (addr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s\n",
+			strerror(errno));
+		goto error;
+	}
+
+	/* strangely, the base address is mmap addr + phys_addr */
+	p->base = (uintptr_t)addr + phys_addr;
+	p->len = end_addr + 1;
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"\n", p->base);
+	fclose(f);
+
+	return 0;
+
+error:
+	fclose(f);
+	return -1;
+}
+#endif
+
+void
+pci_uio_ioport_read(struct rte_pci_ioport *p,
+		    void *data, size_t len, off_t offset)
+{
+	uint8_t *d;
+	int size;
+	uintptr_t reg = p->base + offset;
+
+	for (d = data; len > 0; d += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+#if defined(RTE_ARCH_X86)
+			*(uint32_t *)d = inl(reg);
+#else
+			*(uint32_t *)d = *(volatile uint32_t *)reg;
+#endif
+		} else if (len >= 2) {
+			size = 2;
+#if defined(RTE_ARCH_X86)
+			*(uint16_t *)d = inw(reg);
+#else
+			*(uint16_t *)d = *(volatile uint16_t *)reg;
+#endif
+		} else {
+			size = 1;
+#if defined(RTE_ARCH_X86)
+			*d = inb(reg);
+#else
+			*d = *(volatile uint8_t *)reg;
+#endif
+		}
+	}
+}
+
+void
+pci_uio_ioport_write(struct rte_pci_ioport *p,
+		     const void *data, size_t len, off_t offset)
+{
+	const uint8_t *s;
+	int size;
+	uintptr_t reg = p->base + offset;
+
+	for (s = data; len > 0; s += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+#if defined(RTE_ARCH_X86)
+			outl_p(*(const uint32_t *)s, reg);
+#else
+			*(volatile uint32_t *)reg = *(const uint32_t *)s;
+#endif
+		} else if (len >= 2) {
+			size = 2;
+#if defined(RTE_ARCH_X86)
+			outw_p(*(const uint16_t *)s, reg);
+#else
+			*(volatile uint16_t *)reg = *(const uint16_t *)s;
+#endif
+		} else {
+			size = 1;
+#if defined(RTE_ARCH_X86)
+			outb_p(*s, reg);
+#else
+			*(volatile uint8_t *)reg = *s;
+#endif
+		}
+	}
+}
+
+int
+pci_uio_ioport_unmap(struct rte_pci_ioport *p)
+{
+#if defined(RTE_ARCH_X86)
+	RTE_SET_USED(p);
+	/* FIXME close intr fd ? */
+	return 0;
+#else
+	return munmap((void *)(uintptr_t)p->base, p->len);
+#endif
+}
diff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c
new file mode 100644
index 0000000..e69e4d3
--- /dev/null
+++ b/drivers/bus/pci/linux/pci_vfio.c
@@ -0,0 +1,756 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <fcntl.h>
+#include <linux/pci_regs.h>
+#include <sys/eventfd.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "pci_init.h"
+#include "eal_vfio.h"
+#include "private.h"
+
+/**
+ * @file
+ * PCI probing under linux (VFIO version)
+ *
+ * This code tries to determine if the PCI device is bound to VFIO driver,
+ * and initialize it (map BARs, set up interrupts) if that's the case.
+ *
+ * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
+ */
+
+#ifdef VFIO_PRESENT
+
+#define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
+#define PAGE_MASK   (~(PAGE_SIZE - 1))
+
+static struct rte_tailq_elem rte_vfio_tailq = {
+	.name = "VFIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_vfio_tailq)
+
+int
+pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
+		    void *buf, size_t len, off_t offs)
+{
+	return pread64(intr_handle->vfio_dev_fd, buf, len,
+	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
+}
+
+int
+pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
+		    const void *buf, size_t len, off_t offs)
+{
+	return pwrite64(intr_handle->vfio_dev_fd, buf, len,
+	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
+}
+
+/* get PCI BAR number where MSI-X interrupts are */
+static int
+pci_vfio_get_msix_bar(int fd, struct pci_msix_table *msix_table)
+{
+	int ret;
+	uint32_t reg;
+	uint16_t flags;
+	uint8_t cap_id, cap_offset;
+
+	/* read PCI capability pointer from config space */
+	ret = pread64(fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_CAPABILITY_LIST);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
+				"config space!\n");
+		return -1;
+	}
+
+	/* we need first byte */
+	cap_offset = reg & 0xFF;
+
+	while (cap_offset) {
+
+		/* read PCI capability ID */
+		ret = pread64(fd, &reg, sizeof(reg),
+				VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+				cap_offset);
+		if (ret != sizeof(reg)) {
+			RTE_LOG(ERR, EAL, "Cannot read capability ID from PCI "
+					"config space!\n");
+			return -1;
+		}
+
+		/* we need first byte */
+		cap_id = reg & 0xFF;
+
+		/* if we haven't reached MSI-X, check next capability */
+		if (cap_id != PCI_CAP_ID_MSIX) {
+			ret = pread64(fd, &reg, sizeof(reg),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset);
+			if (ret != sizeof(reg)) {
+				RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
+						"config space!\n");
+				return -1;
+			}
+
+			/* we need second byte */
+			cap_offset = (reg & 0xFF00) >> 8;
+
+			continue;
+		}
+		/* else, read table offset */
+		else {
+			/* table offset resides in the next 4 bytes */
+			ret = pread64(fd, &reg, sizeof(reg),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset + 4);
+			if (ret != sizeof(reg)) {
+				RTE_LOG(ERR, EAL, "Cannot read table offset from PCI config "
+						"space!\n");
+				return -1;
+			}
+
+			ret = pread64(fd, &flags, sizeof(flags),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset + 2);
+			if (ret != sizeof(flags)) {
+				RTE_LOG(ERR, EAL, "Cannot read table flags from PCI config "
+						"space!\n");
+				return -1;
+			}
+
+			msix_table->bar_index = reg & RTE_PCI_MSIX_TABLE_BIR;
+			msix_table->offset = reg & RTE_PCI_MSIX_TABLE_OFFSET;
+			msix_table->size =
+				16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE));
+
+			return 0;
+		}
+	}
+	return 0;
+}
+
+/* set PCI bus mastering */
+static int
+pci_vfio_set_bus_master(int dev_fd, bool op)
+{
+	uint16_t reg;
+	int ret;
+
+	ret = pread64(dev_fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n");
+		return -1;
+	}
+
+	if (op)
+		/* set the master bit */
+		reg |= PCI_COMMAND_MASTER;
+	else
+		reg &= ~(PCI_COMMAND_MASTER);
+
+	ret = pwrite64(dev_fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_COMMAND);
+
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* set up interrupt support (but not enable interrupts) */
+static int
+pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
+{
+	int i, ret, intr_idx;
+
+	/* default to invalid index */
+	intr_idx = VFIO_PCI_NUM_IRQS;
+
+	/* get interrupt type from internal config (MSI-X by default, can be
+	 * overridden from the command line
+	 */
+	switch (internal_config.vfio_intr_mode) {
+	case RTE_INTR_MODE_MSIX:
+		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
+		break;
+	case RTE_INTR_MODE_MSI:
+		intr_idx = VFIO_PCI_MSI_IRQ_INDEX;
+		break;
+	case RTE_INTR_MODE_LEGACY:
+		intr_idx = VFIO_PCI_INTX_IRQ_INDEX;
+		break;
+	/* don't do anything if we want to automatically determine interrupt type */
+	case RTE_INTR_MODE_NONE:
+		break;
+	default:
+		RTE_LOG(ERR, EAL, "  unknown default interrupt type!\n");
+		return -1;
+	}
+
+	/* start from MSI-X interrupt type */
+	for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) {
+		struct vfio_irq_info irq = { .argsz = sizeof(irq) };
+		int fd = -1;
+
+		/* skip interrupt modes we don't want */
+		if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE &&
+				i != intr_idx)
+			continue;
+
+		irq.index = i;
+
+		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  cannot get IRQ info, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+
+		/* if this vector cannot be used with eventfd, fail if we explicitly
+		 * specified interrupt type, otherwise continue */
+		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
+			if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE) {
+				RTE_LOG(ERR, EAL,
+						"  interrupt vector does not support eventfd!\n");
+				return -1;
+			} else
+				continue;
+		}
+
+		/* set up an eventfd for interrupts */
+		fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
+		if (fd < 0) {
+			RTE_LOG(ERR, EAL, "  cannot set up eventfd, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+
+		dev->intr_handle.fd = fd;
+		dev->intr_handle.vfio_dev_fd = vfio_dev_fd;
+
+		switch (i) {
+		case VFIO_PCI_MSIX_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSIX;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
+			break;
+		case VFIO_PCI_MSI_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSI;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
+			break;
+		case VFIO_PCI_INTX_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_LEGACY;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
+			break;
+		default:
+			RTE_LOG(ERR, EAL, "  unknown interrupt type!\n");
+			return -1;
+		}
+
+		return 0;
+	}
+
+	/* if we're here, we haven't found a suitable interrupt vector */
+	return -1;
+}
+
+static int
+pci_vfio_is_ioport_bar(int vfio_dev_fd, int bar_index)
+{
+	uint32_t ioport_bar;
+	int ret;
+
+	ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar),
+			  VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX)
+			  + PCI_BASE_ADDRESS_0 + bar_index*4);
+	if (ret != sizeof(ioport_bar)) {
+		RTE_LOG(ERR, EAL, "Cannot read command (%x) from config space!\n",
+			PCI_BASE_ADDRESS_0 + bar_index*4);
+		return -1;
+	}
+
+	return (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) != 0;
+}
+
+static int
+pci_vfio_setup_device(struct rte_pci_device *dev, int vfio_dev_fd)
+{
+	if (pci_vfio_setup_interrupts(dev, vfio_dev_fd) != 0) {
+		RTE_LOG(ERR, EAL, "Error setting up interrupts!\n");
+		return -1;
+	}
+
+	/* set bus mastering for the device */
+	if (pci_vfio_set_bus_master(vfio_dev_fd, true)) {
+		RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
+		return -1;
+	}
+
+	/* Reset the device */
+	ioctl(vfio_dev_fd, VFIO_DEVICE_RESET);
+
+	return 0;
+}
+
+static int
+pci_vfio_mmap_bar(int vfio_dev_fd, struct mapped_pci_resource *vfio_res,
+		int bar_index, int additional_flags)
+{
+	struct memreg {
+		unsigned long offset, size;
+	} memreg[2] = {};
+	void *bar_addr;
+	struct pci_msix_table *msix_table = &vfio_res->msix_table;
+	struct pci_map *bar = &vfio_res->maps[bar_index];
+
+	if (bar->size == 0)
+		/* Skip this BAR */
+		return 0;
+
+	if (msix_table->bar_index == bar_index) {
+		/*
+		 * VFIO will not let us map the MSI-X table,
+		 * but we can map around it.
+		 */
+		uint32_t table_start = msix_table->offset;
+		uint32_t table_end = table_start + msix_table->size;
+		table_end = (table_end + ~PAGE_MASK) & PAGE_MASK;
+		table_start &= PAGE_MASK;
+
+		if (table_start == 0 && table_end >= bar->size) {
+			/* Cannot map this BAR */
+			RTE_LOG(DEBUG, EAL, "Skipping BAR%d\n", bar_index);
+			bar->size = 0;
+			bar->addr = 0;
+			return 0;
+		}
+
+		memreg[0].offset = bar->offset;
+		memreg[0].size = table_start;
+		memreg[1].offset = bar->offset + table_end;
+		memreg[1].size = bar->size - table_end;
+
+		RTE_LOG(DEBUG, EAL,
+			"Trying to map BAR%d that contains the MSI-X "
+			"table. Trying offsets: "
+			"0x%04lx:0x%04lx, 0x%04lx:0x%04lx\n", bar_index,
+			memreg[0].offset, memreg[0].size,
+			memreg[1].offset, memreg[1].size);
+	} else {
+		memreg[0].offset = bar->offset;
+		memreg[0].size = bar->size;
+	}
+
+	/* reserve the address using an inaccessible mapping */
+	bar_addr = mmap(bar->addr, bar->size, 0, MAP_PRIVATE |
+			MAP_ANONYMOUS | additional_flags, -1, 0);
+	if (bar_addr != MAP_FAILED) {
+		void *map_addr = NULL;
+		if (memreg[0].size) {
+			/* actual map of first part */
+			map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
+							memreg[0].offset,
+							memreg[0].size,
+							MAP_FIXED);
+		}
+
+		/* if there's a second part, try to map it */
+		if (map_addr != MAP_FAILED
+			&& memreg[1].offset && memreg[1].size) {
+			void *second_addr = RTE_PTR_ADD(bar_addr,
+							memreg[1].offset -
+							(uintptr_t)bar->offset);
+			map_addr = pci_map_resource(second_addr,
+							vfio_dev_fd,
+							memreg[1].offset,
+							memreg[1].size,
+							MAP_FIXED);
+		}
+
+		if (map_addr == MAP_FAILED || !map_addr) {
+			munmap(bar_addr, bar->size);
+			bar_addr = MAP_FAILED;
+			RTE_LOG(ERR, EAL, "Failed to map pci BAR%d\n",
+					bar_index);
+			return -1;
+		}
+	} else {
+		RTE_LOG(ERR, EAL,
+				"Failed to create inaccessible mapping for BAR%d\n",
+				bar_index);
+		return -1;
+	}
+
+	bar->addr = bar_addr;
+	return 0;
+}
+
+static int
+pci_vfio_map_resource_primary(struct rte_pci_device *dev)
+{
+	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+	char pci_addr[PATH_MAX] = {0};
+	int vfio_dev_fd;
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list =
+		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+
+	struct pci_map *maps;
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
+					&vfio_dev_fd, &device_info);
+	if (ret)
+		return ret;
+
+	/* allocate vfio_res and get region info */
+	vfio_res = rte_zmalloc("VFIO_RES", sizeof(*vfio_res), 0);
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto err_vfio_dev_fd;
+	}
+	memcpy(&vfio_res->pci_addr, &dev->addr, sizeof(vfio_res->pci_addr));
+
+	/* get number of registers (up to BAR5) */
+	vfio_res->nb_maps = RTE_MIN((int) device_info.num_regions,
+			VFIO_PCI_BAR5_REGION_INDEX + 1);
+
+	/* map BARs */
+	maps = vfio_res->maps;
+
+	vfio_res->msix_table.bar_index = -1;
+	/* get MSI-X BAR, if any (we have to know where it is because we can't
+	 * easily mmap it when using VFIO)
+	 */
+	ret = pci_vfio_get_msix_bar(vfio_dev_fd, &vfio_res->msix_table);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "  %s cannot get MSI-X BAR number!\n",
+				pci_addr);
+		goto err_vfio_dev_fd;
+	}
+
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+		struct vfio_region_info reg = { .argsz = sizeof(reg) };
+		void *bar_addr;
+
+		reg.index = i;
+
+		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg);
+		if (ret) {
+			RTE_LOG(ERR, EAL, "  %s cannot get device region info "
+					"error %i (%s)\n", pci_addr, errno, strerror(errno));
+			goto err_vfio_res;
+		}
+
+		/* chk for io port region */
+		ret = pci_vfio_is_ioport_bar(vfio_dev_fd, i);
+		if (ret < 0)
+			goto err_vfio_res;
+		else if (ret) {
+			RTE_LOG(INFO, EAL, "Ignore mapping IO port bar(%d)\n",
+					i);
+			continue;
+		}
+
+		/* skip non-mmapable BARs */
+		if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0)
+			continue;
+
+		/* try mapping somewhere close to the end of hugepages */
+		if (pci_map_addr == NULL)
+			pci_map_addr = pci_find_max_end_va();
+
+		bar_addr = pci_map_addr;
+		pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
+
+		maps[i].addr = bar_addr;
+		maps[i].offset = reg.offset;
+		maps[i].size = reg.size;
+		maps[i].path = NULL; /* vfio doesn't have per-resource paths */
+
+		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, 0);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
+					pci_addr, i, strerror(errno));
+			goto err_vfio_res;
+		}
+
+		dev->mem_resource[i].addr = maps[i].addr;
+	}
+
+	if (pci_vfio_setup_device(dev, vfio_dev_fd) < 0) {
+		RTE_LOG(ERR, EAL, "  %s setup device failed\n", pci_addr);
+		goto err_vfio_res;
+	}
+
+	TAILQ_INSERT_TAIL(vfio_res_list, vfio_res, next);
+
+	return 0;
+err_vfio_res:
+	rte_free(vfio_res);
+err_vfio_dev_fd:
+	close(vfio_dev_fd);
+	return -1;
+}
+
+static int
+pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
+{
+	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+	char pci_addr[PATH_MAX] = {0};
+	int vfio_dev_fd;
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list =
+		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+
+	struct pci_map *maps;
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
+					&vfio_dev_fd, &device_info);
+	if (ret)
+		return ret;
+
+	/* if we're in a secondary process, just find our tailq entry */
+	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
+		if (rte_eal_compare_pci_addr(&vfio_res->pci_addr,
+						 &dev->addr))
+			continue;
+		break;
+	}
+	/* if we haven't found our tailq entry, something's wrong */
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
+				pci_addr);
+		goto err_vfio_dev_fd;
+	}
+
+	/* map BARs */
+	maps = vfio_res->maps;
+
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, MAP_FIXED);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
+					pci_addr, i, strerror(errno));
+			goto err_vfio_dev_fd;
+		}
+
+		dev->mem_resource[i].addr = maps[i].addr;
+	}
+
+	return 0;
+err_vfio_dev_fd:
+	close(vfio_dev_fd);
+	return -1;
+}
+
+/*
+ * map the PCI resources of a PCI device in virtual memory (VFIO version).
+ * primary and secondary processes follow almost exactly the same path
+ */
+int
+pci_vfio_map_resource(struct rte_pci_device *dev)
+{
+	if (internal_config.process_type == RTE_PROC_PRIMARY)
+		return pci_vfio_map_resource_primary(dev);
+	else
+		return pci_vfio_map_resource_secondary(dev);
+}
+
+int
+pci_vfio_unmap_resource(struct rte_pci_device *dev)
+{
+	char pci_addr[PATH_MAX] = {0};
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list;
+
+	struct pci_map *maps;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+
+	if (close(dev->intr_handle.fd) < 0) {
+		RTE_LOG(INFO, EAL, "Error when closing eventfd file descriptor for %s\n",
+			pci_addr);
+		return -1;
+	}
+
+	if (pci_vfio_set_bus_master(dev->intr_handle.vfio_dev_fd, false)) {
+		RTE_LOG(ERR, EAL, "  %s cannot unset bus mastering for PCI device!\n",
+				pci_addr);
+		return -1;
+	}
+
+	ret = vfio_release_device(pci_get_sysfs_path(), pci_addr,
+				  dev->intr_handle.vfio_dev_fd);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot release device\n", __func__);
+		return ret;
+	}
+
+	vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+	/* Get vfio_res */
+	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
+		if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
+			continue;
+		break;
+	}
+	/* if we haven't found our tailq entry, something's wrong */
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
+				pci_addr);
+		return -1;
+	}
+
+	/* unmap BARs */
+	maps = vfio_res->maps;
+
+	RTE_LOG(INFO, EAL, "Releasing pci mapped resource for %s\n",
+		pci_addr);
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+
+		/*
+		 * We do not need to be aware of MSI-X table BAR mappings as
+		 * when mapping. Just using current maps array is enough
+		 */
+		if (maps[i].addr) {
+			RTE_LOG(INFO, EAL, "Calling pci_unmap_resource for %s at %p\n",
+				pci_addr, maps[i].addr);
+			pci_unmap_resource(maps[i].addr, maps[i].size);
+		}
+	}
+
+	TAILQ_REMOVE(vfio_res_list, vfio_res, next);
+
+	return 0;
+}
+
+int
+pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
+		    struct rte_pci_ioport *p)
+{
+	if (bar < VFIO_PCI_BAR0_REGION_INDEX ||
+	    bar > VFIO_PCI_BAR5_REGION_INDEX) {
+		RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar);
+		return -1;
+	}
+
+	p->dev = dev;
+	p->base = VFIO_GET_REGION_ADDR(bar);
+	return 0;
+}
+
+void
+pci_vfio_ioport_read(struct rte_pci_ioport *p,
+		     void *data, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
+
+	if (pread64(intr_handle->vfio_dev_fd, data,
+		    len, p->base + offset) <= 0)
+		RTE_LOG(ERR, EAL,
+			"Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n",
+			VFIO_GET_REGION_IDX(p->base), (int)offset);
+}
+
+void
+pci_vfio_ioport_write(struct rte_pci_ioport *p,
+		      const void *data, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
+
+	if (pwrite64(intr_handle->vfio_dev_fd, data,
+		     len, p->base + offset) <= 0)
+		RTE_LOG(ERR, EAL,
+			"Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n",
+			VFIO_GET_REGION_IDX(p->base), (int)offset);
+}
+
+int
+pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
+{
+	RTE_SET_USED(p);
+	return -1;
+}
+
+int
+pci_vfio_enable(void)
+{
+	return vfio_enable("vfio_pci");
+}
+
+int
+pci_vfio_is_enabled(void)
+{
+	return vfio_is_enabled("vfio_pci");
+}
+#endif
diff --git a/drivers/bus/pci/linux/vfio_mp_sync.c b/drivers/bus/pci/linux/vfio_mp_sync.c
new file mode 100644
index 0000000..dd24e86
--- /dev/null
+++ b/drivers/bus/pci/linux/vfio_mp_sync.c
@@ -0,0 +1,425 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <pthread.h>
+
+/* sys/un.h with __USE_MISC uses strlen, which is unsafe */
+#ifdef __USE_MISC
+#define REMOVED_USE_MISC
+#undef __USE_MISC
+#endif
+#include <sys/un.h>
+/* make sure we redefine __USE_MISC only if it was previously undefined */
+#ifdef REMOVED_USE_MISC
+#define __USE_MISC
+#undef REMOVED_USE_MISC
+#endif
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "eal_thread.h"
+#include "pci_init.h"
+
+/**
+ * @file
+ * VFIO socket for communication between primary and secondary processes.
+ *
+ * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
+ */
+
+#ifdef VFIO_PRESENT
+
+#define SOCKET_PATH_FMT "%s/.%s_mp_socket"
+#define CMSGLEN (CMSG_LEN(sizeof(int)))
+#define FD_TO_CMSGHDR(fd, chdr) \
+		do {\
+			(chdr).cmsg_len = CMSGLEN;\
+			(chdr).cmsg_level = SOL_SOCKET;\
+			(chdr).cmsg_type = SCM_RIGHTS;\
+			memcpy((chdr).__cmsg_data, &(fd), sizeof(fd));\
+		} while (0)
+#define CMSGHDR_TO_FD(chdr, fd) \
+			memcpy(&(fd), (chdr).__cmsg_data, sizeof(fd))
+
+static pthread_t socket_thread;
+static int mp_socket_fd;
+
+
+/* get socket path (/var/run if root, $HOME otherwise) */
+static void
+get_socket_path(char *buffer, int bufsz)
+{
+	const char *dir = "/var/run";
+	const char *home_dir = getenv("HOME");
+
+	if (getuid() != 0 && home_dir != NULL)
+		dir = home_dir;
+
+	/* use current prefix as file path */
+	snprintf(buffer, bufsz, SOCKET_PATH_FMT, dir,
+			internal_config.hugefile_prefix);
+}
+
+
+
+/*
+ * data flow for socket comm protocol:
+ * 1. client sends SOCKET_REQ_CONTAINER or SOCKET_REQ_GROUP
+ * 1a. in case of SOCKET_REQ_GROUP, client also then sends group number
+ * 2. server receives message
+ * 2a. in case of invalid group, SOCKET_ERR is sent back to client
+ * 2b. in case of unbound group, SOCKET_NO_FD is sent back to client
+ * 2c. in case of valid group, SOCKET_OK is sent and immediately followed by fd
+ *
+ * in case of any error, socket is closed.
+ */
+
+/* send a request, return -1 on error */
+int
+vfio_mp_sync_send_request(int socket, int req)
+{
+	struct msghdr hdr;
+	struct iovec iov;
+	int buf;
+	int ret;
+
+	memset(&hdr, 0, sizeof(hdr));
+
+	buf = req;
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+
+	ret = sendmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+	return 0;
+}
+
+/* receive a request and return it */
+int
+vfio_mp_sync_receive_request(int socket)
+{
+	int buf;
+	struct msghdr hdr;
+	struct iovec iov;
+	int ret, req;
+
+	memset(&hdr, 0, sizeof(hdr));
+
+	buf = SOCKET_ERR;
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+
+	ret = recvmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+
+	req = buf;
+
+	return req;
+}
+
+/* send OK in message, fd in control message */
+int
+vfio_mp_sync_send_fd(int socket, int fd)
+{
+	int buf;
+	struct msghdr hdr;
+	struct cmsghdr *chdr;
+	char chdr_buf[CMSGLEN];
+	struct iovec iov;
+	int ret;
+
+	chdr = (struct cmsghdr *) chdr_buf;
+	memset(chdr, 0, sizeof(chdr_buf));
+	memset(&hdr, 0, sizeof(hdr));
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+	hdr.msg_control = chdr;
+	hdr.msg_controllen = CMSGLEN;
+
+	buf = SOCKET_OK;
+	FD_TO_CMSGHDR(fd, *chdr);
+
+	ret = sendmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+	return 0;
+}
+
+/* receive OK in message, fd in control message */
+int
+vfio_mp_sync_receive_fd(int socket)
+{
+	int buf;
+	struct msghdr hdr;
+	struct cmsghdr *chdr;
+	char chdr_buf[CMSGLEN];
+	struct iovec iov;
+	int ret, req, fd;
+
+	buf = SOCKET_ERR;
+
+	chdr = (struct cmsghdr *) chdr_buf;
+	memset(chdr, 0, sizeof(chdr_buf));
+	memset(&hdr, 0, sizeof(hdr));
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+	hdr.msg_control = chdr;
+	hdr.msg_controllen = CMSGLEN;
+
+	ret = recvmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+
+	req = buf;
+
+	if (req != SOCKET_OK)
+		return -1;
+
+	CMSGHDR_TO_FD(*chdr, fd);
+
+	return fd;
+}
+
+/* connect socket_fd in secondary process to the primary process's socket */
+int
+vfio_mp_sync_connect_to_primary(void)
+{
+	struct sockaddr_un addr;
+	socklen_t sockaddr_len;
+	int socket_fd;
+
+	/* set up a socket */
+	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+	if (socket_fd < 0) {
+		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
+		return -1;
+	}
+
+	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
+	addr.sun_family = AF_UNIX;
+
+	sockaddr_len = sizeof(struct sockaddr_un);
+
+	if (connect(socket_fd, (struct sockaddr *) &addr, sockaddr_len) == 0)
+		return socket_fd;
+
+	/* if connect failed */
+	close(socket_fd);
+	return -1;
+}
+
+
+
+/*
+ * socket listening thread for primary process
+ */
+static __attribute__((noreturn)) void *
+vfio_mp_sync_thread(void __rte_unused * arg)
+{
+	int ret, fd, vfio_data;
+
+	/* wait for requests on the socket */
+	for (;;) {
+		int conn_sock;
+		struct sockaddr_un addr;
+		socklen_t sockaddr_len = sizeof(addr);
+
+		/* this is a blocking call */
+		conn_sock = accept(mp_socket_fd, (struct sockaddr *) &addr,
+				&sockaddr_len);
+
+		/* just restart on error */
+		if (conn_sock == -1)
+			continue;
+
+		/* set socket to linger after close */
+		struct linger l;
+		l.l_onoff = 1;
+		l.l_linger = 60;
+
+		if (setsockopt(conn_sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0)
+			RTE_LOG(WARNING, EAL, "Cannot set SO_LINGER option "
+					"on listen socket (%s)\n", strerror(errno));
+
+		ret = vfio_mp_sync_receive_request(conn_sock);
+
+		switch (ret) {
+		case SOCKET_REQ_CONTAINER:
+			fd = vfio_get_container_fd();
+			if (fd < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			else
+				vfio_mp_sync_send_fd(conn_sock, fd);
+			if (fd >= 0)
+				close(fd);
+			break;
+		case SOCKET_REQ_GROUP:
+			/* wait for group number */
+			vfio_data = vfio_mp_sync_receive_request(conn_sock);
+			if (vfio_data < 0) {
+				close(conn_sock);
+				continue;
+			}
+
+			fd = vfio_get_group_fd(vfio_data);
+
+			if (fd < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			/* if VFIO group exists but isn't bound to VFIO driver */
+			else if (fd == 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
+			/* if group exists and is bound to VFIO driver */
+			else {
+				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
+				vfio_mp_sync_send_fd(conn_sock, fd);
+			}
+			break;
+		case SOCKET_CLR_GROUP:
+			/* wait for group fd */
+			vfio_data = vfio_mp_sync_receive_request(conn_sock);
+			if (vfio_data < 0) {
+				close(conn_sock);
+				continue;
+			}
+
+			ret = clear_group(vfio_data);
+
+			if (ret < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
+			else
+				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
+			break;
+		default:
+			vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			break;
+		}
+		close(conn_sock);
+	}
+}
+
+static int
+vfio_mp_sync_socket_setup(void)
+{
+	int ret, socket_fd;
+	struct sockaddr_un addr;
+	socklen_t sockaddr_len;
+
+	/* set up a socket */
+	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+	if (socket_fd < 0) {
+		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
+		return -1;
+	}
+
+	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
+	addr.sun_family = AF_UNIX;
+
+	sockaddr_len = sizeof(struct sockaddr_un);
+
+	unlink(addr.sun_path);
+
+	ret = bind(socket_fd, (struct sockaddr *) &addr, sockaddr_len);
+	if (ret) {
+		RTE_LOG(ERR, EAL, "Failed to bind socket: %s!\n", strerror(errno));
+		close(socket_fd);
+		return -1;
+	}
+
+	ret = listen(socket_fd, 50);
+	if (ret) {
+		RTE_LOG(ERR, EAL, "Failed to listen: %s!\n", strerror(errno));
+		close(socket_fd);
+		return -1;
+	}
+
+	/* save the socket in local configuration */
+	mp_socket_fd = socket_fd;
+
+	return 0;
+}
+
+/*
+ * set up a local socket and tell it to listen for incoming connections
+ */
+int
+vfio_mp_sync_setup(void)
+{
+	int ret;
+	char thread_name[RTE_MAX_THREAD_NAME_LEN];
+
+	if (vfio_mp_sync_socket_setup() < 0) {
+		RTE_LOG(ERR, EAL, "Failed to set up local socket!\n");
+		return -1;
+	}
+
+	ret = pthread_create(&socket_thread, NULL,
+			vfio_mp_sync_thread, NULL);
+	if (ret) {
+		RTE_LOG(ERR, EAL,
+			"Failed to create thread for communication with secondary processes!\n");
+		close(mp_socket_fd);
+		return -1;
+	}
+
+	/* Set thread_name for aid in debugging. */
+	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "vfio-sync");
+	ret = rte_thread_setname(socket_thread, thread_name);
+	if (ret)
+		RTE_LOG(DEBUG, EAL,
+			"Failed to set thread name for secondary processes!\n");
+
+	return 0;
+}
+
+#endif
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
new file mode 100644
index 0000000..7b68e99
--- /dev/null
+++ b/drivers/bus/pci/pci_common.c
@@ -0,0 +1,535 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+
+#include "private.h"
+
+extern struct rte_pci_bus rte_pci_bus;
+
+#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
+
+const char *pci_get_sysfs_path(void)
+{
+	const char *path = NULL;
+
+	path = getenv("SYSFS_PCI_DEVICES");
+	if (path == NULL)
+		return SYSFS_PCI_DEVICES;
+
+	return path;
+}
+
+static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
+{
+	struct rte_devargs *devargs;
+	struct rte_pci_addr addr;
+	struct rte_bus *pbus;
+
+	pbus = rte_bus_find_by_name("pci");
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->bus != pbus)
+			continue;
+		devargs->bus->parse(devargs->name, &addr);
+		if (!rte_eal_compare_pci_addr(&dev->addr, &addr))
+			return devargs;
+	}
+	return NULL;
+}
+
+void
+pci_name_set(struct rte_pci_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	/* Each device has its internal, canonical name set. */
+	rte_pci_device_name(&dev->addr,
+			dev->name, sizeof(dev->name));
+	devargs = pci_devargs_lookup(dev);
+	dev->device.devargs = devargs;
+	/* In blacklist mode, if the device is not blacklisted, no
+	 * rte_devargs exists for it.
+	 */
+	if (devargs != NULL)
+		/* If an rte_devargs exists, the generic rte_device uses the
+		 * given name as its namea
+		 */
+		dev->device.name = dev->device.devargs->name;
+	else
+		/* Otherwise, it uses the internal, canonical form. */
+		dev->device.name = dev->name;
+}
+
+/*
+ * Match the PCI Driver and Device using the ID Table
+ */
+int
+rte_pci_match(const struct rte_pci_driver *pci_drv,
+	      const struct rte_pci_device *pci_dev)
+{
+	const struct rte_pci_id *id_table;
+
+	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
+	     id_table++) {
+		/* check if device's identifiers match the driver's ones */
+		if (id_table->vendor_id != pci_dev->id.vendor_id &&
+				id_table->vendor_id != PCI_ANY_ID)
+			continue;
+		if (id_table->device_id != pci_dev->id.device_id &&
+				id_table->device_id != PCI_ANY_ID)
+			continue;
+		if (id_table->subsystem_vendor_id !=
+		    pci_dev->id.subsystem_vendor_id &&
+		    id_table->subsystem_vendor_id != PCI_ANY_ID)
+			continue;
+		if (id_table->subsystem_device_id !=
+		    pci_dev->id.subsystem_device_id &&
+		    id_table->subsystem_device_id != PCI_ANY_ID)
+			continue;
+		if (id_table->class_id != pci_dev->id.class_id &&
+				id_table->class_id != RTE_CLASS_ANY_ID)
+			continue;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * If vendor/device ID match, call the probe() function of the
+ * driver.
+ */
+static int
+rte_pci_probe_one_driver(struct rte_pci_driver *dr,
+			 struct rte_pci_device *dev)
+{
+	int ret;
+	struct rte_pci_addr *loc;
+
+	if ((dr == NULL) || (dev == NULL))
+		return -EINVAL;
+
+	loc = &dev->addr;
+
+	/* The device is not blacklisted; Check if driver supports it */
+	if (!rte_pci_match(dr, dev))
+		/* Match of device and driver failed */
+		return 1;
+
+	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			loc->domain, loc->bus, loc->devid, loc->function,
+			dev->device.numa_node);
+
+	/* no initialization when blacklisted, return without error */
+	if (dev->device.devargs != NULL &&
+		dev->device.devargs->policy ==
+			RTE_DEV_BLACKLISTED) {
+		RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
+			" initializing\n");
+		return 1;
+	}
+
+	if (dev->device.numa_node < 0) {
+		RTE_LOG(WARNING, EAL, "  Invalid NUMA socket, default to 0\n");
+		dev->device.numa_node = 0;
+	}
+
+	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
+		dev->id.device_id, dr->driver.name);
+
+	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+		/* map resources for devices that use igb_uio */
+		ret = rte_pci_map_device(dev);
+		if (ret != 0)
+			return ret;
+	}
+
+	/* reference driver structure */
+	dev->driver = dr;
+	dev->device.driver = &dr->driver;
+
+	/* call the driver probe() function */
+	ret = dr->probe(dr, dev);
+	if (ret) {
+		dev->driver = NULL;
+		dev->device.driver = NULL;
+		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
+			/* Don't unmap if device is unsupported and
+			 * driver needs mapped resources.
+			 */
+			!(ret > 0 &&
+				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
+			rte_pci_unmap_device(dev);
+	}
+
+	return ret;
+}
+
+/*
+ * If vendor/device ID match, call the remove() function of the
+ * driver.
+ */
+static int
+rte_pci_detach_dev(struct rte_pci_device *dev)
+{
+	struct rte_pci_addr *loc;
+	struct rte_pci_driver *dr;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	dr = dev->driver;
+	loc = &dev->addr;
+
+	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			loc->domain, loc->bus, loc->devid,
+			loc->function, dev->device.numa_node);
+
+	RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
+			dev->id.device_id, dr->driver.name);
+
+	if (dr->remove && (dr->remove(dev) < 0))
+		return -1;	/* negative value is an error */
+
+	/* clear driver structure */
+	dev->driver = NULL;
+
+	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
+		/* unmap resources for devices that use igb_uio */
+		rte_pci_unmap_device(dev);
+
+	return 0;
+}
+
+/*
+ * If vendor/device ID match, call the probe() function of all
+ * registered driver for the given device. Return -1 if initialization
+ * failed, return 1 if no driver is found for this device.
+ */
+static int
+pci_probe_all_drivers(struct rte_pci_device *dev)
+{
+	struct rte_pci_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	/* Check if a driver is already loaded */
+	if (dev->driver != NULL)
+		return 0;
+
+	FOREACH_DRIVER_ON_PCIBUS(dr) {
+		rc = rte_pci_probe_one_driver(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * Find the pci device specified by pci address, then invoke probe function of
+ * the driver of the device.
+ */
+int
+rte_pci_probe_one(const struct rte_pci_addr *addr)
+{
+	struct rte_pci_device *dev = NULL;
+
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	/* update current pci device in global list, kernel bindings might have
+	 * changed since last time we looked at it.
+	 */
+	if (pci_update_device(addr) < 0)
+		goto err_return;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (rte_eal_compare_pci_addr(&dev->addr, addr))
+			continue;
+
+		ret = pci_probe_all_drivers(dev);
+		if (ret)
+			goto err_return;
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL,
+		"Requested device " PCI_PRI_FMT " cannot be used\n",
+		addr->domain, addr->bus, addr->devid, addr->function);
+	return -1;
+}
+
+/*
+ * Detach device specified by its pci address.
+ */
+int
+rte_pci_detach(const struct rte_pci_addr *addr)
+{
+	struct rte_pci_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (rte_eal_compare_pci_addr(&dev->addr, addr))
+			continue;
+
+		ret = rte_pci_detach_dev(dev);
+		if (ret < 0)
+			/* negative value is an error */
+			goto err_return;
+		if (ret > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+
+		rte_pci_remove_device(dev);
+		free(dev);
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
+			" cannot be used\n", dev->addr.domain, dev->addr.bus,
+			dev->addr.devid, dev->addr.function);
+	return -1;
+}
+
+/*
+ * Scan the content of the PCI bus, and call the probe() function for
+ * all registered drivers that have a matching entry in its id_table
+ * for discovered devices.
+ */
+int
+rte_pci_probe(void)
+{
+	struct rte_pci_device *dev = NULL;
+	size_t probed = 0, failed = 0;
+	struct rte_devargs *devargs;
+	int probe_all = 0;
+	int ret = 0;
+
+	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
+		probe_all = 1;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		probed++;
+
+		devargs = dev->device.devargs;
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = pci_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->policy == RTE_DEV_WHITELISTED)
+			ret = pci_probe_all_drivers(dev);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
+				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
+				 dev->addr.devid, dev->addr.function);
+			rte_errno = errno;
+			failed++;
+			ret = 0;
+		}
+	}
+
+	return (probed && probed == failed) ? -1 : 0;
+}
+
+/* dump one device */
+static int
+pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
+{
+	int i;
+
+	fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
+	       dev->addr.devid, dev->addr.function);
+	fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
+	       dev->id.device_id);
+
+	for (i = 0; i != sizeof(dev->mem_resource) /
+		sizeof(dev->mem_resource[0]); i++) {
+		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
+			dev->mem_resource[i].phys_addr,
+			dev->mem_resource[i].len);
+	}
+	return 0;
+}
+
+/* dump devices on the bus */
+void
+rte_pci_dump(FILE *f)
+{
+	struct rte_pci_device *dev = NULL;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		pci_dump_one_device(f, dev);
+	}
+}
+
+static int
+pci_parse(const char *name, void *addr)
+{
+	struct rte_pci_addr *out = addr;
+	struct rte_pci_addr pci_addr;
+	bool parse;
+
+	parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
+		 eal_parse_pci_DomBDF(name, &pci_addr) == 0);
+	if (parse && addr != NULL)
+		*out = pci_addr;
+	return parse == false;
+}
+
+/* register a driver */
+void
+rte_pci_register(struct rte_pci_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
+	driver->bus = &rte_pci_bus;
+}
+
+/* unregister a driver */
+void
+rte_pci_unregister(struct rte_pci_driver *driver)
+{
+	TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
+	driver->bus = NULL;
+}
+
+/* Add a device to PCI bus */
+void
+rte_pci_add_device(struct rte_pci_device *pci_dev)
+{
+	TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
+}
+
+/* Insert a device into a predefined position in PCI bus */
+void
+rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+		      struct rte_pci_device *new_pci_dev)
+{
+	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
+}
+
+/* Remove a device from PCI bus */
+void
+rte_pci_remove_device(struct rte_pci_device *pci_dev)
+{
+	TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
+}
+
+static struct rte_device *
+pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		const void *data)
+{
+	struct rte_pci_device *dev;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (start && &dev->device == start) {
+			start = NULL; /* starting point found */
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+
+	return NULL;
+}
+
+static int
+pci_plug(struct rte_device *dev)
+{
+	return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
+}
+
+static int
+pci_unplug(struct rte_device *dev)
+{
+	struct rte_pci_device *pdev;
+	int ret;
+
+	pdev = RTE_DEV_TO_PCI(dev);
+	ret = rte_pci_detach_dev(pdev);
+	rte_pci_remove_device(pdev);
+	free(pdev);
+	return ret;
+}
+
+struct rte_pci_bus rte_pci_bus = {
+	.bus = {
+		.scan = rte_pci_scan,
+		.probe = rte_pci_probe,
+		.find_device = pci_find_device,
+		.plug = pci_plug,
+		.unplug = pci_unplug,
+		.parse = pci_parse,
+		.get_iommu_class = rte_pci_get_iommu_class,
+	},
+	.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
+	.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(pci, rte_pci_bus.bus);
diff --git a/drivers/bus/pci/pci_common_uio.c b/drivers/bus/pci/pci_common_uio.c
new file mode 100644
index 0000000..4365660
--- /dev/null
+++ b/drivers/bus/pci/pci_common_uio.c
@@ -0,0 +1,234 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_tailq.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+
+#include "private.h"
+
+static struct rte_tailq_elem rte_uio_tailq = {
+	.name = "UIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_uio_tailq)
+
+static int
+pci_uio_map_secondary(struct rte_pci_device *dev)
+{
+	int fd, i, j;
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	TAILQ_FOREACH(uio_res, uio_res_list, next) {
+
+		/* skip this element if it doesn't match our PCI address */
+		if (rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+			continue;
+
+		for (i = 0; i != uio_res->nb_maps; i++) {
+			/*
+			 * open devname, to mmap it
+			 */
+			fd = open(uio_res->maps[i].path, O_RDWR);
+			if (fd < 0) {
+				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+					uio_res->maps[i].path, strerror(errno));
+				return -1;
+			}
+
+			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
+					fd, (off_t)uio_res->maps[i].offset,
+					(size_t)uio_res->maps[i].size, 0);
+			/* fd is not needed in slave process, close it */
+			close(fd);
+			if (mapaddr != uio_res->maps[i].addr) {
+				RTE_LOG(ERR, EAL,
+					"Cannot mmap device resource file %s to address: %p\n",
+					uio_res->maps[i].path,
+					uio_res->maps[i].addr);
+				if (mapaddr != MAP_FAILED) {
+					/* unmap addrs correctly mapped */
+					for (j = 0; j < i; j++)
+						pci_unmap_resource(
+							uio_res->maps[j].addr,
+							(size_t)uio_res->maps[j].size);
+					/* unmap addr wrongly mapped */
+					pci_unmap_resource(mapaddr,
+						(size_t)uio_res->maps[i].size);
+				}
+				return -1;
+			}
+		}
+		return 0;
+	}
+
+	RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
+	return 1;
+}
+
+/* map the PCI resource of a PCI device in virtual memory */
+int
+pci_uio_map_resource(struct rte_pci_device *dev)
+{
+	int i, map_idx = 0, ret;
+	uint64_t phaddr;
+	struct mapped_pci_resource *uio_res = NULL;
+	struct mapped_pci_res_list *uio_res_list =
+		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.uio_cfg_fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* secondary processes - use already recorded details */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return pci_uio_map_secondary(dev);
+
+	/* allocate uio resource */
+	ret = pci_uio_alloc_resource(dev, &uio_res);
+	if (ret)
+		return ret;
+
+	/* Map all BARs */
+	for (i = 0; i != PCI_MAX_RESOURCE; i++) {
+		/* skip empty BAR */
+		phaddr = dev->mem_resource[i].phys_addr;
+		if (phaddr == 0)
+			continue;
+
+		ret = pci_uio_map_resource_by_index(dev, i,
+				uio_res, map_idx);
+		if (ret)
+			goto error;
+
+		map_idx++;
+	}
+
+	uio_res->nb_maps = map_idx;
+
+	TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
+
+	return 0;
+error:
+	for (i = 0; i < map_idx; i++) {
+		pci_unmap_resource(uio_res->maps[i].addr,
+				(size_t)uio_res->maps[i].size);
+		rte_free(uio_res->maps[i].path);
+	}
+	pci_uio_free_resource(dev, uio_res);
+	return -1;
+}
+
+static void
+pci_uio_unmap(struct mapped_pci_resource *uio_res)
+{
+	int i;
+
+	if (uio_res == NULL)
+		return;
+
+	for (i = 0; i != uio_res->nb_maps; i++) {
+		pci_unmap_resource(uio_res->maps[i].addr,
+				(size_t)uio_res->maps[i].size);
+		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+			rte_free(uio_res->maps[i].path);
+	}
+}
+
+static struct mapped_pci_resource *
+pci_uio_find_resource(struct rte_pci_device *dev)
+{
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	if (dev == NULL)
+		return NULL;
+
+	TAILQ_FOREACH(uio_res, uio_res_list, next) {
+
+		/* skip this element if it doesn't match our PCI address */
+		if (!rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+			return uio_res;
+	}
+	return NULL;
+}
+
+/* unmap the PCI resource of a PCI device in virtual memory */
+void
+pci_uio_unmap_resource(struct rte_pci_device *dev)
+{
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	if (dev == NULL)
+		return;
+
+	/* find an entry for the device */
+	uio_res = pci_uio_find_resource(dev);
+	if (uio_res == NULL)
+		return;
+
+	/* secondary processes - just free maps */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return pci_uio_unmap(uio_res);
+
+	TAILQ_REMOVE(uio_res_list, uio_res, next);
+
+	/* unmap all resources */
+	pci_uio_unmap(uio_res);
+
+	/* free uio resource */
+	rte_free(uio_res);
+
+	/* close fd if in primary process */
+	close(dev->intr_handle.fd);
+	if (dev->intr_handle.uio_cfg_fd >= 0) {
+		close(dev->intr_handle.uio_cfg_fd);
+		dev->intr_handle.uio_cfg_fd = -1;
+	}
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+}
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
new file mode 100644
index 0000000..7ff1fc4
--- /dev/null
+++ b/drivers/bus/pci/private.h
@@ -0,0 +1,173 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PCI_PRIVATE_H_
+#define _PCI_PRIVATE_H_
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <rte_pci.h>
+
+struct rte_pci_driver;
+struct rte_pci_device;
+
+/**
+ * Find the name of a PCI device.
+ */
+void
+pci_name_set(struct rte_pci_device *dev);
+
+/**
+ * Add a PCI device to the PCI Bus (append to PCI Device list). This function
+ * also updates the bus references of the PCI Device (and the generic device
+ * object embedded within.
+ *
+ * @param pci_dev
+ *	PCI device to add
+ * @return void
+ */
+void rte_pci_add_device(struct rte_pci_device *pci_dev);
+
+/**
+ * Insert a PCI device in the PCI Bus at a particular location in the device
+ * list. It also updates the PCI Bus reference of the new devices to be
+ * inserted.
+ *
+ * @param exist_pci_dev
+ *	Existing PCI device in PCI Bus
+ * @param new_pci_dev
+ *	PCI device to be added before exist_pci_dev
+ * @return void
+ */
+void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+		struct rte_pci_device *new_pci_dev);
+
+/**
+ * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
+ * in the PCI device object as well as the generic device object.
+ *
+ * @param pci_device
+ *	PCI device to be removed from PCI Bus
+ * @return void
+ */
+void rte_pci_remove_device(struct rte_pci_device *pci_device);
+
+/**
+ * Update a pci device object by asking the kernel for the latest information.
+ *
+ * This function is private to EAL.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to look for
+ * @return
+ *   - 0 on success.
+ *   - negative on error.
+ */
+int pci_update_device(const struct rte_pci_addr *addr);
+
+/**
+ * Unbind kernel driver for this device
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_unbind_kernel_driver(struct rte_pci_device *dev);
+
+/**
+ * Map the PCI resource of a PCI device in virtual memory
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_map_resource(struct rte_pci_device *dev);
+
+/**
+ * Unmap the PCI resource of a PCI device
+ *
+ * This function is private to EAL.
+ */
+void pci_uio_unmap_resource(struct rte_pci_device *dev);
+
+/**
+ * Allocate uio resource for PCI device
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device to allocate uio resource
+ * @param uio_res
+ *   Pointer to uio resource.
+ *   If the function returns 0, the pointer will be filled.
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res);
+
+/**
+ * Free uio resource for PCI device
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device to free uio resource
+ * @param uio_res
+ *   Pointer to uio resource.
+ */
+void pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res);
+
+/**
+ * Map device memory to uio resource
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device that has memory information.
+ * @param res_idx
+ *   Memory resource index of the PCI device.
+ * @param uio_res
+ *  uio resource that will keep mapping information.
+ * @param map_idx
+ *   Mapping information index of the uio resource.
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx);
+
+#endif /* _PCI_PRIVATE_H_ */
diff --git a/drivers/bus/pci/rte_bus_pci_version.map b/drivers/bus/pci/rte_bus_pci_version.map
new file mode 100644
index 0000000..c1973f6
--- /dev/null
+++ b/drivers/bus/pci/rte_bus_pci_version.map
@@ -0,0 +1,21 @@
+DPDK_17.11 {
+	global:
+
+	rte_pci_detach;
+	rte_pci_dump;
+	rte_pci_ioport_map;
+	rte_pci_ioport_read;
+	rte_pci_ioport_unmap;
+	rte_pci_ioport_write;
+	rte_pci_map_device;
+	rte_pci_probe;
+	rte_pci_probe_one;
+	rte_pci_read_config;
+	rte_pci_register;
+	rte_pci_scan;
+	rte_pci_unmap_device;
+	rte_pci_unregister;
+	rte_pci_write_config;
+
+	local: *;
+};
diff --git a/lib/Makefile b/lib/Makefile
index 86d475f..abe6467 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-y += librte_compat
 DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
+DIRS-$(CONFIG_RTE_LIBRTE_PCI) += librte_pci
+DEPDIRS-librte_pci := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
 DEPDIRS-librte_ring := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 317a75e..518832f 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -55,7 +55,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
@@ -69,8 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_errno.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 30d3bd5..2917808 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -66,7 +66,6 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_bus.h>
-#include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_version.h>
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
deleted file mode 100644
index 1595988..0000000
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ /dev/null
@@ -1,680 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-#include <limits.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/pciio.h>
-#include <dev/pci/pcireg.h>
-
-#if defined(RTE_ARCH_X86)
-#include <machine/cpufunc.h>
-#endif
-
-#include <rte_interrupts.h>
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_common.h>
-#include <rte_launch.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_eal.h>
-#include <rte_eal_memconfig.h>
-#include <rte_per_lcore.h>
-#include <rte_lcore.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-#include <rte_debug.h>
-#include <rte_devargs.h>
-
-#include "eal_filesystem.h"
-#include "eal_private.h"
-
-/**
- * @file
- * PCI probing under linux
- *
- * This code is used to simulate a PCI probe by parsing information in
- * sysfs. Moreover, when a registered driver matches a device, the
- * kernel driver currently using it is unloaded and replaced by
- * igb_uio module, which is a very minimal userland driver for Intel
- * network card, only providing access to PCI BAR to applications, and
- * enabling bus master.
- */
-
-extern struct rte_pci_bus rte_pci_bus;
-
-/* Map pci device */
-int
-rte_pci_map_device(struct rte_pci_device *dev)
-{
-	int ret = -1;
-
-	/* try mapping the NIC resources */
-	switch (dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		/* map resources for devices that use uio */
-		ret = pci_uio_map_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		ret = 1;
-		break;
-	}
-
-	return ret;
-}
-
-/* Unmap pci device */
-void
-rte_pci_unmap_device(struct rte_pci_device *dev)
-{
-	/* try unmapping the NIC resources */
-	switch (dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		/* unmap resources for devices that use uio */
-		pci_uio_unmap_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		break;
-	}
-}
-
-void
-pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res)
-{
-	rte_free(uio_res);
-
-	if (dev->intr_handle.fd) {
-		close(dev->intr_handle.fd);
-		dev->intr_handle.fd = -1;
-		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	}
-}
-
-int
-pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res)
-{
-	char devname[PATH_MAX]; /* contains the /dev/uioX */
-	struct rte_pci_addr *loc;
-
-	loc = &dev->addr;
-
-	snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
-			dev->addr.bus, dev->addr.devid, dev->addr.function);
-
-	if (access(devname, O_RDWR) < 0) {
-		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
-				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
-		return 1;
-	}
-
-	/* save fd if in primary process */
-	dev->intr_handle.fd = open(devname, O_RDWR);
-	if (dev->intr_handle.fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			devname, strerror(errno));
-		goto error;
-	}
-	dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-
-	/* allocate the mapping details for secondary processes*/
-	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
-	if (*uio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto error;
-	}
-
-	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
-	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
-
-	return 0;
-
-error:
-	pci_uio_free_resource(dev, *uio_res);
-	return -1;
-}
-
-int
-pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx)
-{
-	int fd;
-	char *devname;
-	void *mapaddr;
-	uint64_t offset;
-	uint64_t pagesz;
-	struct pci_map *maps;
-
-	maps = uio_res->maps;
-	devname = uio_res->path;
-	pagesz = sysconf(_SC_PAGESIZE);
-
-	/* allocate memory to keep path */
-	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
-	if (maps[map_idx].path == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
-				strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * open resource file, to mmap it
-	 */
-	fd = open(devname, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				devname, strerror(errno));
-		goto error;
-	}
-
-	/* if matching map is found, then use it */
-	offset = res_idx * pagesz;
-	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
-			(size_t)dev->mem_resource[res_idx].len, 0);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		goto error;
-
-	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
-	maps[map_idx].size = dev->mem_resource[res_idx].len;
-	maps[map_idx].addr = mapaddr;
-	maps[map_idx].offset = offset;
-	strcpy(maps[map_idx].path, devname);
-	dev->mem_resource[res_idx].addr = mapaddr;
-
-	return 0;
-
-error:
-	rte_free(maps[map_idx].path);
-	return -1;
-}
-
-static int
-pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
-{
-	struct rte_pci_device *dev;
-	struct pci_bar_io bar;
-	unsigned i, max;
-
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL) {
-		return -1;
-	}
-
-	memset(dev, 0, sizeof(*dev));
-	dev->addr.domain = conf->pc_sel.pc_domain;
-	dev->addr.bus = conf->pc_sel.pc_bus;
-	dev->addr.devid = conf->pc_sel.pc_dev;
-	dev->addr.function = conf->pc_sel.pc_func;
-
-	/* get vendor id */
-	dev->id.vendor_id = conf->pc_vendor;
-
-	/* get device id */
-	dev->id.device_id = conf->pc_device;
-
-	/* get subsystem_vendor id */
-	dev->id.subsystem_vendor_id = conf->pc_subvendor;
-
-	/* get subsystem_device id */
-	dev->id.subsystem_device_id = conf->pc_subdevice;
-
-	/* get class id */
-	dev->id.class_id = (conf->pc_class << 16) |
-			   (conf->pc_subclass << 8) |
-			   (conf->pc_progif);
-
-	/* TODO: get max_vfs */
-	dev->max_vfs = 0;
-
-	/* FreeBSD has no NUMA support (yet) */
-	dev->device.numa_node = 0;
-
-	pci_name_set(dev);
-
-	/* FreeBSD has only one pass through driver */
-	dev->kdrv = RTE_KDRV_NIC_UIO;
-
-	/* parse resources */
-	switch (conf->pc_hdr & PCIM_HDRTYPE) {
-	case PCIM_HDRTYPE_NORMAL:
-		max = PCIR_MAX_BAR_0;
-		break;
-	case PCIM_HDRTYPE_BRIDGE:
-		max = PCIR_MAX_BAR_1;
-		break;
-	case PCIM_HDRTYPE_CARDBUS:
-		max = PCIR_MAX_BAR_2;
-		break;
-	default:
-		goto skipdev;
-	}
-
-	for (i = 0; i <= max; i++) {
-		bar.pbi_sel = conf->pc_sel;
-		bar.pbi_reg = PCIR_BAR(i);
-		if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
-			continue;
-
-		dev->mem_resource[i].len = bar.pbi_length;
-		if (PCI_BAR_IO(bar.pbi_base)) {
-			dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
-			continue;
-		}
-		dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
-	}
-
-	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-		rte_pci_add_device(dev);
-	}
-	else {
-		struct rte_pci_device *dev2 = NULL;
-		int ret;
-
-		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
-			if (ret > 0)
-				continue;
-			else if (ret < 0) {
-				rte_pci_insert_device(dev2, dev);
-			} else { /* already registered */
-				dev2->kdrv = dev->kdrv;
-				dev2->max_vfs = dev->max_vfs;
-				pci_name_set(dev2);
-				memmove(dev2->mem_resource,
-					dev->mem_resource,
-					sizeof(dev->mem_resource));
-				free(dev);
-			}
-			return 0;
-		}
-		rte_pci_add_device(dev);
-	}
-
-	return 0;
-
-skipdev:
-	free(dev);
-	return 0;
-}
-
-/*
- * Scan the content of the PCI bus, and add the devices in the devices
- * list. Call pci_scan_one() for each pci entry found.
- */
-int
-rte_pci_scan(void)
-{
-	int fd;
-	unsigned dev_count = 0;
-	struct pci_conf matches[16];
-	struct pci_conf_io conf_io = {
-			.pat_buf_len = 0,
-			.num_patterns = 0,
-			.patterns = NULL,
-			.match_buf_len = sizeof(matches),
-			.matches = &matches[0],
-	};
-
-	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
-		return 0;
-
-	fd = open("/dev/pci", O_RDONLY);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	do {
-		unsigned i;
-		if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
-			RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
-					__func__, strerror(errno));
-			goto error;
-		}
-
-		for (i = 0; i < conf_io.num_matches; i++)
-			if (pci_scan_one(fd, &matches[i]) < 0)
-				goto error;
-
-		dev_count += conf_io.num_matches;
-	} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
-
-	close(fd);
-
-	RTE_LOG(DEBUG, EAL, "PCI scan found %u devices\n", dev_count);
-	return 0;
-
-error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/*
- * Get iommu class of PCI devices on the bus.
- */
-enum rte_iova_mode
-rte_pci_get_iommu_class(void)
-{
-	/* Supports only RTE_KDRV_NIC_UIO */
-	return RTE_IOVA_PA;
-}
-
-int
-pci_update_device(const struct rte_pci_addr *addr)
-{
-	int fd;
-	struct pci_conf matches[2];
-	struct pci_match_conf match = {
-		.pc_sel = {
-			.pc_domain = addr->domain,
-			.pc_bus = addr->bus,
-			.pc_dev = addr->devid,
-			.pc_func = addr->function,
-		},
-	};
-	struct pci_conf_io conf_io = {
-		.pat_buf_len = 0,
-		.num_patterns = 1,
-		.patterns = &match,
-		.match_buf_len = sizeof(matches),
-		.matches = &matches[0],
-	};
-
-	fd = open("/dev/pci", O_RDONLY);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
-				__func__, strerror(errno));
-		goto error;
-	}
-
-	if (conf_io.num_matches != 1)
-		goto error;
-
-	if (pci_scan_one(fd, &matches[0]) < 0)
-		goto error;
-
-	close(fd);
-
-	return 0;
-
-error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/* Read PCI config space. */
-int rte_pci_read_config(const struct rte_pci_device *dev,
-		void *buf, size_t len, off_t offset)
-{
-	int fd = -1;
-	int size;
-	struct pci_io pi = {
-		.pi_sel = {
-			.pc_domain = dev->addr.domain,
-			.pc_bus = dev->addr.bus,
-			.pc_dev = dev->addr.devid,
-			.pc_func = dev->addr.function,
-		},
-		.pi_reg = offset,
-	};
-
-	fd = open("/dev/pci", O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	while (len > 0) {
-		size = (len >= 4) ? 4 : ((len >= 2) ? 2 : 1);
-		pi.pi_width = size;
-
-		if (ioctl(fd, PCIOCREAD, &pi) < 0)
-			goto error;
-		memcpy(buf, &pi.pi_data, size);
-
-		buf = (char *)buf + size;
-		pi.pi_reg += size;
-		len -= size;
-	}
-	close(fd);
-
-	return 0;
-
- error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/* Write PCI config space. */
-int rte_pci_write_config(const struct rte_pci_device *dev,
-		const void *buf, size_t len, off_t offset)
-{
-	int fd = -1;
-
-	struct pci_io pi = {
-		.pi_sel = {
-			.pc_domain = dev->addr.domain,
-			.pc_bus = dev->addr.bus,
-			.pc_dev = dev->addr.devid,
-			.pc_func = dev->addr.function,
-		},
-		.pi_reg = offset,
-		.pi_data = *(const uint32_t *)buf,
-		.pi_width = len,
-	};
-
-	if (len == 3 || len > sizeof(pi.pi_data)) {
-		RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__);
-		goto error;
-	}
-
-	memcpy(&pi.pi_data, buf, len);
-
-	fd = open("/dev/pci", O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	if (ioctl(fd, PCIOCWRITE, &pi) < 0)
-		goto error;
-
-	close(fd);
-	return 0;
-
- error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-int
-rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p)
-{
-	int ret;
-
-	switch (dev->kdrv) {
-#if defined(RTE_ARCH_X86)
-	case RTE_KDRV_NIC_UIO:
-		if ((uintptr_t) dev->mem_resource[bar].addr <= UINT16_MAX) {
-			p->base = (uintptr_t)dev->mem_resource[bar].addr;
-			ret = 0;
-		} else
-			ret = -1;
-		break;
-#endif
-	default:
-		ret = -1;
-		break;
-	}
-
-	if (!ret)
-		p->dev = dev;
-
-	return ret;
-}
-
-static void
-pci_uio_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-#if defined(RTE_ARCH_X86)
-	uint8_t *d;
-	int size;
-	unsigned short reg = p->base + offset;
-
-	for (d = data; len > 0; d += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-			*(uint32_t *)d = inl(reg);
-		} else if (len >= 2) {
-			size = 2;
-			*(uint16_t *)d = inw(reg);
-		} else {
-			size = 1;
-			*d = inb(reg);
-		}
-	}
-#else
-	RTE_SET_USED(p);
-	RTE_SET_USED(data);
-	RTE_SET_USED(len);
-	RTE_SET_USED(offset);
-#endif
-}
-
-void
-rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	default:
-		break;
-	}
-}
-
-static void
-pci_uio_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-#if defined(RTE_ARCH_X86)
-	const uint8_t *s;
-	int size;
-	unsigned short reg = p->base + offset;
-
-	for (s = data; len > 0; s += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-			outl(reg, *(const uint32_t *)s);
-		} else if (len >= 2) {
-			size = 2;
-			outw(reg, *(const uint16_t *)s);
-		} else {
-			size = 1;
-			outb(reg, *s);
-		}
-	}
-#else
-	RTE_SET_USED(p);
-	RTE_SET_USED(data);
-	RTE_SET_USED(len);
-	RTE_SET_USED(offset);
-#endif
-}
-
-void
-rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	default:
-		break;
-	}
-}
-
-int
-rte_pci_ioport_unmap(struct rte_pci_ioport *p)
-{
-	int ret;
-
-	switch (p->dev->kdrv) {
-#if defined(RTE_ARCH_X86)
-	case RTE_KDRV_NIC_UIO:
-		ret = 0;
-		break;
-#endif
-	default:
-		ret = -1;
-		break;
-	}
-
-	return ret;
-}
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index d19f264..97b3918 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -166,21 +166,6 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_pci_detach;
-	rte_pci_dump;
-	rte_pci_ioport_map;
-	rte_pci_ioport_read;
-	rte_pci_ioport_unmap;
-	rte_pci_ioport_write;
-	rte_pci_map_device;
-	rte_pci_probe;
-	rte_pci_probe_one;
-	rte_pci_read_config;
-	rte_pci_register;
-	rte_pci_scan;
-	rte_pci_unmap_device;
-	rte_pci_unregister;
-	rte_pci_write_config;
 	rte_vdev_init;
 	rte_vdev_register;
 	rte_vdev_uninit;
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index e8fd67a..ac8d3bb 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h
 INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
deleted file mode 100644
index 0f0e4b9..0000000
--- a/lib/librte_eal/common/eal_common_pci.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   Copyright 2013-2014 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-
-#include <rte_errno.h>
-#include <rte_interrupts.h>
-#include <rte_log.h>
-#include <rte_bus.h>
-#include <rte_pci.h>
-#include <rte_per_lcore.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_eal.h>
-#include <rte_string_fns.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-
-#include "eal_private.h"
-
-extern struct rte_pci_bus rte_pci_bus;
-
-#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
-
-const char *pci_get_sysfs_path(void)
-{
-	const char *path = NULL;
-
-	path = getenv("SYSFS_PCI_DEVICES");
-	if (path == NULL)
-		return SYSFS_PCI_DEVICES;
-
-	return path;
-}
-
-static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_pci_addr addr;
-	struct rte_bus *pbus;
-
-	pbus = rte_bus_find_by_name("pci");
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-		if (devargs->bus != pbus)
-			continue;
-		devargs->bus->parse(devargs->name, &addr);
-		if (!rte_eal_compare_pci_addr(&dev->addr, &addr))
-			return devargs;
-	}
-	return NULL;
-}
-
-void
-pci_name_set(struct rte_pci_device *dev)
-{
-	struct rte_devargs *devargs;
-
-	/* Each device has its internal, canonical name set. */
-	rte_pci_device_name(&dev->addr,
-			dev->name, sizeof(dev->name));
-	devargs = pci_devargs_lookup(dev);
-	dev->device.devargs = devargs;
-	/* In blacklist mode, if the device is not blacklisted, no
-	 * rte_devargs exists for it.
-	 */
-	if (devargs != NULL)
-		/* If an rte_devargs exists, the generic rte_device uses the
-		 * given name as its namea
-		 */
-		dev->device.name = dev->device.devargs->name;
-	else
-		/* Otherwise, it uses the internal, canonical form. */
-		dev->device.name = dev->name;
-}
-
-/* map a particular resource from a file */
-void *
-pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
-		 int additional_flags)
-{
-	void *mapaddr;
-
-	/* Map the PCI memory resource of device */
-	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
-			MAP_SHARED | additional_flags, fd, offset);
-	if (mapaddr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
-			__func__, fd, requested_addr,
-			(unsigned long)size, (unsigned long)offset,
-			strerror(errno), mapaddr);
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
-
-	return mapaddr;
-}
-
-/* unmap a particular resource */
-void
-pci_unmap_resource(void *requested_addr, size_t size)
-{
-	if (requested_addr == NULL)
-		return;
-
-	/* Unmap the PCI memory resource of device */
-	if (munmap(requested_addr, size)) {
-		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
-			__func__, requested_addr, (unsigned long)size,
-			strerror(errno));
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
-				requested_addr);
-}
-
-/*
- * Match the PCI Driver and Device using the ID Table
- */
-int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev)
-{
-	const struct rte_pci_id *id_table;
-
-	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
-	     id_table++) {
-		/* check if device's identifiers match the driver's ones */
-		if (id_table->vendor_id != pci_dev->id.vendor_id &&
-				id_table->vendor_id != PCI_ANY_ID)
-			continue;
-		if (id_table->device_id != pci_dev->id.device_id &&
-				id_table->device_id != PCI_ANY_ID)
-			continue;
-		if (id_table->subsystem_vendor_id !=
-		    pci_dev->id.subsystem_vendor_id &&
-		    id_table->subsystem_vendor_id != PCI_ANY_ID)
-			continue;
-		if (id_table->subsystem_device_id !=
-		    pci_dev->id.subsystem_device_id &&
-		    id_table->subsystem_device_id != PCI_ANY_ID)
-			continue;
-		if (id_table->class_id != pci_dev->id.class_id &&
-				id_table->class_id != RTE_CLASS_ANY_ID)
-			continue;
-
-		return 1;
-	}
-
-	return 0;
-}
-
-/*
- * If vendor/device ID match, call the probe() function of the
- * driver.
- */
-static int
-rte_pci_probe_one_driver(struct rte_pci_driver *dr,
-			 struct rte_pci_device *dev)
-{
-	int ret;
-	struct rte_pci_addr *loc;
-
-	if ((dr == NULL) || (dev == NULL))
-		return -EINVAL;
-
-	loc = &dev->addr;
-
-	/* The device is not blacklisted; Check if driver supports it */
-	if (!rte_pci_match(dr, dev))
-		/* Match of device and driver failed */
-		return 1;
-
-	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-			loc->domain, loc->bus, loc->devid, loc->function,
-			dev->device.numa_node);
-
-	/* no initialization when blacklisted, return without error */
-	if (dev->device.devargs != NULL &&
-		dev->device.devargs->policy ==
-			RTE_DEV_BLACKLISTED) {
-		RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
-			" initializing\n");
-		return 1;
-	}
-
-	if (dev->device.numa_node < 0) {
-		RTE_LOG(WARNING, EAL, "  Invalid NUMA socket, default to 0\n");
-		dev->device.numa_node = 0;
-	}
-
-	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
-		dev->id.device_id, dr->driver.name);
-
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
-		/* map resources for devices that use igb_uio */
-		ret = rte_pci_map_device(dev);
-		if (ret != 0)
-			return ret;
-	}
-
-	/* reference driver structure */
-	dev->driver = dr;
-	dev->device.driver = &dr->driver;
-
-	/* call the driver probe() function */
-	ret = dr->probe(dr, dev);
-	if (ret) {
-		dev->driver = NULL;
-		dev->device.driver = NULL;
-		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
-			/* Don't unmap if device is unsupported and
-			 * driver needs mapped resources.
-			 */
-			!(ret > 0 &&
-				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
-			rte_pci_unmap_device(dev);
-	}
-
-	return ret;
-}
-
-/*
- * If vendor/device ID match, call the remove() function of the
- * driver.
- */
-static int
-rte_pci_detach_dev(struct rte_pci_device *dev)
-{
-	struct rte_pci_addr *loc;
-	struct rte_pci_driver *dr;
-
-	if (dev == NULL)
-		return -EINVAL;
-
-	dr = dev->driver;
-	loc = &dev->addr;
-
-	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-			loc->domain, loc->bus, loc->devid,
-			loc->function, dev->device.numa_node);
-
-	RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
-			dev->id.device_id, dr->driver.name);
-
-	if (dr->remove && (dr->remove(dev) < 0))
-		return -1;	/* negative value is an error */
-
-	/* clear driver structure */
-	dev->driver = NULL;
-
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
-		/* unmap resources for devices that use igb_uio */
-		rte_pci_unmap_device(dev);
-
-	return 0;
-}
-
-/*
- * If vendor/device ID match, call the probe() function of all
- * registered driver for the given device. Return -1 if initialization
- * failed, return 1 if no driver is found for this device.
- */
-static int
-pci_probe_all_drivers(struct rte_pci_device *dev)
-{
-	struct rte_pci_driver *dr = NULL;
-	int rc = 0;
-
-	if (dev == NULL)
-		return -1;
-
-	/* Check if a driver is already loaded */
-	if (dev->driver != NULL)
-		return 0;
-
-	FOREACH_DRIVER_ON_PCIBUS(dr) {
-		rc = rte_pci_probe_one_driver(dr, dev);
-		if (rc < 0)
-			/* negative value is an error */
-			return -1;
-		if (rc > 0)
-			/* positive value means driver doesn't support it */
-			continue;
-		return 0;
-	}
-	return 1;
-}
-
-/*
- * Find the pci device specified by pci address, then invoke probe function of
- * the driver of the device.
- */
-int
-rte_pci_probe_one(const struct rte_pci_addr *addr)
-{
-	struct rte_pci_device *dev = NULL;
-
-	int ret = 0;
-
-	if (addr == NULL)
-		return -1;
-
-	/* update current pci device in global list, kernel bindings might have
-	 * changed since last time we looked at it.
-	 */
-	if (pci_update_device(addr) < 0)
-		goto err_return;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_eal_compare_pci_addr(&dev->addr, addr))
-			continue;
-
-		ret = pci_probe_all_drivers(dev);
-		if (ret)
-			goto err_return;
-		return 0;
-	}
-	return -1;
-
-err_return:
-	RTE_LOG(WARNING, EAL,
-		"Requested device " PCI_PRI_FMT " cannot be used\n",
-		addr->domain, addr->bus, addr->devid, addr->function);
-	return -1;
-}
-
-/*
- * Detach device specified by its pci address.
- */
-int
-rte_pci_detach(const struct rte_pci_addr *addr)
-{
-	struct rte_pci_device *dev = NULL;
-	int ret = 0;
-
-	if (addr == NULL)
-		return -1;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_eal_compare_pci_addr(&dev->addr, addr))
-			continue;
-
-		ret = rte_pci_detach_dev(dev);
-		if (ret < 0)
-			/* negative value is an error */
-			goto err_return;
-		if (ret > 0)
-			/* positive value means driver doesn't support it */
-			continue;
-
-		rte_pci_remove_device(dev);
-		free(dev);
-		return 0;
-	}
-	return -1;
-
-err_return:
-	RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
-			" cannot be used\n", dev->addr.domain, dev->addr.bus,
-			dev->addr.devid, dev->addr.function);
-	return -1;
-}
-
-/*
- * Scan the content of the PCI bus, and call the probe() function for
- * all registered drivers that have a matching entry in its id_table
- * for discovered devices.
- */
-int
-rte_pci_probe(void)
-{
-	struct rte_pci_device *dev = NULL;
-	size_t probed = 0, failed = 0;
-	struct rte_devargs *devargs;
-	int probe_all = 0;
-	int ret = 0;
-
-	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
-		probe_all = 1;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		probed++;
-
-		devargs = dev->device.devargs;
-		/* probe all or only whitelisted devices */
-		if (probe_all)
-			ret = pci_probe_all_drivers(dev);
-		else if (devargs != NULL &&
-			devargs->policy == RTE_DEV_WHITELISTED)
-			ret = pci_probe_all_drivers(dev);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
-				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
-				 dev->addr.devid, dev->addr.function);
-			rte_errno = errno;
-			failed++;
-			ret = 0;
-		}
-	}
-
-	return (probed && probed == failed) ? -1 : 0;
-}
-
-/* dump one device */
-static int
-pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
-{
-	int i;
-
-	fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
-	       dev->addr.devid, dev->addr.function);
-	fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
-	       dev->id.device_id);
-
-	for (i = 0; i != sizeof(dev->mem_resource) /
-		sizeof(dev->mem_resource[0]); i++) {
-		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
-			dev->mem_resource[i].phys_addr,
-			dev->mem_resource[i].len);
-	}
-	return 0;
-}
-
-/* dump devices on the bus */
-void
-rte_pci_dump(FILE *f)
-{
-	struct rte_pci_device *dev = NULL;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		pci_dump_one_device(f, dev);
-	}
-}
-
-static int
-pci_parse(const char *name, void *addr)
-{
-	struct rte_pci_addr *out = addr;
-	struct rte_pci_addr pci_addr;
-	bool parse;
-
-	parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
-		 eal_parse_pci_DomBDF(name, &pci_addr) == 0);
-	if (parse && addr != NULL)
-		*out = pci_addr;
-	return parse == false;
-}
-
-/* register a driver */
-void
-rte_pci_register(struct rte_pci_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
-	driver->bus = &rte_pci_bus;
-}
-
-/* unregister a driver */
-void
-rte_pci_unregister(struct rte_pci_driver *driver)
-{
-	TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
-	driver->bus = NULL;
-}
-
-/* Add a device to PCI bus */
-void
-rte_pci_add_device(struct rte_pci_device *pci_dev)
-{
-	TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
-}
-
-/* Insert a device into a predefined position in PCI bus */
-void
-rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
-		      struct rte_pci_device *new_pci_dev)
-{
-	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
-}
-
-/* Remove a device from PCI bus */
-void
-rte_pci_remove_device(struct rte_pci_device *pci_dev)
-{
-	TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
-}
-
-static struct rte_device *
-pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		const void *data)
-{
-	struct rte_pci_device *dev;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (start && &dev->device == start) {
-			start = NULL; /* starting point found */
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-
-	return NULL;
-}
-
-static int
-pci_plug(struct rte_device *dev)
-{
-	return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
-}
-
-static int
-pci_unplug(struct rte_device *dev)
-{
-	struct rte_pci_device *pdev;
-	int ret;
-
-	pdev = RTE_DEV_TO_PCI(dev);
-	ret = rte_pci_detach_dev(pdev);
-	rte_pci_remove_device(pdev);
-	free(pdev);
-	return ret;
-}
-
-struct rte_pci_bus rte_pci_bus = {
-	.bus = {
-		.scan = rte_pci_scan,
-		.probe = rte_pci_probe,
-		.find_device = pci_find_device,
-		.plug = pci_plug,
-		.unplug = pci_unplug,
-		.parse = pci_parse,
-		.get_iommu_class = rte_pci_get_iommu_class,
-	},
-	.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
-	.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
-};
-
-RTE_REGISTER_BUS(pci, rte_pci_bus.bus);
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
deleted file mode 100644
index 367a681..0000000
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include <rte_eal.h>
-#include <rte_tailq.h>
-#include <rte_log.h>
-#include <rte_malloc.h>
-
-#include "eal_private.h"
-
-static struct rte_tailq_elem rte_uio_tailq = {
-	.name = "UIO_RESOURCE_LIST",
-};
-EAL_REGISTER_TAILQ(rte_uio_tailq)
-
-static int
-pci_uio_map_secondary(struct rte_pci_device *dev)
-{
-	int fd, i, j;
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	TAILQ_FOREACH(uio_res, uio_res_list, next) {
-
-		/* skip this element if it doesn't match our PCI address */
-		if (rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
-			continue;
-
-		for (i = 0; i != uio_res->nb_maps; i++) {
-			/*
-			 * open devname, to mmap it
-			 */
-			fd = open(uio_res->maps[i].path, O_RDWR);
-			if (fd < 0) {
-				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-					uio_res->maps[i].path, strerror(errno));
-				return -1;
-			}
-
-			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
-					fd, (off_t)uio_res->maps[i].offset,
-					(size_t)uio_res->maps[i].size, 0);
-			/* fd is not needed in slave process, close it */
-			close(fd);
-			if (mapaddr != uio_res->maps[i].addr) {
-				RTE_LOG(ERR, EAL,
-					"Cannot mmap device resource file %s to address: %p\n",
-					uio_res->maps[i].path,
-					uio_res->maps[i].addr);
-				if (mapaddr != MAP_FAILED) {
-					/* unmap addrs correctly mapped */
-					for (j = 0; j < i; j++)
-						pci_unmap_resource(
-							uio_res->maps[j].addr,
-							(size_t)uio_res->maps[j].size);
-					/* unmap addr wrongly mapped */
-					pci_unmap_resource(mapaddr,
-						(size_t)uio_res->maps[i].size);
-				}
-				return -1;
-			}
-		}
-		return 0;
-	}
-
-	RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
-	return 1;
-}
-
-/* map the PCI resource of a PCI device in virtual memory */
-int
-pci_uio_map_resource(struct rte_pci_device *dev)
-{
-	int i, map_idx = 0, ret;
-	uint64_t phaddr;
-	struct mapped_pci_resource *uio_res = NULL;
-	struct mapped_pci_res_list *uio_res_list =
-		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.uio_cfg_fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* secondary processes - use already recorded details */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return pci_uio_map_secondary(dev);
-
-	/* allocate uio resource */
-	ret = pci_uio_alloc_resource(dev, &uio_res);
-	if (ret)
-		return ret;
-
-	/* Map all BARs */
-	for (i = 0; i != PCI_MAX_RESOURCE; i++) {
-		/* skip empty BAR */
-		phaddr = dev->mem_resource[i].phys_addr;
-		if (phaddr == 0)
-			continue;
-
-		ret = pci_uio_map_resource_by_index(dev, i,
-				uio_res, map_idx);
-		if (ret)
-			goto error;
-
-		map_idx++;
-	}
-
-	uio_res->nb_maps = map_idx;
-
-	TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
-
-	return 0;
-error:
-	for (i = 0; i < map_idx; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
-				(size_t)uio_res->maps[i].size);
-		rte_free(uio_res->maps[i].path);
-	}
-	pci_uio_free_resource(dev, uio_res);
-	return -1;
-}
-
-static void
-pci_uio_unmap(struct mapped_pci_resource *uio_res)
-{
-	int i;
-
-	if (uio_res == NULL)
-		return;
-
-	for (i = 0; i != uio_res->nb_maps; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
-				(size_t)uio_res->maps[i].size);
-		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-			rte_free(uio_res->maps[i].path);
-	}
-}
-
-static struct mapped_pci_resource *
-pci_uio_find_resource(struct rte_pci_device *dev)
-{
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	if (dev == NULL)
-		return NULL;
-
-	TAILQ_FOREACH(uio_res, uio_res_list, next) {
-
-		/* skip this element if it doesn't match our PCI address */
-		if (!rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
-			return uio_res;
-	}
-	return NULL;
-}
-
-/* unmap the PCI resource of a PCI device in virtual memory */
-void
-pci_uio_unmap_resource(struct rte_pci_device *dev)
-{
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	if (dev == NULL)
-		return;
-
-	/* find an entry for the device */
-	uio_res = pci_uio_find_resource(dev);
-	if (uio_res == NULL)
-		return;
-
-	/* secondary processes - just free maps */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return pci_uio_unmap(uio_res);
-
-	TAILQ_REMOVE(uio_res_list, uio_res, next);
-
-	/* unmap all resources */
-	pci_uio_unmap(uio_res);
-
-	/* free uio resource */
-	rte_free(uio_res);
-
-	/* close fd if in primary process */
-	close(dev->intr_handle.fd);
-	if (dev->intr_handle.uio_cfg_fd >= 0) {
-		close(dev->intr_handle.uio_cfg_fd);
-		dev->intr_handle.uio_cfg_fd = -1;
-	}
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 597d82e..6baa667 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,7 +36,6 @@
 
 #include <stdbool.h>
 #include <stdio.h>
-#include <rte_pci.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -109,137 +108,6 @@ int rte_eal_timer_init(void);
  */
 int rte_eal_log_init(const char *id, int facility);
 
-struct rte_pci_driver;
-struct rte_pci_device;
-
-/**
- * Find the name of a PCI device.
- */
-void pci_name_set(struct rte_pci_device *dev);
-
-/**
- * Add a PCI device to the PCI Bus (append to PCI Device list). This function
- * also updates the bus references of the PCI Device (and the generic device
- * object embedded within.
- *
- * @param pci_dev
- *	PCI device to add
- * @return void
- */
-void rte_pci_add_device(struct rte_pci_device *pci_dev);
-
-/**
- * Insert a PCI device in the PCI Bus at a particular location in the device
- * list. It also updates the PCI Bus reference of the new devices to be
- * inserted.
- *
- * @param exist_pci_dev
- *	Existing PCI device in PCI Bus
- * @param new_pci_dev
- *	PCI device to be added before exist_pci_dev
- * @return void
- */
-void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
-		struct rte_pci_device *new_pci_dev);
-
-/**
- * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
- * in the PCI device object as well as the generic device object.
- *
- * @param pci_device
- *	PCI device to be removed from PCI Bus
- * @return void
- */
-void rte_pci_remove_device(struct rte_pci_device *pci_device);
-
-/**
- * Update a pci device object by asking the kernel for the latest information.
- *
- * This function is private to EAL.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to look for
- * @return
- *   - 0 on success.
- *   - negative on error.
- */
-int pci_update_device(const struct rte_pci_addr *addr);
-
-/**
- * Unbind kernel driver for this device
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int pci_unbind_kernel_driver(struct rte_pci_device *dev);
-
-/**
- * Map the PCI resource of a PCI device in virtual memory
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_map_resource(struct rte_pci_device *dev);
-
-/**
- * Unmap the PCI resource of a PCI device
- *
- * This function is private to EAL.
- */
-void pci_uio_unmap_resource(struct rte_pci_device *dev);
-
-/**
- * Allocate uio resource for PCI device
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device to allocate uio resource
- * @param uio_res
- *   Pointer to uio resource.
- *   If the function returns 0, the pointer will be filled.
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res);
-
-/**
- * Free uio resource for PCI device
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device to free uio resource
- * @param uio_res
- *   Pointer to uio resource.
- */
-void pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res);
-
-/**
- * Map device memory to uio resource
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device that has memory information.
- * @param res_idx
- *   Memory resource index of the PCI device.
- * @param uio_res
- *  uio resource that will keep mapping information.
- * @param map_idx
- *   Mapping information index of the uio resource.
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx);
-
 /**
  * Init tail queues for non-EAL library structures. This is to allow
  * the rings, mempools, etc. lists to be shared among multiple processes
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
deleted file mode 100644
index 1c5f469..0000000
--- a/lib/librte_eal/common/include/rte_pci.h
+++ /dev/null
@@ -1,633 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   Copyright 2013-2014 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_PCI_H_
-#define _RTE_PCI_H_
-
-/**
- * @file
- *
- * RTE PCI Interface
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <errno.h>
-#include <sys/queue.h>
-#include <stdint.h>
-#include <inttypes.h>
-
-#include <rte_debug.h>
-#include <rte_interrupts.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-
-/** Pathname of PCI devices directory. */
-const char *pci_get_sysfs_path(void);
-
-/** Formatting string for PCI device identifier: Ex: 0000:00:01.0 */
-#define PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
-#define PCI_PRI_STR_SIZE sizeof("XXXXXXXX:XX:XX.X")
-
-/** Short formatting string, without domain, for PCI device: Ex: 00:01.0 */
-#define PCI_SHORT_PRI_FMT "%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
-
-/** Nb. of values in PCI device identifier format string. */
-#define PCI_FMT_NVAL 4
-
-/** Nb. of values in PCI resource format. */
-#define PCI_RESOURCE_FMT_NVAL 3
-
-/** Maximum number of PCI resources. */
-#define PCI_MAX_RESOURCE 6
-
-/* Forward declarations */
-struct rte_pci_device;
-struct rte_pci_driver;
-
-/** List of PCI devices */
-TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
-/** List of PCI drivers */
-TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
-
-/* PCI Bus iterators */
-#define FOREACH_DEVICE_ON_PCIBUS(p)	\
-		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
-
-#define FOREACH_DRIVER_ON_PCIBUS(p)	\
-		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
-
-/**
- * A structure describing an ID for a PCI driver. Each driver provides a
- * table of these IDs for each device that it supports.
- */
-struct rte_pci_id {
-	uint32_t class_id;            /**< Class ID (class, subclass, pi) or RTE_CLASS_ANY_ID. */
-	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
-	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
-	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
-	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
-};
-
-/**
- * A structure describing the location of a PCI device.
- */
-struct rte_pci_addr {
-	uint32_t domain;                /**< Device domain */
-	uint8_t bus;                    /**< Device bus */
-	uint8_t devid;                  /**< Device ID */
-	uint8_t function;               /**< Device function. */
-};
-
-struct rte_devargs;
-
-/**
- * A structure describing a PCI device.
- */
-struct rte_pci_device {
-	TAILQ_ENTRY(rte_pci_device) next;       /**< Next probed PCI device. */
-	struct rte_device device;               /**< Inherit core device */
-	struct rte_pci_addr addr;               /**< PCI location. */
-	struct rte_pci_id id;                   /**< PCI ID. */
-	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
-						/**< PCI Memory Resource */
-	struct rte_intr_handle intr_handle;     /**< Interrupt handle */
-	struct rte_pci_driver *driver;          /**< Associated driver */
-	uint16_t max_vfs;                       /**< sriov enable if not zero */
-	enum rte_kernel_driver kdrv;            /**< Kernel driver passthrough */
-	char name[PCI_PRI_STR_SIZE+1];          /**< PCI location (ASCII) */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_pci_device.
- */
-#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
-
-/** Any PCI device identifier (vendor, device, ...) */
-#define PCI_ANY_ID (0xffff)
-#define RTE_CLASS_ANY_ID (0xffffff)
-
-#ifdef __cplusplus
-/** C++ macro used to help building up tables of device IDs */
-#define RTE_PCI_DEVICE(vend, dev) \
-	RTE_CLASS_ANY_ID,         \
-	(vend),                   \
-	(dev),                    \
-	PCI_ANY_ID,               \
-	PCI_ANY_ID
-#else
-/** Macro used to help building up tables of device IDs */
-#define RTE_PCI_DEVICE(vend, dev)          \
-	.class_id = RTE_CLASS_ANY_ID,      \
-	.vendor_id = (vend),               \
-	.device_id = (dev),                \
-	.subsystem_vendor_id = PCI_ANY_ID, \
-	.subsystem_device_id = PCI_ANY_ID
-#endif
-
-/**
- * Initialisation function for the driver called during PCI probing.
- */
-typedef int (pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
-
-/**
- * Uninitialisation function for the driver called during hotplugging.
- */
-typedef int (pci_remove_t)(struct rte_pci_device *);
-
-/**
- * A structure describing a PCI driver.
- */
-struct rte_pci_driver {
-	TAILQ_ENTRY(rte_pci_driver) next;       /**< Next in list. */
-	struct rte_driver driver;               /**< Inherit core driver. */
-	struct rte_pci_bus *bus;                /**< PCI bus reference. */
-	pci_probe_t *probe;                     /**< Device Probe function. */
-	pci_remove_t *remove;                   /**< Device Remove function. */
-	const struct rte_pci_id *id_table;	/**< ID table, NULL terminated. */
-	uint32_t drv_flags;                     /**< Flags contolling handling of device. */
-};
-
-/**
- * Structure describing the PCI bus
- */
-struct rte_pci_bus {
-	struct rte_bus bus;               /**< Inherit the generic class */
-	struct rte_pci_device_list device_list;  /**< List of PCI devices */
-	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
-};
-
-/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
-#define RTE_PCI_DRV_NEED_MAPPING 0x0001
-/** Device driver supports link state interrupt */
-#define RTE_PCI_DRV_INTR_LSC	0x0008
-/** Device driver supports device removal interrupt */
-#define RTE_PCI_DRV_INTR_RMV 0x0010
-/** Device driver needs to keep mapped resources if unsupported dev detected */
-#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
-/** Device driver supports IOVA as VA */
-#define RTE_PCI_DRV_IOVA_AS_VA 0X0040
-
-/**
- * A structure describing a PCI mapping.
- */
-struct pci_map {
-	void *addr;
-	char *path;
-	uint64_t offset;
-	uint64_t size;
-	uint64_t phaddr;
-};
-
-struct pci_msix_table {
-	int bar_index;
-	uint32_t offset;
-	uint32_t size;
-};
-
-/**
- * A structure describing a mapped PCI resource.
- * For multi-process we need to reproduce all PCI mappings in secondary
- * processes, so save them in a tailq.
- */
-struct mapped_pci_resource {
-	TAILQ_ENTRY(mapped_pci_resource) next;
-
-	struct rte_pci_addr pci_addr;
-	char path[PATH_MAX];
-	int nb_maps;
-	struct pci_map maps[PCI_MAX_RESOURCE];
-	struct pci_msix_table msix_table;
-};
-
-/** mapped pci device list */
-TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
-
-/**< Internal use only - Macro used by pci addr parsing functions **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
-do {                                                               \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
-
-/**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided without
- * a domain prefix (i.e. domain returned is always 0)
- *
- * @param input
- *	The input string to be parsed. Should have the format XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned. Domain will always be
- *	returned as 0
- * @return
- *  0 on success, negative on error.
- */
-static inline int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-
-/**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided including
- * a domain prefix.
- *
- * @param input
- *	The input string to be parsed. Should have the format XXXX:XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned
- * @return
- *  0 on success, negative on error.
- */
-static inline int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-#undef GET_PCIADDR_FIELD
-
-/**
- * Utility function to write a pci device name, this device name can later be
- * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
- * BDF helpers.
- *
- * @param addr
- *	The PCI Bus-Device-Function address
- * @param output
- *	The output buffer string
- * @param size
- *	The output buffer size
- */
-static inline void
-rte_pci_device_name(const struct rte_pci_addr *addr,
-		char *output, size_t size)
-{
-	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
-	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
-			    addr->domain, addr->bus,
-			    addr->devid, addr->function) >= 0);
-}
-
-/* Compare two PCI device addresses. */
-/**
- * Utility function to compare two PCI device addresses.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to compare
- * @param addr2
- *	The PCI Bus-Device-Function address to compare
- * @return
- *	0 on equal PCI address.
- *	Positive on addr is greater than addr2.
- *	Negative on addr is less than addr2, or error.
- */
-static inline int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			 const struct rte_pci_addr *addr2)
-{
-	uint64_t dev_addr, dev_addr2;
-
-	if ((addr == NULL) || (addr2 == NULL))
-		return -1;
-
-	dev_addr = ((uint64_t)addr->domain << 24) |
-		(addr->bus << 16) | (addr->devid << 8) | addr->function;
-	dev_addr2 = ((uint64_t)addr2->domain << 24) |
-		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
-
-	if (dev_addr > dev_addr2)
-		return 1;
-	else if (dev_addr < dev_addr2)
-		return -1;
-	else
-		return 0;
-}
-
-/**
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- *
- * @return
- *  0 on success, negative on error
- */
-int rte_pci_scan(void);
-
-/**
- * Probe the PCI bus
- *
- * @return
- *   - 0 on success.
- *   - !0 on error.
- */
-int
-rte_pci_probe(void);
-
-/*
- * Match the PCI Driver and Device using the ID Table
- *
- * @param pci_drv
- *      PCI driver from which ID table would be extracted
- * @param pci_dev
- *      PCI device to match against the driver
- * @return
- *      1 for successful match
- *      0 for unsuccessful match
- */
-int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev);
-
-
-/**
- * Get iommu class of PCI devices on the bus.
- * And return their preferred iova mapping mode.
- *
- * @return
- *   - enum rte_iova_mode.
- */
-enum rte_iova_mode
-rte_pci_get_iommu_class(void);
-
-/**
- * Map the PCI device resources in user space virtual memory address
- *
- * Note that driver should not call this function when flag
- * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for
- * you when it's on.
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- *
- * @return
- *   0 on success, negative on error and positive if no driver
- *   is found for the device.
- */
-int rte_pci_map_device(struct rte_pci_device *dev);
-
-/**
- * Unmap this device
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- */
-void rte_pci_unmap_device(struct rte_pci_device *dev);
-
-/**
- * @internal
- * Map a particular resource from a file.
- *
- * @param requested_addr
- *      The starting address for the new mapping range.
- * @param fd
- *      The file descriptor.
- * @param offset
- *      The offset for the mapping range.
- * @param size
- *      The size for the mapping range.
- * @param additional_flags
- *      The additional flags for the mapping range.
- * @return
- *   - On success, the function returns a pointer to the mapped area.
- *   - On error, the value MAP_FAILED is returned.
- */
-void *pci_map_resource(void *requested_addr, int fd, off_t offset,
-		size_t size, int additional_flags);
-
-/**
- * @internal
- * Unmap a particular resource.
- *
- * @param requested_addr
- *      The address for the unmapping range.
- * @param size
- *      The size for the unmapping range.
- */
-void pci_unmap_resource(void *requested_addr, size_t size);
-
-/**
- * Probe the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the probe() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to probe.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_probe_one(const struct rte_pci_addr *addr);
-
-/**
- * Close the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the remove() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to close.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_detach(const struct rte_pci_addr *addr);
-
-/**
- * Dump the content of the PCI bus.
- *
- * @param f
- *   A pointer to a file for output
- */
-void rte_pci_dump(FILE *f);
-
-/**
- * Register a PCI driver.
- *
- * @param driver
- *   A pointer to a rte_pci_driver structure describing the driver
- *   to be registered.
- */
-void rte_pci_register(struct rte_pci_driver *driver);
-
-/** Helper for PCI device registration from driver (eth, crypto) instance */
-#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
-RTE_INIT(pciinitfn_ ##nm); \
-static void pciinitfn_ ##nm(void) \
-{\
-	(pci_drv).driver.name = RTE_STR(nm);\
-	rte_pci_register(&pci_drv); \
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-/**
- * Unregister a PCI driver.
- *
- * @param driver
- *   A pointer to a rte_pci_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_pci_unregister(struct rte_pci_driver *driver);
-
-/**
- * Read PCI config space.
- *
- * @param device
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- * @param buf
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into PCI config space
- */
-int rte_pci_read_config(const struct rte_pci_device *device,
-		void *buf, size_t len, off_t offset);
-
-/**
- * Write PCI config space.
- *
- * @param device
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- * @param buf
- *   A data buffer containing the bytes should be written
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into PCI config space
- */
-int rte_pci_write_config(const struct rte_pci_device *device,
-		const void *buf, size_t len, off_t offset);
-
-/**
- * A structure used to access io resources for a pci device.
- * rte_pci_ioport is arch, os, driver specific, and should not be used outside
- * of pci ioport api.
- */
-struct rte_pci_ioport {
-	struct rte_pci_device *dev;
-	uint64_t base;
-	uint64_t len; /* only filled for memory mapped ports */
-};
-
-/**
- * Initialize a rte_pci_ioport object for a pci device io resource.
- *
- * This object is then used to gain access to those io resources (see below).
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use.
- * @param bar
- *   Index of the io pci resource we want to access.
- * @param p
- *   The rte_pci_ioport object to be initialized.
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p);
-
-/**
- * Release any resources used in a rte_pci_ioport object.
- *
- * @param p
- *   The rte_pci_ioport object to be uninitialized.
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_ioport_unmap(struct rte_pci_ioport *p);
-
-/**
- * Read from a io pci resource.
- *
- * @param p
- *   The rte_pci_ioport object from which we want to read.
- * @param data
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into the pci io resource.
- */
-void rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset);
-
-/**
- * Write to a io pci resource.
- *
- * @param p
- *   The rte_pci_ioport object to which we want to write.
- * @param data
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into the pci io resource.
- */
-void rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RTE_PCI_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 21e0b4a..90adb8d 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -61,10 +61,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
@@ -78,8 +74,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_errno.c
@@ -106,16 +100,12 @@ CFLAGS_eal_common_cpuflags.o := $(CPUFLAGS_LIST)
 
 CFLAGS_eal.o := -D_GNU_SOURCE
 CFLAGS_eal_interrupts.o := -D_GNU_SOURCE
-CFLAGS_eal_vfio_mp_sync.o := -D_GNU_SOURCE
 CFLAGS_eal_timer.o := -D_GNU_SOURCE
 CFLAGS_eal_lcore.o := -D_GNU_SOURCE
 CFLAGS_eal_thread.o := -D_GNU_SOURCE
 CFLAGS_eal_log.o := -D_GNU_SOURCE
 CFLAGS_eal_common_log.o := -D_GNU_SOURCE
 CFLAGS_eal_hugepage_info.o := -D_GNU_SOURCE
-CFLAGS_eal_pci.o := -D_GNU_SOURCE
-CFLAGS_eal_pci_uio.o := -D_GNU_SOURCE
-CFLAGS_eal_pci_vfio.o := -D_GNU_SOURCE
 CFLAGS_eal_common_whitelist.o := -D_GNU_SOURCE
 CFLAGS_eal_common_options.o := -D_GNU_SOURCE
 CFLAGS_eal_common_thread.o := -D_GNU_SOURCE
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index ec37c52..5005e6d 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -71,7 +71,6 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_bus.h>
-#include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_version.h>
diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
index 3e9ac41..0bebf00 100644
--- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
@@ -60,7 +60,6 @@
 #include <rte_branch_prediction.h>
 #include <rte_debug.h>
 #include <rte_log.h>
-#include <rte_pci.h>
 #include <rte_malloc.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
deleted file mode 100644
index b4dbf95..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ /dev/null
@@ -1,818 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <dirent.h>
-
-#include <rte_log.h>
-#include <rte_bus.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-#include <rte_devargs.h>
-#include <rte_memcpy.h>
-
-#include "eal_filesystem.h"
-#include "eal_private.h"
-#include "eal_pci_init.h"
-#include "eal_vfio.h"
-
-/**
- * @file
- * PCI probing under linux
- *
- * This code is used to simulate a PCI probe by parsing information in sysfs.
- * When a registered device matches a driver, it is then initialized with
- * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
- */
-
-extern struct rte_pci_bus rte_pci_bus;
-
-static int
-pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
-{
-	int count;
-	char path[PATH_MAX];
-	char *name;
-
-	if (!filename || !dri_name)
-		return -1;
-
-	count = readlink(filename, path, PATH_MAX);
-	if (count >= PATH_MAX)
-		return -1;
-
-	/* For device does not have a driver */
-	if (count < 0)
-		return 1;
-
-	path[count] = '\0';
-
-	name = strrchr(path, '/');
-	if (name) {
-		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
-		return 0;
-	}
-
-	return -1;
-}
-
-/* Map pci device */
-int
-rte_pci_map_device(struct rte_pci_device *dev)
-{
-	int ret = -1;
-
-	/* try mapping the NIC resources using VFIO if it exists */
-	switch (dev->kdrv) {
-	case RTE_KDRV_VFIO:
-#ifdef VFIO_PRESENT
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_map_resource(dev);
-#endif
-		break;
-	case RTE_KDRV_IGB_UIO:
-	case RTE_KDRV_UIO_GENERIC:
-		if (rte_eal_using_phys_addrs()) {
-			/* map resources for devices that use uio */
-			ret = pci_uio_map_resource(dev);
-		}
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		ret = 1;
-		break;
-	}
-
-	return ret;
-}
-
-/* Unmap pci device */
-void
-rte_pci_unmap_device(struct rte_pci_device *dev)
-{
-	/* try unmapping the NIC resources using VFIO if it exists */
-	switch (dev->kdrv) {
-	case RTE_KDRV_VFIO:
-#ifdef VFIO_PRESENT
-		if (pci_vfio_is_enabled())
-			pci_vfio_unmap_resource(dev);
-#endif
-		break;
-	case RTE_KDRV_IGB_UIO:
-	case RTE_KDRV_UIO_GENERIC:
-		/* unmap resources for devices that use uio */
-		pci_uio_unmap_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		break;
-	}
-}
-
-void *
-pci_find_max_end_va(void)
-{
-	const struct rte_memseg *seg = rte_eal_get_physmem_layout();
-	const struct rte_memseg *last = seg;
-	unsigned i = 0;
-
-	for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
-		if (seg->addr == NULL)
-			break;
-
-		if (seg->addr > last->addr)
-			last = seg;
-
-	}
-	return RTE_PTR_ADD(last->addr, last->len);
-}
-
-/* parse one line of the "resource" sysfs file (note that the 'line'
- * string is modified)
- */
-int
-pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
-	uint64_t *end_addr, uint64_t *flags)
-{
-	union pci_resource_info {
-		struct {
-			char *phys_addr;
-			char *end_addr;
-			char *flags;
-		};
-		char *ptrs[PCI_RESOURCE_FMT_NVAL];
-	} res_info;
-
-	if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
-		RTE_LOG(ERR, EAL,
-			"%s(): bad resource format\n", __func__);
-		return -1;
-	}
-	errno = 0;
-	*phys_addr = strtoull(res_info.phys_addr, NULL, 16);
-	*end_addr = strtoull(res_info.end_addr, NULL, 16);
-	*flags = strtoull(res_info.flags, NULL, 16);
-	if (errno != 0) {
-		RTE_LOG(ERR, EAL,
-			"%s(): bad resource format\n", __func__);
-		return -1;
-	}
-
-	return 0;
-}
-
-/* parse the "resource" sysfs file */
-static int
-pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
-{
-	FILE *f;
-	char buf[BUFSIZ];
-	int i;
-	uint64_t phys_addr, end_addr, flags;
-
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
-		return -1;
-	}
-
-	for (i = 0; i<PCI_MAX_RESOURCE; i++) {
-
-		if (fgets(buf, sizeof(buf), f) == NULL) {
-			RTE_LOG(ERR, EAL,
-				"%s(): cannot read resource\n", __func__);
-			goto error;
-		}
-		if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
-				&end_addr, &flags) < 0)
-			goto error;
-
-		if (flags & IORESOURCE_MEM) {
-			dev->mem_resource[i].phys_addr = phys_addr;
-			dev->mem_resource[i].len = end_addr - phys_addr + 1;
-			/* not mapped for now */
-			dev->mem_resource[i].addr = NULL;
-		}
-	}
-	fclose(f);
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
-}
-
-/* Scan one pci sysfs entry, and fill the devices list from it. */
-static int
-pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
-{
-	char filename[PATH_MAX];
-	unsigned long tmp;
-	struct rte_pci_device *dev;
-	char driver[PATH_MAX];
-	int ret;
-
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL)
-		return -1;
-
-	memset(dev, 0, sizeof(*dev));
-	dev->addr = *addr;
-
-	/* get vendor id */
-	snprintf(filename, sizeof(filename), "%s/vendor", dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.vendor_id = (uint16_t)tmp;
-
-	/* get device id */
-	snprintf(filename, sizeof(filename), "%s/device", dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.device_id = (uint16_t)tmp;
-
-	/* get subsystem_vendor id */
-	snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.subsystem_vendor_id = (uint16_t)tmp;
-
-	/* get subsystem_device id */
-	snprintf(filename, sizeof(filename), "%s/subsystem_device",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.subsystem_device_id = (uint16_t)tmp;
-
-	/* get class_id */
-	snprintf(filename, sizeof(filename), "%s/class",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	/* the least 24 bits are valid: class, subclass, program interface */
-	dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
-
-	/* get max_vfs */
-	dev->max_vfs = 0;
-	snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
-	if (!access(filename, F_OK) &&
-	    eal_parse_sysfs_value(filename, &tmp) == 0)
-		dev->max_vfs = (uint16_t)tmp;
-	else {
-		/* for non igb_uio driver, need kernel version >= 3.8 */
-		snprintf(filename, sizeof(filename),
-			 "%s/sriov_numvfs", dirname);
-		if (!access(filename, F_OK) &&
-		    eal_parse_sysfs_value(filename, &tmp) == 0)
-			dev->max_vfs = (uint16_t)tmp;
-	}
-
-	/* get numa node, default to 0 if not present */
-	snprintf(filename, sizeof(filename), "%s/numa_node",
-		 dirname);
-
-	if (access(filename, F_OK) != -1) {
-		if (eal_parse_sysfs_value(filename, &tmp) == 0)
-			dev->device.numa_node = tmp;
-		else
-			dev->device.numa_node = -1;
-	} else {
-		dev->device.numa_node = 0;
-	}
-
-	pci_name_set(dev);
-
-	/* parse resources */
-	snprintf(filename, sizeof(filename), "%s/resource", dirname);
-	if (pci_parse_sysfs_resource(filename, dev) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
-		free(dev);
-		return -1;
-	}
-
-	/* parse driver */
-	snprintf(filename, sizeof(filename), "%s/driver", dirname);
-	ret = pci_get_kernel_driver_by_path(filename, driver);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
-		free(dev);
-		return -1;
-	}
-
-	if (!ret) {
-		if (!strcmp(driver, "vfio-pci"))
-			dev->kdrv = RTE_KDRV_VFIO;
-		else if (!strcmp(driver, "igb_uio"))
-			dev->kdrv = RTE_KDRV_IGB_UIO;
-		else if (!strcmp(driver, "uio_pci_generic"))
-			dev->kdrv = RTE_KDRV_UIO_GENERIC;
-		else
-			dev->kdrv = RTE_KDRV_UNKNOWN;
-	} else
-		dev->kdrv = RTE_KDRV_NONE;
-
-	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-		rte_pci_add_device(dev);
-	} else {
-		struct rte_pci_device *dev2;
-		int ret;
-
-		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
-			if (ret > 0)
-				continue;
-
-			if (ret < 0) {
-				rte_pci_insert_device(dev2, dev);
-			} else { /* already registered */
-				dev2->kdrv = dev->kdrv;
-				dev2->max_vfs = dev->max_vfs;
-				pci_name_set(dev2);
-				memmove(dev2->mem_resource, dev->mem_resource,
-					sizeof(dev->mem_resource));
-				free(dev);
-			}
-			return 0;
-		}
-
-		rte_pci_add_device(dev);
-	}
-
-	return 0;
-}
-
-int
-pci_update_device(const struct rte_pci_addr *addr)
-{
-	char filename[PATH_MAX];
-
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
-		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
-		 addr->function);
-
-	return pci_scan_one(filename, addr);
-}
-
-/*
- * split up a pci address into its constituent parts.
- */
-static int
-parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
-{
-	/* first split on ':' */
-	union splitaddr {
-		struct {
-			char *domain;
-			char *bus;
-			char *devid;
-			char *function;
-		};
-		char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
-	} splitaddr;
-
-	char *buf_copy = strndup(buf, bufsize);
-	if (buf_copy == NULL)
-		return -1;
-
-	if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
-			!= PCI_FMT_NVAL - 1)
-		goto error;
-	/* final split is on '.' between devid and function */
-	splitaddr.function = strchr(splitaddr.devid,'.');
-	if (splitaddr.function == NULL)
-		goto error;
-	*splitaddr.function++ = '\0';
-
-	/* now convert to int values */
-	errno = 0;
-	addr->domain = strtoul(splitaddr.domain, NULL, 16);
-	addr->bus = strtoul(splitaddr.bus, NULL, 16);
-	addr->devid = strtoul(splitaddr.devid, NULL, 16);
-	addr->function = strtoul(splitaddr.function, NULL, 10);
-	if (errno != 0)
-		goto error;
-
-	free(buf_copy); /* free the copy made with strdup */
-	return 0;
-error:
-	free(buf_copy);
-	return -1;
-}
-
-/*
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- */
-int
-rte_pci_scan(void)
-{
-	struct dirent *e;
-	DIR *dir;
-	char dirname[PATH_MAX];
-	struct rte_pci_addr addr;
-
-	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
-		return 0;
-
-	dir = opendir(pci_get_sysfs_path());
-	if (dir == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
-			__func__, strerror(errno));
-		return -1;
-	}
-
-	while ((e = readdir(dir)) != NULL) {
-		if (e->d_name[0] == '.')
-			continue;
-
-		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
-			continue;
-
-		snprintf(dirname, sizeof(dirname), "%s/%s",
-				pci_get_sysfs_path(), e->d_name);
-
-		if (pci_scan_one(dirname, &addr) < 0)
-			goto error;
-	}
-	closedir(dir);
-	return 0;
-
-error:
-	closedir(dir);
-	return -1;
-}
-
-/*
- * Is pci device bound to any kdrv
- */
-static inline int
-pci_one_device_is_bound(void)
-{
-	struct rte_pci_device *dev = NULL;
-	int ret = 0;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (dev->kdrv == RTE_KDRV_UNKNOWN ||
-		    dev->kdrv == RTE_KDRV_NONE) {
-			continue;
-		} else {
-			ret = 1;
-			break;
-		}
-	}
-	return ret;
-}
-
-/*
- * Any one of the device bound to uio
- */
-static inline int
-pci_one_device_bound_uio(void)
-{
-	struct rte_pci_device *dev = NULL;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (dev->kdrv == RTE_KDRV_IGB_UIO ||
-		   dev->kdrv == RTE_KDRV_UIO_GENERIC) {
-			return 1;
-		}
-	}
-	return 0;
-}
-
-/*
- * Any one of the device has iova as va
- */
-static inline int
-pci_one_device_has_iova_va(void)
-{
-	struct rte_pci_device *dev = NULL;
-	struct rte_pci_driver *drv = NULL;
-
-	FOREACH_DRIVER_ON_PCIBUS(drv) {
-		if (drv && drv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) {
-			FOREACH_DEVICE_ON_PCIBUS(dev) {
-				if (dev->kdrv == RTE_KDRV_VFIO &&
-				    rte_pci_match(drv, dev))
-					return 1;
-			}
-		}
-	}
-	return 0;
-}
-
-/*
- * Get iommu class of PCI devices on the bus.
- */
-enum rte_iova_mode
-rte_pci_get_iommu_class(void)
-{
-	bool is_bound;
-	bool is_vfio_noiommu_enabled = true;
-	bool has_iova_va;
-	bool is_bound_uio;
-
-	is_bound = pci_one_device_is_bound();
-	if (!is_bound)
-		return RTE_IOVA_DC;
-
-	has_iova_va = pci_one_device_has_iova_va();
-	is_bound_uio = pci_one_device_bound_uio();
-#ifdef VFIO_PRESENT
-	is_vfio_noiommu_enabled = vfio_noiommu_is_enabled() == true ?
-					true : false;
-#endif
-
-	if (has_iova_va && !is_bound_uio && !is_vfio_noiommu_enabled)
-		return RTE_IOVA_VA;
-
-	if (has_iova_va) {
-		RTE_LOG(WARNING, EAL, "Some devices want iova as va but pa will be used because.. ");
-		if (is_vfio_noiommu_enabled)
-			RTE_LOG(WARNING, EAL, "vfio-noiommu mode configured\n");
-		if (is_bound_uio)
-			RTE_LOG(WARNING, EAL, "few device bound to UIO\n");
-	}
-
-	return RTE_IOVA_PA;
-}
-
-/* Read PCI config space. */
-int rte_pci_read_config(const struct rte_pci_device *device,
-		void *buf, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &device->intr_handle;
-
-	switch (intr_handle->type) {
-	case RTE_INTR_HANDLE_UIO:
-	case RTE_INTR_HANDLE_UIO_INTX:
-		return pci_uio_read_config(intr_handle, buf, len, offset);
-
-#ifdef VFIO_PRESENT
-	case RTE_INTR_HANDLE_VFIO_MSIX:
-	case RTE_INTR_HANDLE_VFIO_MSI:
-	case RTE_INTR_HANDLE_VFIO_LEGACY:
-		return pci_vfio_read_config(intr_handle, buf, len, offset);
-#endif
-	default:
-		RTE_LOG(ERR, EAL,
-			"Unknown handle type of fd %d\n",
-					intr_handle->fd);
-		return -1;
-	}
-}
-
-/* Write PCI config space. */
-int rte_pci_write_config(const struct rte_pci_device *device,
-		const void *buf, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &device->intr_handle;
-
-	switch (intr_handle->type) {
-	case RTE_INTR_HANDLE_UIO:
-	case RTE_INTR_HANDLE_UIO_INTX:
-		return pci_uio_write_config(intr_handle, buf, len, offset);
-
-#ifdef VFIO_PRESENT
-	case RTE_INTR_HANDLE_VFIO_MSIX:
-	case RTE_INTR_HANDLE_VFIO_MSI:
-	case RTE_INTR_HANDLE_VFIO_LEGACY:
-		return pci_vfio_write_config(intr_handle, buf, len, offset);
-#endif
-	default:
-		RTE_LOG(ERR, EAL,
-			"Unknown handle type of fd %d\n",
-					intr_handle->fd);
-		return -1;
-	}
-}
-
-#if defined(RTE_ARCH_X86)
-static int
-pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
-		struct rte_pci_ioport *p)
-{
-	uint16_t start, end;
-	FILE *fp;
-	char *line = NULL;
-	char pci_id[16];
-	int found = 0;
-	size_t linesz;
-
-	snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
-		 dev->addr.domain, dev->addr.bus,
-		 dev->addr.devid, dev->addr.function);
-
-	fp = fopen("/proc/ioports", "r");
-	if (fp == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);
-		return -1;
-	}
-
-	while (getdelim(&line, &linesz, '\n', fp) > 0) {
-		char *ptr = line;
-		char *left;
-		int n;
-
-		n = strcspn(ptr, ":");
-		ptr[n] = 0;
-		left = &ptr[n + 1];
-
-		while (*left && isspace(*left))
-			left++;
-
-		if (!strncmp(left, pci_id, strlen(pci_id))) {
-			found = 1;
-
-			while (*ptr && isspace(*ptr))
-				ptr++;
-
-			sscanf(ptr, "%04hx-%04hx", &start, &end);
-
-			break;
-		}
-	}
-
-	free(line);
-	fclose(fp);
-
-	if (!found)
-		return -1;
-
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	p->base = start;
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
-
-	return 0;
-}
-#endif
-
-int
-rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p)
-{
-	int ret = -1;
-
-	switch (dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_ioport_map(dev, bar, p);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		ret = pci_uio_ioport_map(dev, bar, p);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-#if defined(RTE_ARCH_X86)
-		ret = pci_ioport_map(dev, bar, p);
-#else
-		ret = pci_uio_ioport_map(dev, bar, p);
-#endif
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		ret = pci_ioport_map(dev, bar, p);
-#endif
-		break;
-	default:
-		break;
-	}
-
-	if (!ret)
-		p->dev = dev;
-
-	return ret;
-}
-
-void
-rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		pci_vfio_ioport_read(p, data, len, offset);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		pci_uio_ioport_read(p, data, len, offset);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-void
-rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		pci_vfio_ioport_write(p, data, len, offset);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		pci_uio_ioport_write(p, data, len, offset);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-int
-rte_pci_ioport_unmap(struct rte_pci_ioport *p)
-{
-	int ret = -1;
-
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_ioport_unmap(p);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		ret = pci_uio_ioport_unmap(p);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-#if defined(RTE_ARCH_X86)
-		ret = 0;
-#else
-		ret = pci_uio_ioport_unmap(p);
-#endif
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		ret = 0;
-#endif
-		break;
-	default:
-		break;
-	}
-
-	return ret;
-}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
deleted file mode 100644
index ae2980d..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_init.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef EAL_PCI_INIT_H_
-#define EAL_PCI_INIT_H_
-
-#include "eal_vfio.h"
-
-/** IO resource type: */
-#define IORESOURCE_IO         0x00000100
-#define IORESOURCE_MEM        0x00000200
-
-/*
- * Helper function to map PCI resources right after hugepages in virtual memory
- */
-extern void *pci_map_addr;
-void *pci_find_max_end_va(void);
-
-/* parse one line of the "resource" sysfs file (note that the 'line'
- * string is modified)
- */
-int pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
-	uint64_t *end_addr, uint64_t *flags);
-
-int pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res);
-void pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res);
-int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx);
-
-int pci_uio_read_config(const struct rte_intr_handle *intr_handle,
-			void *buf, size_t len, off_t offs);
-int pci_uio_write_config(const struct rte_intr_handle *intr_handle,
-			 const void *buf, size_t len, off_t offs);
-
-int pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		       struct rte_pci_ioport *p);
-void pci_uio_ioport_read(struct rte_pci_ioport *p,
-			 void *data, size_t len, off_t offset);
-void pci_uio_ioport_write(struct rte_pci_ioport *p,
-			  const void *data, size_t len, off_t offset);
-int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
-
-#ifdef VFIO_PRESENT
-
-/* access config space */
-int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
-			 void *buf, size_t len, off_t offs);
-int pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
-			  const void *buf, size_t len, off_t offs);
-
-int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
-		        struct rte_pci_ioport *p);
-void pci_vfio_ioport_read(struct rte_pci_ioport *p,
-			  void *data, size_t len, off_t offset);
-void pci_vfio_ioport_write(struct rte_pci_ioport *p,
-			   const void *data, size_t len, off_t offset);
-int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
-
-/* map/unmap VFIO resource prototype */
-int pci_vfio_map_resource(struct rte_pci_device *dev);
-int pci_vfio_unmap_resource(struct rte_pci_device *dev);
-
-#endif
-
-#endif /* EAL_PCI_INIT_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
deleted file mode 100644
index b639ab9..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/sysmacros.h>
-#include <linux/pci_regs.h>
-
-#if defined(RTE_ARCH_X86)
-#include <sys/io.h>
-#endif
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-
-void *pci_map_addr = NULL;
-
-#define OFF_MAX              ((uint64_t)(off_t)-1)
-
-int
-pci_uio_read_config(const struct rte_intr_handle *intr_handle,
-		    void *buf, size_t len, off_t offset)
-{
-	return pread(intr_handle->uio_cfg_fd, buf, len, offset);
-}
-
-int
-pci_uio_write_config(const struct rte_intr_handle *intr_handle,
-		     const void *buf, size_t len, off_t offset)
-{
-	return pwrite(intr_handle->uio_cfg_fd, buf, len, offset);
-}
-
-static int
-pci_uio_set_bus_master(int dev_fd)
-{
-	uint16_t reg;
-	int ret;
-
-	ret = pread(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL,
-			"Cannot read command from PCI config space!\n");
-		return -1;
-	}
-
-	/* return if bus mastering is already on */
-	if (reg & PCI_COMMAND_MASTER)
-		return 0;
-
-	reg |= PCI_COMMAND_MASTER;
-
-	ret = pwrite(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL,
-			"Cannot write command to PCI config space!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-static int
-pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
-{
-	FILE *f;
-	char filename[PATH_MAX];
-	int ret;
-	unsigned major, minor;
-	dev_t dev;
-
-	/* get the name of the sysfs file that contains the major and minor
-	 * of the uio device and read its content */
-	snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path);
-
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n",
-			__func__);
-		return -1;
-	}
-
-	ret = fscanf(f, "%u:%u", &major, &minor);
-	if (ret != 2) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n",
-			__func__);
-		fclose(f);
-		return -1;
-	}
-	fclose(f);
-
-	/* create the char device "mknod /dev/uioX c major minor" */
-	snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
-	dev = makedev(major, minor);
-	ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
-	if (ret != 0) {
-		RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
-			__func__, strerror(errno));
-		return -1;
-	}
-
-	return ret;
-}
-
-/*
- * Return the uioX char device used for a pci device. On success, return
- * the UIO number and fill dstbuf string with the path of the device in
- * sysfs. On error, return a negative value. In this case dstbuf is
- * invalid.
- */
-static int
-pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
-			   unsigned int buflen, int create)
-{
-	struct rte_pci_addr *loc = &dev->addr;
-	int uio_num = -1;
-	struct dirent *e;
-	DIR *dir;
-	char dirname[PATH_MAX];
-
-	/* depending on kernel version, uio can be located in uio/uioX
-	 * or uio:uioX */
-
-	snprintf(dirname, sizeof(dirname),
-			"%s/" PCI_PRI_FMT "/uio", pci_get_sysfs_path(),
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	dir = opendir(dirname);
-	if (dir == NULL) {
-		/* retry with the parent directory */
-		snprintf(dirname, sizeof(dirname),
-				"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
-				loc->domain, loc->bus, loc->devid, loc->function);
-		dir = opendir(dirname);
-
-		if (dir == NULL) {
-			RTE_LOG(ERR, EAL, "Cannot opendir %s\n", dirname);
-			return -1;
-		}
-	}
-
-	/* take the first file starting with "uio" */
-	while ((e = readdir(dir)) != NULL) {
-		/* format could be uio%d ...*/
-		int shortprefix_len = sizeof("uio") - 1;
-		/* ... or uio:uio%d */
-		int longprefix_len = sizeof("uio:uio") - 1;
-		char *endptr;
-
-		if (strncmp(e->d_name, "uio", 3) != 0)
-			continue;
-
-		/* first try uio%d */
-		errno = 0;
-		uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
-		if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
-			snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
-			break;
-		}
-
-		/* then try uio:uio%d */
-		errno = 0;
-		uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
-		if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
-			snprintf(dstbuf, buflen, "%s/uio:uio%u", dirname, uio_num);
-			break;
-		}
-	}
-	closedir(dir);
-
-	/* No uio resource found */
-	if (e == NULL)
-		return -1;
-
-	/* create uio device if we've been asked to */
-	if (internal_config.create_uio_dev && create &&
-			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
-		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
-
-	return uio_num;
-}
-
-void
-pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res)
-{
-	rte_free(uio_res);
-
-	if (dev->intr_handle.uio_cfg_fd >= 0) {
-		close(dev->intr_handle.uio_cfg_fd);
-		dev->intr_handle.uio_cfg_fd = -1;
-	}
-	if (dev->intr_handle.fd >= 0) {
-		close(dev->intr_handle.fd);
-		dev->intr_handle.fd = -1;
-		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	}
-}
-
-int
-pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res)
-{
-	char dirname[PATH_MAX];
-	char cfgname[PATH_MAX];
-	char devname[PATH_MAX]; /* contains the /dev/uioX */
-	int uio_num;
-	struct rte_pci_addr *loc;
-
-	loc = &dev->addr;
-
-	/* find uio resource */
-	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 1);
-	if (uio_num < 0) {
-		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
-				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
-		return 1;
-	}
-	snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
-
-	/* save fd if in primary process */
-	dev->intr_handle.fd = open(devname, O_RDWR);
-	if (dev->intr_handle.fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			devname, strerror(errno));
-		goto error;
-	}
-
-	snprintf(cfgname, sizeof(cfgname),
-			"/sys/class/uio/uio%u/device/config", uio_num);
-	dev->intr_handle.uio_cfg_fd = open(cfgname, O_RDWR);
-	if (dev->intr_handle.uio_cfg_fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			cfgname, strerror(errno));
-		goto error;
-	}
-
-	if (dev->kdrv == RTE_KDRV_IGB_UIO)
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-	else {
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
-
-		/* set bus master that is not done by uio_pci_generic */
-		if (pci_uio_set_bus_master(dev->intr_handle.uio_cfg_fd)) {
-			RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
-			goto error;
-		}
-	}
-
-	/* allocate the mapping details for secondary processes*/
-	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
-	if (*uio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto error;
-	}
-
-	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
-	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
-
-	return 0;
-
-error:
-	pci_uio_free_resource(dev, *uio_res);
-	return -1;
-}
-
-int
-pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx)
-{
-	int fd;
-	char devname[PATH_MAX];
-	void *mapaddr;
-	struct rte_pci_addr *loc;
-	struct pci_map *maps;
-
-	loc = &dev->addr;
-	maps = uio_res->maps;
-
-	/* update devname for mmap  */
-	snprintf(devname, sizeof(devname),
-			"%s/" PCI_PRI_FMT "/resource%d",
-			pci_get_sysfs_path(),
-			loc->domain, loc->bus, loc->devid,
-			loc->function, res_idx);
-
-	/* allocate memory to keep path */
-	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
-	if (maps[map_idx].path == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
-				strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * open resource file, to mmap it
-	 */
-	fd = open(devname, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				devname, strerror(errno));
-		goto error;
-	}
-
-	/* try mapping somewhere close to the end of hugepages */
-	if (pci_map_addr == NULL)
-		pci_map_addr = pci_find_max_end_va();
-
-	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
-			(size_t)dev->mem_resource[res_idx].len, 0);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		goto error;
-
-	pci_map_addr = RTE_PTR_ADD(mapaddr,
-			(size_t)dev->mem_resource[res_idx].len);
-
-	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
-	maps[map_idx].size = dev->mem_resource[res_idx].len;
-	maps[map_idx].addr = mapaddr;
-	maps[map_idx].offset = 0;
-	strcpy(maps[map_idx].path, devname);
-	dev->mem_resource[res_idx].addr = mapaddr;
-
-	return 0;
-
-error:
-	rte_free(maps[map_idx].path);
-	return -1;
-}
-
-#if defined(RTE_ARCH_X86)
-int
-pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		   struct rte_pci_ioport *p)
-{
-	char dirname[PATH_MAX];
-	char filename[PATH_MAX];
-	int uio_num;
-	unsigned long start;
-
-	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 0);
-	if (uio_num < 0)
-		return -1;
-
-	/* get portio start */
-	snprintf(filename, sizeof(filename),
-		 "%s/portio/port%d/start", dirname, bar);
-	if (eal_parse_sysfs_value(filename, &start) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
-			__func__);
-		return -1;
-	}
-	/* ensure we don't get anything funny here, read/write will cast to
-	 * uin16_t */
-	if (start > UINT16_MAX)
-		return -1;
-
-	/* FIXME only for primary process ? */
-	if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {
-
-		snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
-		dev->intr_handle.fd = open(filename, O_RDWR);
-		if (dev->intr_handle.fd < 0) {
-			RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				filename, strerror(errno));
-			return -1;
-		}
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-	}
-
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);
-
-	p->base = start;
-	p->len = 0;
-	return 0;
-}
-#else
-int
-pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		   struct rte_pci_ioport *p)
-{
-	FILE *f;
-	char buf[BUFSIZ];
-	char filename[PATH_MAX];
-	uint64_t phys_addr, end_addr, flags;
-	int fd, i;
-	void *addr;
-
-	/* open and read addresses of the corresponding resource in sysfs */
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
-		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
-		dev->addr.devid, dev->addr.function);
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",
-			strerror(errno));
-		return -1;
-	}
-	for (i = 0; i < bar + 1; i++) {
-		if (fgets(buf, sizeof(buf), f) == NULL) {
-			RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");
-			goto error;
-		}
-	}
-	if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
-			&end_addr, &flags) < 0)
-		goto error;
-	if ((flags & IORESOURCE_IO) == 0) {
-		RTE_LOG(ERR, EAL, "BAR %d is not an IO resource\n", bar);
-		goto error;
-	}
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
-		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
-		dev->addr.devid, dev->addr.function, bar);
-
-	/* mmap the pci resource */
-	fd = open(filename, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
-			strerror(errno));
-		goto error;
-	}
-	addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
-		MAP_SHARED, fd, 0);
-	close(fd);
-	if (addr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s\n",
-			strerror(errno));
-		goto error;
-	}
-
-	/* strangely, the base address is mmap addr + phys_addr */
-	p->base = (uintptr_t)addr + phys_addr;
-	p->len = end_addr + 1;
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"\n", p->base);
-	fclose(f);
-
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
-}
-#endif
-
-void
-pci_uio_ioport_read(struct rte_pci_ioport *p,
-		    void *data, size_t len, off_t offset)
-{
-	uint8_t *d;
-	int size;
-	uintptr_t reg = p->base + offset;
-
-	for (d = data; len > 0; d += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-#if defined(RTE_ARCH_X86)
-			*(uint32_t *)d = inl(reg);
-#else
-			*(uint32_t *)d = *(volatile uint32_t *)reg;
-#endif
-		} else if (len >= 2) {
-			size = 2;
-#if defined(RTE_ARCH_X86)
-			*(uint16_t *)d = inw(reg);
-#else
-			*(uint16_t *)d = *(volatile uint16_t *)reg;
-#endif
-		} else {
-			size = 1;
-#if defined(RTE_ARCH_X86)
-			*d = inb(reg);
-#else
-			*d = *(volatile uint8_t *)reg;
-#endif
-		}
-	}
-}
-
-void
-pci_uio_ioport_write(struct rte_pci_ioport *p,
-		     const void *data, size_t len, off_t offset)
-{
-	const uint8_t *s;
-	int size;
-	uintptr_t reg = p->base + offset;
-
-	for (s = data; len > 0; s += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-#if defined(RTE_ARCH_X86)
-			outl_p(*(const uint32_t *)s, reg);
-#else
-			*(volatile uint32_t *)reg = *(const uint32_t *)s;
-#endif
-		} else if (len >= 2) {
-			size = 2;
-#if defined(RTE_ARCH_X86)
-			outw_p(*(const uint16_t *)s, reg);
-#else
-			*(volatile uint16_t *)reg = *(const uint16_t *)s;
-#endif
-		} else {
-			size = 1;
-#if defined(RTE_ARCH_X86)
-			outb_p(*s, reg);
-#else
-			*(volatile uint8_t *)reg = *s;
-#endif
-		}
-	}
-}
-
-int
-pci_uio_ioport_unmap(struct rte_pci_ioport *p)
-{
-#if defined(RTE_ARCH_X86)
-	RTE_SET_USED(p);
-	/* FIXME close intr fd ? */
-	return 0;
-#else
-	return munmap((void *)(uintptr_t)p->base, p->len);
-#endif
-}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
deleted file mode 100644
index 10a75da..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ /dev/null
@@ -1,756 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <fcntl.h>
-#include <linux/pci_regs.h>
-#include <sys/eventfd.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <stdbool.h>
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-#include "eal_vfio.h"
-#include "eal_private.h"
-
-/**
- * @file
- * PCI probing under linux (VFIO version)
- *
- * This code tries to determine if the PCI device is bound to VFIO driver,
- * and initialize it (map BARs, set up interrupts) if that's the case.
- *
- * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
- */
-
-#ifdef VFIO_PRESENT
-
-#define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
-#define PAGE_MASK   (~(PAGE_SIZE - 1))
-
-static struct rte_tailq_elem rte_vfio_tailq = {
-	.name = "VFIO_RESOURCE_LIST",
-};
-EAL_REGISTER_TAILQ(rte_vfio_tailq)
-
-int
-pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
-		    void *buf, size_t len, off_t offs)
-{
-	return pread64(intr_handle->vfio_dev_fd, buf, len,
-	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
-}
-
-int
-pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
-		    const void *buf, size_t len, off_t offs)
-{
-	return pwrite64(intr_handle->vfio_dev_fd, buf, len,
-	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
-}
-
-/* get PCI BAR number where MSI-X interrupts are */
-static int
-pci_vfio_get_msix_bar(int fd, struct pci_msix_table *msix_table)
-{
-	int ret;
-	uint32_t reg;
-	uint16_t flags;
-	uint8_t cap_id, cap_offset;
-
-	/* read PCI capability pointer from config space */
-	ret = pread64(fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_CAPABILITY_LIST);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
-				"config space!\n");
-		return -1;
-	}
-
-	/* we need first byte */
-	cap_offset = reg & 0xFF;
-
-	while (cap_offset) {
-
-		/* read PCI capability ID */
-		ret = pread64(fd, &reg, sizeof(reg),
-				VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-				cap_offset);
-		if (ret != sizeof(reg)) {
-			RTE_LOG(ERR, EAL, "Cannot read capability ID from PCI "
-					"config space!\n");
-			return -1;
-		}
-
-		/* we need first byte */
-		cap_id = reg & 0xFF;
-
-		/* if we haven't reached MSI-X, check next capability */
-		if (cap_id != PCI_CAP_ID_MSIX) {
-			ret = pread64(fd, &reg, sizeof(reg),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset);
-			if (ret != sizeof(reg)) {
-				RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
-						"config space!\n");
-				return -1;
-			}
-
-			/* we need second byte */
-			cap_offset = (reg & 0xFF00) >> 8;
-
-			continue;
-		}
-		/* else, read table offset */
-		else {
-			/* table offset resides in the next 4 bytes */
-			ret = pread64(fd, &reg, sizeof(reg),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset + 4);
-			if (ret != sizeof(reg)) {
-				RTE_LOG(ERR, EAL, "Cannot read table offset from PCI config "
-						"space!\n");
-				return -1;
-			}
-
-			ret = pread64(fd, &flags, sizeof(flags),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset + 2);
-			if (ret != sizeof(flags)) {
-				RTE_LOG(ERR, EAL, "Cannot read table flags from PCI config "
-						"space!\n");
-				return -1;
-			}
-
-			msix_table->bar_index = reg & RTE_PCI_MSIX_TABLE_BIR;
-			msix_table->offset = reg & RTE_PCI_MSIX_TABLE_OFFSET;
-			msix_table->size =
-				16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE));
-
-			return 0;
-		}
-	}
-	return 0;
-}
-
-/* set PCI bus mastering */
-static int
-pci_vfio_set_bus_master(int dev_fd, bool op)
-{
-	uint16_t reg;
-	int ret;
-
-	ret = pread64(dev_fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n");
-		return -1;
-	}
-
-	if (op)
-		/* set the master bit */
-		reg |= PCI_COMMAND_MASTER;
-	else
-		reg &= ~(PCI_COMMAND_MASTER);
-
-	ret = pwrite64(dev_fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_COMMAND);
-
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-/* set up interrupt support (but not enable interrupts) */
-static int
-pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
-{
-	int i, ret, intr_idx;
-
-	/* default to invalid index */
-	intr_idx = VFIO_PCI_NUM_IRQS;
-
-	/* get interrupt type from internal config (MSI-X by default, can be
-	 * overridden from the command line
-	 */
-	switch (internal_config.vfio_intr_mode) {
-	case RTE_INTR_MODE_MSIX:
-		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
-		break;
-	case RTE_INTR_MODE_MSI:
-		intr_idx = VFIO_PCI_MSI_IRQ_INDEX;
-		break;
-	case RTE_INTR_MODE_LEGACY:
-		intr_idx = VFIO_PCI_INTX_IRQ_INDEX;
-		break;
-	/* don't do anything if we want to automatically determine interrupt type */
-	case RTE_INTR_MODE_NONE:
-		break;
-	default:
-		RTE_LOG(ERR, EAL, "  unknown default interrupt type!\n");
-		return -1;
-	}
-
-	/* start from MSI-X interrupt type */
-	for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) {
-		struct vfio_irq_info irq = { .argsz = sizeof(irq) };
-		int fd = -1;
-
-		/* skip interrupt modes we don't want */
-		if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE &&
-				i != intr_idx)
-			continue;
-
-		irq.index = i;
-
-		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  cannot get IRQ info, "
-					"error %i (%s)\n", errno, strerror(errno));
-			return -1;
-		}
-
-		/* if this vector cannot be used with eventfd, fail if we explicitly
-		 * specified interrupt type, otherwise continue */
-		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
-			if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE) {
-				RTE_LOG(ERR, EAL,
-						"  interrupt vector does not support eventfd!\n");
-				return -1;
-			} else
-				continue;
-		}
-
-		/* set up an eventfd for interrupts */
-		fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
-		if (fd < 0) {
-			RTE_LOG(ERR, EAL, "  cannot set up eventfd, "
-					"error %i (%s)\n", errno, strerror(errno));
-			return -1;
-		}
-
-		dev->intr_handle.fd = fd;
-		dev->intr_handle.vfio_dev_fd = vfio_dev_fd;
-
-		switch (i) {
-		case VFIO_PCI_MSIX_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSIX;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
-			break;
-		case VFIO_PCI_MSI_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSI;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
-			break;
-		case VFIO_PCI_INTX_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_LEGACY;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
-			break;
-		default:
-			RTE_LOG(ERR, EAL, "  unknown interrupt type!\n");
-			return -1;
-		}
-
-		return 0;
-	}
-
-	/* if we're here, we haven't found a suitable interrupt vector */
-	return -1;
-}
-
-static int
-pci_vfio_is_ioport_bar(int vfio_dev_fd, int bar_index)
-{
-	uint32_t ioport_bar;
-	int ret;
-
-	ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar),
-			  VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX)
-			  + PCI_BASE_ADDRESS_0 + bar_index*4);
-	if (ret != sizeof(ioport_bar)) {
-		RTE_LOG(ERR, EAL, "Cannot read command (%x) from config space!\n",
-			PCI_BASE_ADDRESS_0 + bar_index*4);
-		return -1;
-	}
-
-	return (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) != 0;
-}
-
-static int
-pci_vfio_setup_device(struct rte_pci_device *dev, int vfio_dev_fd)
-{
-	if (pci_vfio_setup_interrupts(dev, vfio_dev_fd) != 0) {
-		RTE_LOG(ERR, EAL, "Error setting up interrupts!\n");
-		return -1;
-	}
-
-	/* set bus mastering for the device */
-	if (pci_vfio_set_bus_master(vfio_dev_fd, true)) {
-		RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
-		return -1;
-	}
-
-	/* Reset the device */
-	ioctl(vfio_dev_fd, VFIO_DEVICE_RESET);
-
-	return 0;
-}
-
-static int
-pci_vfio_mmap_bar(int vfio_dev_fd, struct mapped_pci_resource *vfio_res,
-		int bar_index, int additional_flags)
-{
-	struct memreg {
-		unsigned long offset, size;
-	} memreg[2] = {};
-	void *bar_addr;
-	struct pci_msix_table *msix_table = &vfio_res->msix_table;
-	struct pci_map *bar = &vfio_res->maps[bar_index];
-
-	if (bar->size == 0)
-		/* Skip this BAR */
-		return 0;
-
-	if (msix_table->bar_index == bar_index) {
-		/*
-		 * VFIO will not let us map the MSI-X table,
-		 * but we can map around it.
-		 */
-		uint32_t table_start = msix_table->offset;
-		uint32_t table_end = table_start + msix_table->size;
-		table_end = (table_end + ~PAGE_MASK) & PAGE_MASK;
-		table_start &= PAGE_MASK;
-
-		if (table_start == 0 && table_end >= bar->size) {
-			/* Cannot map this BAR */
-			RTE_LOG(DEBUG, EAL, "Skipping BAR%d\n", bar_index);
-			bar->size = 0;
-			bar->addr = 0;
-			return 0;
-		}
-
-		memreg[0].offset = bar->offset;
-		memreg[0].size = table_start;
-		memreg[1].offset = bar->offset + table_end;
-		memreg[1].size = bar->size - table_end;
-
-		RTE_LOG(DEBUG, EAL,
-			"Trying to map BAR%d that contains the MSI-X "
-			"table. Trying offsets: "
-			"0x%04lx:0x%04lx, 0x%04lx:0x%04lx\n", bar_index,
-			memreg[0].offset, memreg[0].size,
-			memreg[1].offset, memreg[1].size);
-	} else {
-		memreg[0].offset = bar->offset;
-		memreg[0].size = bar->size;
-	}
-
-	/* reserve the address using an inaccessible mapping */
-	bar_addr = mmap(bar->addr, bar->size, 0, MAP_PRIVATE |
-			MAP_ANONYMOUS | additional_flags, -1, 0);
-	if (bar_addr != MAP_FAILED) {
-		void *map_addr = NULL;
-		if (memreg[0].size) {
-			/* actual map of first part */
-			map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
-							memreg[0].offset,
-							memreg[0].size,
-							MAP_FIXED);
-		}
-
-		/* if there's a second part, try to map it */
-		if (map_addr != MAP_FAILED
-			&& memreg[1].offset && memreg[1].size) {
-			void *second_addr = RTE_PTR_ADD(bar_addr,
-							memreg[1].offset -
-							(uintptr_t)bar->offset);
-			map_addr = pci_map_resource(second_addr,
-							vfio_dev_fd,
-							memreg[1].offset,
-							memreg[1].size,
-							MAP_FIXED);
-		}
-
-		if (map_addr == MAP_FAILED || !map_addr) {
-			munmap(bar_addr, bar->size);
-			bar_addr = MAP_FAILED;
-			RTE_LOG(ERR, EAL, "Failed to map pci BAR%d\n",
-					bar_index);
-			return -1;
-		}
-	} else {
-		RTE_LOG(ERR, EAL,
-				"Failed to create inaccessible mapping for BAR%d\n",
-				bar_index);
-		return -1;
-	}
-
-	bar->addr = bar_addr;
-	return 0;
-}
-
-static int
-pci_vfio_map_resource_primary(struct rte_pci_device *dev)
-{
-	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
-	char pci_addr[PATH_MAX] = {0};
-	int vfio_dev_fd;
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list =
-		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-
-	struct pci_map *maps;
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
-					&vfio_dev_fd, &device_info);
-	if (ret)
-		return ret;
-
-	/* allocate vfio_res and get region info */
-	vfio_res = rte_zmalloc("VFIO_RES", sizeof(*vfio_res), 0);
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto err_vfio_dev_fd;
-	}
-	memcpy(&vfio_res->pci_addr, &dev->addr, sizeof(vfio_res->pci_addr));
-
-	/* get number of registers (up to BAR5) */
-	vfio_res->nb_maps = RTE_MIN((int) device_info.num_regions,
-			VFIO_PCI_BAR5_REGION_INDEX + 1);
-
-	/* map BARs */
-	maps = vfio_res->maps;
-
-	vfio_res->msix_table.bar_index = -1;
-	/* get MSI-X BAR, if any (we have to know where it is because we can't
-	 * easily mmap it when using VFIO)
-	 */
-	ret = pci_vfio_get_msix_bar(vfio_dev_fd, &vfio_res->msix_table);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "  %s cannot get MSI-X BAR number!\n",
-				pci_addr);
-		goto err_vfio_dev_fd;
-	}
-
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-		struct vfio_region_info reg = { .argsz = sizeof(reg) };
-		void *bar_addr;
-
-		reg.index = i;
-
-		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg);
-		if (ret) {
-			RTE_LOG(ERR, EAL, "  %s cannot get device region info "
-					"error %i (%s)\n", pci_addr, errno, strerror(errno));
-			goto err_vfio_res;
-		}
-
-		/* chk for io port region */
-		ret = pci_vfio_is_ioport_bar(vfio_dev_fd, i);
-		if (ret < 0)
-			goto err_vfio_res;
-		else if (ret) {
-			RTE_LOG(INFO, EAL, "Ignore mapping IO port bar(%d)\n",
-					i);
-			continue;
-		}
-
-		/* skip non-mmapable BARs */
-		if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0)
-			continue;
-
-		/* try mapping somewhere close to the end of hugepages */
-		if (pci_map_addr == NULL)
-			pci_map_addr = pci_find_max_end_va();
-
-		bar_addr = pci_map_addr;
-		pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
-
-		maps[i].addr = bar_addr;
-		maps[i].offset = reg.offset;
-		maps[i].size = reg.size;
-		maps[i].path = NULL; /* vfio doesn't have per-resource paths */
-
-		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, 0);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
-					pci_addr, i, strerror(errno));
-			goto err_vfio_res;
-		}
-
-		dev->mem_resource[i].addr = maps[i].addr;
-	}
-
-	if (pci_vfio_setup_device(dev, vfio_dev_fd) < 0) {
-		RTE_LOG(ERR, EAL, "  %s setup device failed\n", pci_addr);
-		goto err_vfio_res;
-	}
-
-	TAILQ_INSERT_TAIL(vfio_res_list, vfio_res, next);
-
-	return 0;
-err_vfio_res:
-	rte_free(vfio_res);
-err_vfio_dev_fd:
-	close(vfio_dev_fd);
-	return -1;
-}
-
-static int
-pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
-{
-	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
-	char pci_addr[PATH_MAX] = {0};
-	int vfio_dev_fd;
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list =
-		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-
-	struct pci_map *maps;
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
-					&vfio_dev_fd, &device_info);
-	if (ret)
-		return ret;
-
-	/* if we're in a secondary process, just find our tailq entry */
-	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-		if (rte_eal_compare_pci_addr(&vfio_res->pci_addr,
-						 &dev->addr))
-			continue;
-		break;
-	}
-	/* if we haven't found our tailq entry, something's wrong */
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
-				pci_addr);
-		goto err_vfio_dev_fd;
-	}
-
-	/* map BARs */
-	maps = vfio_res->maps;
-
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, MAP_FIXED);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
-					pci_addr, i, strerror(errno));
-			goto err_vfio_dev_fd;
-		}
-
-		dev->mem_resource[i].addr = maps[i].addr;
-	}
-
-	return 0;
-err_vfio_dev_fd:
-	close(vfio_dev_fd);
-	return -1;
-}
-
-/*
- * map the PCI resources of a PCI device in virtual memory (VFIO version).
- * primary and secondary processes follow almost exactly the same path
- */
-int
-pci_vfio_map_resource(struct rte_pci_device *dev)
-{
-	if (internal_config.process_type == RTE_PROC_PRIMARY)
-		return pci_vfio_map_resource_primary(dev);
-	else
-		return pci_vfio_map_resource_secondary(dev);
-}
-
-int
-pci_vfio_unmap_resource(struct rte_pci_device *dev)
-{
-	char pci_addr[PATH_MAX] = {0};
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list;
-
-	struct pci_map *maps;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-
-	if (close(dev->intr_handle.fd) < 0) {
-		RTE_LOG(INFO, EAL, "Error when closing eventfd file descriptor for %s\n",
-			pci_addr);
-		return -1;
-	}
-
-	if (pci_vfio_set_bus_master(dev->intr_handle.vfio_dev_fd, false)) {
-		RTE_LOG(ERR, EAL, "  %s cannot unset bus mastering for PCI device!\n",
-				pci_addr);
-		return -1;
-	}
-
-	ret = vfio_release_device(pci_get_sysfs_path(), pci_addr,
-				  dev->intr_handle.vfio_dev_fd);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot release device\n", __func__);
-		return ret;
-	}
-
-	vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-	/* Get vfio_res */
-	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-		if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
-			continue;
-		break;
-	}
-	/* if we haven't found our tailq entry, something's wrong */
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
-				pci_addr);
-		return -1;
-	}
-
-	/* unmap BARs */
-	maps = vfio_res->maps;
-
-	RTE_LOG(INFO, EAL, "Releasing pci mapped resource for %s\n",
-		pci_addr);
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-
-		/*
-		 * We do not need to be aware of MSI-X table BAR mappings as
-		 * when mapping. Just using current maps array is enough
-		 */
-		if (maps[i].addr) {
-			RTE_LOG(INFO, EAL, "Calling pci_unmap_resource for %s at %p\n",
-				pci_addr, maps[i].addr);
-			pci_unmap_resource(maps[i].addr, maps[i].size);
-		}
-	}
-
-	TAILQ_REMOVE(vfio_res_list, vfio_res, next);
-
-	return 0;
-}
-
-int
-pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
-		    struct rte_pci_ioport *p)
-{
-	if (bar < VFIO_PCI_BAR0_REGION_INDEX ||
-	    bar > VFIO_PCI_BAR5_REGION_INDEX) {
-		RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar);
-		return -1;
-	}
-
-	p->dev = dev;
-	p->base = VFIO_GET_REGION_ADDR(bar);
-	return 0;
-}
-
-void
-pci_vfio_ioport_read(struct rte_pci_ioport *p,
-		     void *data, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
-
-	if (pread64(intr_handle->vfio_dev_fd, data,
-		    len, p->base + offset) <= 0)
-		RTE_LOG(ERR, EAL,
-			"Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n",
-			VFIO_GET_REGION_IDX(p->base), (int)offset);
-}
-
-void
-pci_vfio_ioport_write(struct rte_pci_ioport *p,
-		      const void *data, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
-
-	if (pwrite64(intr_handle->vfio_dev_fd, data,
-		     len, p->base + offset) <= 0)
-		RTE_LOG(ERR, EAL,
-			"Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n",
-			VFIO_GET_REGION_IDX(p->base), (int)offset);
-}
-
-int
-pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
-{
-	RTE_SET_USED(p);
-	return -1;
-}
-
-int
-pci_vfio_enable(void)
-{
-	return vfio_enable("vfio_pci");
-}
-
-int
-pci_vfio_is_enabled(void)
-{
-	return vfio_is_enabled("vfio_pci");
-}
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
deleted file mode 100644
index 537beeb..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <pthread.h>
-
-/* sys/un.h with __USE_MISC uses strlen, which is unsafe */
-#ifdef __USE_MISC
-#define REMOVED_USE_MISC
-#undef __USE_MISC
-#endif
-#include <sys/un.h>
-/* make sure we redefine __USE_MISC only if it was previously undefined */
-#ifdef REMOVED_USE_MISC
-#define __USE_MISC
-#undef REMOVED_USE_MISC
-#endif
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-#include "eal_thread.h"
-
-/**
- * @file
- * VFIO socket for communication between primary and secondary processes.
- *
- * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
- */
-
-#ifdef VFIO_PRESENT
-
-#define SOCKET_PATH_FMT "%s/.%s_mp_socket"
-#define CMSGLEN (CMSG_LEN(sizeof(int)))
-#define FD_TO_CMSGHDR(fd, chdr) \
-		do {\
-			(chdr).cmsg_len = CMSGLEN;\
-			(chdr).cmsg_level = SOL_SOCKET;\
-			(chdr).cmsg_type = SCM_RIGHTS;\
-			memcpy((chdr).__cmsg_data, &(fd), sizeof(fd));\
-		} while (0)
-#define CMSGHDR_TO_FD(chdr, fd) \
-			memcpy(&(fd), (chdr).__cmsg_data, sizeof(fd))
-
-static pthread_t socket_thread;
-static int mp_socket_fd;
-
-
-/* get socket path (/var/run if root, $HOME otherwise) */
-static void
-get_socket_path(char *buffer, int bufsz)
-{
-	const char *dir = "/var/run";
-	const char *home_dir = getenv("HOME");
-
-	if (getuid() != 0 && home_dir != NULL)
-		dir = home_dir;
-
-	/* use current prefix as file path */
-	snprintf(buffer, bufsz, SOCKET_PATH_FMT, dir,
-			internal_config.hugefile_prefix);
-}
-
-
-
-/*
- * data flow for socket comm protocol:
- * 1. client sends SOCKET_REQ_CONTAINER or SOCKET_REQ_GROUP
- * 1a. in case of SOCKET_REQ_GROUP, client also then sends group number
- * 2. server receives message
- * 2a. in case of invalid group, SOCKET_ERR is sent back to client
- * 2b. in case of unbound group, SOCKET_NO_FD is sent back to client
- * 2c. in case of valid group, SOCKET_OK is sent and immediately followed by fd
- *
- * in case of any error, socket is closed.
- */
-
-/* send a request, return -1 on error */
-int
-vfio_mp_sync_send_request(int socket, int req)
-{
-	struct msghdr hdr;
-	struct iovec iov;
-	int buf;
-	int ret;
-
-	memset(&hdr, 0, sizeof(hdr));
-
-	buf = req;
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-
-	ret = sendmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-	return 0;
-}
-
-/* receive a request and return it */
-int
-vfio_mp_sync_receive_request(int socket)
-{
-	int buf;
-	struct msghdr hdr;
-	struct iovec iov;
-	int ret, req;
-
-	memset(&hdr, 0, sizeof(hdr));
-
-	buf = SOCKET_ERR;
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-
-	ret = recvmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-
-	req = buf;
-
-	return req;
-}
-
-/* send OK in message, fd in control message */
-int
-vfio_mp_sync_send_fd(int socket, int fd)
-{
-	int buf;
-	struct msghdr hdr;
-	struct cmsghdr *chdr;
-	char chdr_buf[CMSGLEN];
-	struct iovec iov;
-	int ret;
-
-	chdr = (struct cmsghdr *) chdr_buf;
-	memset(chdr, 0, sizeof(chdr_buf));
-	memset(&hdr, 0, sizeof(hdr));
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-	hdr.msg_control = chdr;
-	hdr.msg_controllen = CMSGLEN;
-
-	buf = SOCKET_OK;
-	FD_TO_CMSGHDR(fd, *chdr);
-
-	ret = sendmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-	return 0;
-}
-
-/* receive OK in message, fd in control message */
-int
-vfio_mp_sync_receive_fd(int socket)
-{
-	int buf;
-	struct msghdr hdr;
-	struct cmsghdr *chdr;
-	char chdr_buf[CMSGLEN];
-	struct iovec iov;
-	int ret, req, fd;
-
-	buf = SOCKET_ERR;
-
-	chdr = (struct cmsghdr *) chdr_buf;
-	memset(chdr, 0, sizeof(chdr_buf));
-	memset(&hdr, 0, sizeof(hdr));
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-	hdr.msg_control = chdr;
-	hdr.msg_controllen = CMSGLEN;
-
-	ret = recvmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-
-	req = buf;
-
-	if (req != SOCKET_OK)
-		return -1;
-
-	CMSGHDR_TO_FD(*chdr, fd);
-
-	return fd;
-}
-
-/* connect socket_fd in secondary process to the primary process's socket */
-int
-vfio_mp_sync_connect_to_primary(void)
-{
-	struct sockaddr_un addr;
-	socklen_t sockaddr_len;
-	int socket_fd;
-
-	/* set up a socket */
-	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-	if (socket_fd < 0) {
-		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
-		return -1;
-	}
-
-	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
-	addr.sun_family = AF_UNIX;
-
-	sockaddr_len = sizeof(struct sockaddr_un);
-
-	if (connect(socket_fd, (struct sockaddr *) &addr, sockaddr_len) == 0)
-		return socket_fd;
-
-	/* if connect failed */
-	close(socket_fd);
-	return -1;
-}
-
-
-
-/*
- * socket listening thread for primary process
- */
-static __attribute__((noreturn)) void *
-vfio_mp_sync_thread(void __rte_unused * arg)
-{
-	int ret, fd, vfio_data;
-
-	/* wait for requests on the socket */
-	for (;;) {
-		int conn_sock;
-		struct sockaddr_un addr;
-		socklen_t sockaddr_len = sizeof(addr);
-
-		/* this is a blocking call */
-		conn_sock = accept(mp_socket_fd, (struct sockaddr *) &addr,
-				&sockaddr_len);
-
-		/* just restart on error */
-		if (conn_sock == -1)
-			continue;
-
-		/* set socket to linger after close */
-		struct linger l;
-		l.l_onoff = 1;
-		l.l_linger = 60;
-
-		if (setsockopt(conn_sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0)
-			RTE_LOG(WARNING, EAL, "Cannot set SO_LINGER option "
-					"on listen socket (%s)\n", strerror(errno));
-
-		ret = vfio_mp_sync_receive_request(conn_sock);
-
-		switch (ret) {
-		case SOCKET_REQ_CONTAINER:
-			fd = vfio_get_container_fd();
-			if (fd < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			else
-				vfio_mp_sync_send_fd(conn_sock, fd);
-			if (fd >= 0)
-				close(fd);
-			break;
-		case SOCKET_REQ_GROUP:
-			/* wait for group number */
-			vfio_data = vfio_mp_sync_receive_request(conn_sock);
-			if (vfio_data < 0) {
-				close(conn_sock);
-				continue;
-			}
-
-			fd = vfio_get_group_fd(vfio_data);
-
-			if (fd < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			/* if VFIO group exists but isn't bound to VFIO driver */
-			else if (fd == 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
-			/* if group exists and is bound to VFIO driver */
-			else {
-				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
-				vfio_mp_sync_send_fd(conn_sock, fd);
-			}
-			break;
-		case SOCKET_CLR_GROUP:
-			/* wait for group fd */
-			vfio_data = vfio_mp_sync_receive_request(conn_sock);
-			if (vfio_data < 0) {
-				close(conn_sock);
-				continue;
-			}
-
-			ret = clear_group(vfio_data);
-
-			if (ret < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
-			else
-				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
-			break;
-		default:
-			vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			break;
-		}
-		close(conn_sock);
-	}
-}
-
-static int
-vfio_mp_sync_socket_setup(void)
-{
-	int ret, socket_fd;
-	struct sockaddr_un addr;
-	socklen_t sockaddr_len;
-
-	/* set up a socket */
-	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-	if (socket_fd < 0) {
-		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
-		return -1;
-	}
-
-	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
-	addr.sun_family = AF_UNIX;
-
-	sockaddr_len = sizeof(struct sockaddr_un);
-
-	unlink(addr.sun_path);
-
-	ret = bind(socket_fd, (struct sockaddr *) &addr, sockaddr_len);
-	if (ret) {
-		RTE_LOG(ERR, EAL, "Failed to bind socket: %s!\n", strerror(errno));
-		close(socket_fd);
-		return -1;
-	}
-
-	ret = listen(socket_fd, 50);
-	if (ret) {
-		RTE_LOG(ERR, EAL, "Failed to listen: %s!\n", strerror(errno));
-		close(socket_fd);
-		return -1;
-	}
-
-	/* save the socket in local configuration */
-	mp_socket_fd = socket_fd;
-
-	return 0;
-}
-
-/*
- * set up a local socket and tell it to listen for incoming connections
- */
-int
-vfio_mp_sync_setup(void)
-{
-	int ret;
-	char thread_name[RTE_MAX_THREAD_NAME_LEN];
-
-	if (vfio_mp_sync_socket_setup() < 0) {
-		RTE_LOG(ERR, EAL, "Failed to set up local socket!\n");
-		return -1;
-	}
-
-	ret = pthread_create(&socket_thread, NULL,
-			vfio_mp_sync_thread, NULL);
-	if (ret) {
-		RTE_LOG(ERR, EAL,
-			"Failed to create thread for communication with secondary processes!\n");
-		close(mp_socket_fd);
-		return -1;
-	}
-
-	/* Set thread_name for aid in debugging. */
-	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "vfio-sync");
-	ret = rte_thread_setname(socket_thread, thread_name);
-	if (ret)
-		RTE_LOG(DEBUG, EAL,
-			"Failed to set thread name for secondary processes!\n");
-
-	return 0;
-}
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index fe186cb..a8ea4ea 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -170,21 +170,6 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_pci_detach;
-	rte_pci_dump;
-	rte_pci_ioport_map;
-	rte_pci_ioport_read;
-	rte_pci_ioport_unmap;
-	rte_pci_ioport_write;
-	rte_pci_map_device;
-	rte_pci_probe;
-	rte_pci_probe_one;
-	rte_pci_read_config;
-	rte_pci_register;
-	rte_pci_scan;
-	rte_pci_unmap_device;
-	rte_pci_unregister;
-	rte_pci_write_config;
 	rte_vdev_init;
 	rte_vdev_register;
 	rte_vdev_uninit;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 354d170..e7be855 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1151,8 +1151,6 @@ TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
 	} \
 } while (0)
 
-#define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
-
 /**
  * l2 tunnel configuration.
  */
diff --git a/lib/librte_pci/Makefile b/lib/librte_pci/Makefile
new file mode 100644
index 0000000..fc2fadb
--- /dev/null
+++ b/lib/librte_pci/Makefile
@@ -0,0 +1,48 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_pci.a
+
+CFLAGS := -I$(SRCDIR)/include -I$(SRCDIR) $(CFLAGS)
+CFLAGS += $(WERROR_FLAGS) -O3
+
+EXPORT_MAP := rte_pci_version.map
+
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_PCI) += rte_pci.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI)-include += include/rte_pci.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
new file mode 100644
index 0000000..2647568
--- /dev/null
+++ b/lib/librte_pci/include/rte_pci.h
@@ -0,0 +1,287 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_PCI_H_
+#define _RTE_PCI_H_
+
+/**
+ * @file
+ *
+ * RTE PCI Library
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+
+/** Formatting string for PCI device identifier: Ex: 0000:00:01.0 */
+#define PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+#define PCI_PRI_STR_SIZE sizeof("XXXXXXXX:XX:XX.X")
+
+/** Short formatting string, without domain, for PCI device: Ex: 00:01.0 */
+#define PCI_SHORT_PRI_FMT "%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+
+/** Nb. of values in PCI device identifier format string. */
+#define PCI_FMT_NVAL 4
+
+/** Nb. of values in PCI resource format. */
+#define PCI_RESOURCE_FMT_NVAL 3
+
+/** Maximum number of PCI resources. */
+#define PCI_MAX_RESOURCE 6
+
+/**
+ * A structure describing an ID for a PCI driver. Each driver provides a
+ * table of these IDs for each device that it supports.
+ */
+struct rte_pci_id {
+	uint32_t class_id;            /**< Class ID or RTE_CLASS_ANY_ID. */
+	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
+	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
+	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
+	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
+};
+
+/**
+ * A structure describing the location of a PCI device.
+ */
+struct rte_pci_addr {
+	uint32_t domain;                /**< Device domain */
+	uint8_t bus;                    /**< Device bus */
+	uint8_t devid;                  /**< Device ID */
+	uint8_t function;               /**< Device function. */
+};
+
+/** Any PCI device identifier (vendor, device, ...) */
+#define PCI_ANY_ID (0xffff)
+#define RTE_CLASS_ANY_ID (0xffffff)
+
+/**
+ * A structure describing a PCI mapping.
+ */
+struct pci_map {
+	void *addr;
+	char *path;
+	uint64_t offset;
+	uint64_t size;
+	uint64_t phaddr;
+};
+
+struct pci_msix_table {
+	int bar_index;
+	uint32_t offset;
+	uint32_t size;
+};
+
+/**
+ * A structure describing a mapped PCI resource.
+ * For multi-process we need to reproduce all PCI mappings in secondary
+ * processes, so save them in a tailq.
+ */
+struct mapped_pci_resource {
+	TAILQ_ENTRY(mapped_pci_resource) next;
+
+	struct rte_pci_addr pci_addr;
+	char path[PATH_MAX];
+	int nb_maps;
+	struct pci_map maps[PCI_MAX_RESOURCE];
+	struct pci_msix_table msix_table;
+};
+
+
+/** mapped pci device list */
+TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
+
+/**< Internal use only - Macro used by pci addr parsing functions **/
+#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
+do {                                                               \
+	unsigned long val;                                      \
+	char *end;                                              \
+	errno = 0;                                              \
+	val = strtoul((in), &end, 16);                          \
+	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
+		return -EINVAL;                                 \
+	(fd) = (typeof (fd))val;                                \
+	(in) = end + 1;                                         \
+} while(0)
+
+/**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided without
+ * a domain prefix (i.e. domain returned is always 0)
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned.
+ *	Domain will always be returned as 0
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	dev_addr->domain = 0;
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+/**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided including
+ * a domain prefix.
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XXXX:XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+#undef GET_PCIADDR_FIELD
+
+/**
+ * Utility function to write a pci device name, this device name can later be
+ * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
+ * BDF helpers.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ */
+static inline void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+		char *output, size_t size)
+{
+	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+			    addr->domain, addr->bus,
+			    addr->devid, addr->function) >= 0);
+}
+
+/* Compare two PCI device addresses. */
+/**
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
+static inline int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			 const struct rte_pci_addr *addr2)
+{
+	uint64_t dev_addr, dev_addr2;
+
+	if ((addr == NULL) || (addr2 == NULL))
+		return -1;
+
+	dev_addr = ((uint64_t)addr->domain << 24) |
+		(addr->bus << 16) | (addr->devid << 8) | addr->function;
+	dev_addr2 = ((uint64_t)addr2->domain << 24) |
+		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+	if (dev_addr > dev_addr2)
+		return 1;
+	else if (dev_addr < dev_addr2)
+		return -1;
+	else
+		return 0;
+}
+
+/**
+ * Map a particular resource from a file.
+ *
+ * @param requested_addr
+ *      The starting address for the new mapping range.
+ * @param fd
+ *      The file descriptor.
+ * @param offset
+ *      The offset for the mapping range.
+ * @param size
+ *      The size for the mapping range.
+ * @param additional_flags
+ *      The additional flags for the mapping range.
+ * @return
+ *   - On success, the function returns a pointer to the mapped area.
+ *   - On error, the value MAP_FAILED is returned.
+ */
+void *pci_map_resource(void *requested_addr, int fd, off_t offset,
+		size_t size, int additional_flags);
+
+/**
+ * Unmap a particular resource.
+ *
+ * @param requested_addr
+ *      The address for the unmapping range.
+ * @param size
+ *      The size for the unmapping range.
+ */
+void pci_unmap_resource(void *requested_addr, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PCI_H_ */
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
new file mode 100644
index 0000000..9dfdd3f
--- /dev/null
+++ b/lib/librte_pci/rte_pci.c
@@ -0,0 +1,92 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+
+#include "rte_pci.h"
+
+/* map a particular resource from a file */
+void *
+pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+		 int additional_flags)
+{
+	void *mapaddr;
+
+	/* Map the PCI memory resource of device */
+	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+			MAP_SHARED | additional_flags, fd, offset);
+	if (mapaddr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
+			__func__, fd, requested_addr,
+			(unsigned long)size, (unsigned long)offset,
+			strerror(errno), mapaddr);
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
+
+	return mapaddr;
+}
+
+/* unmap a particular resource */
+void
+pci_unmap_resource(void *requested_addr, size_t size)
+{
+	if (requested_addr == NULL)
+		return;
+
+	/* Unmap the PCI memory resource of device */
+	if (munmap(requested_addr, size)) {
+		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+			__func__, requested_addr, (unsigned long)size,
+			strerror(errno));
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
+				requested_addr);
+}
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
new file mode 100644
index 0000000..64dec54
--- /dev/null
+++ b/lib/librte_pci/rte_pci_version.map
@@ -0,0 +1,8 @@
+DPDK_17.11 {
+	global:
+
+	pci_map_resource;
+	pci_unmap_resource;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 0b8f612..88b1a71 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -97,6 +97,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI)            += -lrte_pci
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
@@ -106,6 +107,8 @@ ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
 endif
 
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI_BUS)        += -lrte_bus_pci
+
 ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
 # plugins (link only if static libraries)
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 04/16] lib: include PCI bus header
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
                         ` (2 preceding siblings ...)
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 03/16] pci: introduce PCI lib and bus Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 05/16] drivers: " Gaetan Rivet
                         ` (12 subsequent siblings)
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update the libraries, as structuraly unsound as it may be.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ether/rte_ethdev_pci.h          | 1 +
 lib/librte_eventdev/rte_eventdev_pmd_pci.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h
index 56b1072..722075e 100644
--- a/lib/librte_ether/rte_ethdev_pci.h
+++ b/lib/librte_ether/rte_ethdev_pci.h
@@ -36,6 +36,7 @@
 
 #include <rte_malloc.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 
 /**
diff --git a/lib/librte_eventdev/rte_eventdev_pmd_pci.h b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
index b6bd731..ade32b5 100644
--- a/lib/librte_eventdev/rte_eventdev_pmd_pci.h
+++ b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
@@ -50,6 +50,7 @@ extern "C" {
 #include <rte_eal.h>
 #include <rte_lcore.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "rte_eventdev_pmd.h"
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 05/16] drivers: include PCI bus header
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
                         ` (3 preceding siblings ...)
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 04/16] lib: include PCI bus header Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 06/16] test: " Gaetan Rivet
                         ` (11 subsequent siblings)
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update drivers.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/bus/pci/bsd/pci.c                  | 1 +
 drivers/bus/pci/linux/pci.c                | 1 +
 drivers/bus/pci/linux/pci_uio.c            | 1 +
 drivers/bus/pci/linux/pci_vfio.c           | 1 +
 drivers/bus/pci/linux/vfio_mp_sync.c       | 1 +
 drivers/bus/pci/pci_common.c               | 1 +
 drivers/bus/pci/pci_common_uio.c           | 1 +
 drivers/bus/pci/private.h                  | 1 +
 drivers/crypto/qat/qat_qp.c                | 1 +
 drivers/event/octeontx/ssovf_probe.c       | 1 +
 drivers/mempool/octeontx/octeontx_fpavf.c  | 2 +-
 drivers/net/ark/ark_ethdev.c               | 1 +
 drivers/net/avp/avp_ethdev.c               | 2 ++
 drivers/net/bnxt/bnxt.h                    | 1 +
 drivers/net/bonding/rte_eth_bond_args.c    | 1 +
 drivers/net/cxgbe/base/adapter.h           | 1 +
 drivers/net/cxgbe/cxgbe_ethdev.c           | 1 +
 drivers/net/e1000/em_ethdev.c              | 1 +
 drivers/net/e1000/igb_ethdev.c             | 1 +
 drivers/net/e1000/igb_pf.c                 | 1 +
 drivers/net/ena/ena_ethdev.h               | 1 +
 drivers/net/enic/base/vnic_dev.h           | 4 +++-
 drivers/net/enic/enic_ethdev.c             | 1 +
 drivers/net/enic/enic_main.c               | 1 +
 drivers/net/i40e/i40e_ethdev.c             | 1 +
 drivers/net/i40e/i40e_ethdev_vf.c          | 1 +
 drivers/net/ixgbe/ixgbe_ethdev.c           | 1 +
 drivers/net/ixgbe/ixgbe_ethdev.h           | 1 +
 drivers/net/mlx4/mlx4_ethdev.c             | 2 +-
 drivers/net/mlx5/mlx5.c                    | 1 +
 drivers/net/mlx5/mlx5_ethdev.c             | 1 +
 drivers/net/nfp/nfp_nfpu.c                 | 2 +-
 drivers/net/nfp/nfp_nfpu.h                 | 2 +-
 drivers/net/octeontx/base/octeontx_pkivf.c | 2 +-
 drivers/net/octeontx/base/octeontx_pkovf.c | 2 +-
 drivers/net/sfc/sfc.h                      | 1 +
 drivers/net/sfc/sfc_ethdev.c               | 1 +
 drivers/net/thunderx/nicvf_ethdev.c        | 1 +
 drivers/net/virtio/virtio_ethdev.c         | 1 +
 drivers/net/virtio/virtio_pci.h            | 1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c       | 1 +
 41 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
index 599519a..753d914 100644
--- a/drivers/bus/pci/bsd/pci.c
+++ b/drivers/bus/pci/bsd/pci.c
@@ -57,6 +57,7 @@
 #include <rte_interrupts.h>
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_common.h>
 #include <rte_launch.h>
 #include <rte_memory.h>
diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c
index c1fcc56..422579f 100644
--- a/drivers/bus/pci/linux/pci.c
+++ b/drivers/bus/pci/linux/pci.c
@@ -37,6 +37,7 @@
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 #include <rte_devargs.h>
diff --git a/drivers/bus/pci/linux/pci_uio.c b/drivers/bus/pci/linux/pci_uio.c
index d3f0556..940fa21 100644
--- a/drivers/bus/pci/linux/pci_uio.c
+++ b/drivers/bus/pci/linux/pci_uio.c
@@ -47,6 +47,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_common.h>
 #include <rte_malloc.h>
diff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c
index e69e4d3..855e2b9 100644
--- a/drivers/bus/pci/linux/pci_vfio.c
+++ b/drivers/bus/pci/linux/pci_vfio.c
@@ -42,6 +42,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 
diff --git a/drivers/bus/pci/linux/vfio_mp_sync.c b/drivers/bus/pci/linux/vfio_mp_sync.c
index dd24e86..d07687f 100644
--- a/drivers/bus/pci/linux/vfio_mp_sync.c
+++ b/drivers/bus/pci/linux/vfio_mp_sync.c
@@ -50,6 +50,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index 7b68e99..cd95d1a 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -45,6 +45,7 @@
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_per_lcore.h>
 #include <rte_memory.h>
 #include <rte_memzone.h>
diff --git a/drivers/bus/pci/pci_common_uio.c b/drivers/bus/pci/pci_common_uio.c
index 4365660..544c606 100644
--- a/drivers/bus/pci/pci_common_uio.c
+++ b/drivers/bus/pci/pci_common_uio.c
@@ -40,6 +40,7 @@
 
 #include <rte_eal.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tailq.h>
 #include <rte_log.h>
 #include <rte_malloc.h>
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 7ff1fc4..fdc2c81 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -37,6 +37,7 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 struct rte_pci_driver;
 struct rte_pci_device;
diff --git a/drivers/crypto/qat/qat_qp.c b/drivers/crypto/qat/qat_qp.c
index 34f75ca..8489662 100644
--- a/drivers/crypto/qat/qat_qp.c
+++ b/drivers/crypto/qat/qat_qp.c
@@ -37,6 +37,7 @@
 #include <rte_memzone.h>
 #include <rte_cryptodev_pmd.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_prefetch.h>
 
diff --git a/drivers/event/octeontx/ssovf_probe.c b/drivers/event/octeontx/ssovf_probe.c
index e1c0c6d..1cac4bc 100644
--- a/drivers/event/octeontx/ssovf_probe.c
+++ b/drivers/event/octeontx/ssovf_probe.c
@@ -35,6 +35,7 @@
 #include <rte_eal.h>
 #include <rte_io.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "ssovf_evdev.h"
 
diff --git a/drivers/mempool/octeontx/octeontx_fpavf.c b/drivers/mempool/octeontx/octeontx_fpavf.c
index eea934f..bbede5d 100644
--- a/drivers/mempool/octeontx/octeontx_fpavf.c
+++ b/drivers/mempool/octeontx/octeontx_fpavf.c
@@ -41,7 +41,7 @@
 
 #include <rte_atomic.h>
 #include <rte_eal.h>
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_errno.h>
 #include <rte_memory.h>
 #include <rte_malloc.h>
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index dae1f3d..384be47 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -35,6 +35,7 @@
 #include <sys/stat.h>
 #include <dlfcn.h>
 
+#include <rte_bus_pci.h>
 #include <rte_ethdev_pci.h>
 #include <rte_kvargs.h>
 
diff --git a/drivers/net/avp/avp_ethdev.c b/drivers/net/avp/avp_ethdev.c
index b97a90c..89e91e2 100644
--- a/drivers/net/avp/avp_ethdev.c
+++ b/drivers/net/avp/avp_ethdev.c
@@ -36,6 +36,7 @@
 #include <errno.h>
 #include <unistd.h>
 
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_memcpy.h>
@@ -45,6 +46,7 @@
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 294a174..039b248 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -39,6 +39,7 @@
 #include <sys/queue.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_memory.h>
 #include <rte_lcore.h>
diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index c4dcefa..dea0265 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -33,6 +33,7 @@
 
 #include <rte_devargs.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 
 #include <cmdline_parse.h>
diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index 5e5f221..f2057af 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -36,6 +36,7 @@
 #ifndef __T4_ADAPTER_H__
 #define __T4_ADAPTER_H__
 
+#include <rte_bus_pci.h>
 #include <rte_mbuf.h>
 #include <rte_io.h>
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 02b4f62..b1405e5 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index e724205..aa831f8 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index f3b1d70..380ec31 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/e1000/igb_pf.c b/drivers/net/e1000/igb_pf.c
index 6809d30..cd6ae2f 100644
--- a/drivers/net/e1000/igb_pf.c
+++ b/drivers/net/e1000/igb_pf.c
@@ -39,6 +39,7 @@
 #include <stdarg.h>
 #include <inttypes.h>
 
+#include <rte_bus_pci.h>
 #include <rte_interrupts.h>
 #include <rte_log.h>
 #include <rte_debug.h>
diff --git a/drivers/net/ena/ena_ethdev.h b/drivers/net/ena/ena_ethdev.h
index dc3080f..be8bc9f 100644
--- a/drivers/net/ena/ena_ethdev.h
+++ b/drivers/net/ena/ena_ethdev.h
@@ -35,6 +35,7 @@
 #define _ENA_ETHDEV_H_
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "ena_com.h"
 
diff --git a/drivers/net/enic/base/vnic_dev.h b/drivers/net/enic/base/vnic_dev.h
index 9a9e691..c9ca25b 100644
--- a/drivers/net/enic/base/vnic_dev.h
+++ b/drivers/net/enic/base/vnic_dev.h
@@ -35,8 +35,10 @@
 #ifndef _VNIC_DEV_H_
 #define _VNIC_DEV_H_
 
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+
 #include "enic_compat.h"
-#include "rte_pci.h"
 #include "vnic_resource.h"
 #include "vnic_devcmd.h"
 
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 5386b2a..7a7e2d9 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -37,6 +37,7 @@
 
 #include <rte_dev.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_string_fns.h>
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 5211670..be62447 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -40,6 +40,7 @@
 #include <libgen.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_memzone.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 814f458..ffead82 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_eal.h>
 #include <rte_string_fns.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 63d1f77..39a0cbd 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -47,6 +47,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a08e475..a750a88 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index e28c856..5156483 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -41,6 +41,7 @@
 #include <rte_time.h>
 #include <rte_hash.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tm_driver.h>
 
 /* need update link, bit flag */
diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
index 8962be1..b97b146 100644
--- a/drivers/net/mlx4/mlx4_ethdev.c
+++ b/drivers/net/mlx4/mlx4_ethdev.c
@@ -64,7 +64,7 @@
 #include <rte_errno.h>
 #include <rte_ethdev.h>
 #include <rte_ether.h>
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "mlx4.h"
 #include "mlx4_rxtx.h"
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 29221dc..d60ef74 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -54,6 +54,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_common.h>
 #include <rte_kvargs.h>
 
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index e06dce3..c31ea4b 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -56,6 +56,7 @@
 
 #include <rte_atomic.h>
 #include <rte_ethdev.h>
+#include <rte_bus_pci.h>
 #include <rte_mbuf.h>
 #include <rte_common.h>
 #include <rte_interrupts.h>
diff --git a/drivers/net/nfp/nfp_nfpu.c b/drivers/net/nfp/nfp_nfpu.c
index 556ded3..5775d8d 100644
--- a/drivers/net/nfp/nfp_nfpu.c
+++ b/drivers/net/nfp/nfp_nfpu.c
@@ -8,7 +8,7 @@
 #include <fcntl.h>
 #include <sys/types.h>
 
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_malloc.h>
 
 #include "nfp_nfpu.h"
diff --git a/drivers/net/nfp/nfp_nfpu.h b/drivers/net/nfp/nfp_nfpu.h
index 31511b3..e56fa09 100644
--- a/drivers/net/nfp/nfp_nfpu.h
+++ b/drivers/net/nfp/nfp_nfpu.h
@@ -42,7 +42,7 @@
  */
 
 
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include "nfp_nspu.h"
 
 typedef struct {
diff --git a/drivers/net/octeontx/base/octeontx_pkivf.c b/drivers/net/octeontx/base/octeontx_pkivf.c
index afae6a3..20cbe0c 100644
--- a/drivers/net/octeontx/base/octeontx_pkivf.c
+++ b/drivers/net/octeontx/base/octeontx_pkivf.c
@@ -32,7 +32,7 @@
 #include <string.h>
 
 #include <rte_eal.h>
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "octeontx_pkivf.h"
 
diff --git a/drivers/net/octeontx/base/octeontx_pkovf.c b/drivers/net/octeontx/base/octeontx_pkovf.c
index a8f6e5d..2bf607b 100644
--- a/drivers/net/octeontx/base/octeontx_pkovf.c
+++ b/drivers/net/octeontx/base/octeontx_pkovf.c
@@ -37,7 +37,7 @@
 #include <rte_cycles.h>
 #include <rte_malloc.h>
 #include <rte_memory.h>
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_spinlock.h>
 
 #include "../octeontx_logs.h"
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index c170384..7f11bf2 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -35,6 +35,7 @@
 #include <stdbool.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_kvargs.h>
 #include <rte_spinlock.h>
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index bd09191..430e24f 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -33,6 +33,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_errno.h>
 
 #include "efx.h"
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index 551b371..24ac3f9 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -61,6 +61,7 @@
 #include <rte_malloc.h>
 #include <rte_random.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tailq.h>
 
 #include "base/nicvf_plat.h"
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 0ec54a9..3c4c083 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -46,6 +46,7 @@
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_common.h>
 #include <rte_errno.h>
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 5f3b6c8..36d452c 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -37,6 +37,7 @@
 #include <stdint.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 
 struct virtqueue;
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 58bc4f2..9772386 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 06/16] test: include PCI bus header
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
                         ` (4 preceding siblings ...)
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 05/16] drivers: " Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 07/16] app/testpmd: " Gaetan Rivet
                         ` (10 subsequent siblings)
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update test applications.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 test/test/test_kni.c    | 1 +
 test/test/virtual_pmd.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/test/test/test_kni.c b/test/test/test_kni.c
index 2450c9f..b956727 100644
--- a/test/test/test_kni.c
+++ b/test/test/test_kni.c
@@ -42,6 +42,7 @@
 #include <rte_string_fns.h>
 #include <rte_mempool.h>
 #include <rte_ethdev.h>
+#include <rte_bus_pci.h>
 #include <rte_cycles.h>
 #include <rte_kni.h>
 
diff --git a/test/test/virtual_pmd.c b/test/test/virtual_pmd.c
index 09daf6c..b57a949 100644
--- a/test/test/virtual_pmd.c
+++ b/test/test/virtual_pmd.c
@@ -34,6 +34,7 @@
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_memory.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 07/16] app/testpmd: include PCI bus header
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
                         ` (5 preceding siblings ...)
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 06/16] test: " Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 08/16] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
                         ` (9 subsequent siblings)
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update applications.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 app/test-pmd/testpmd.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 0b8e624..b05c8a0 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -35,6 +35,7 @@
 #define _TESTPMD_H_
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_gro.h>
 #include <rte_gso.h>
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 08/16] cryptodev: move PCI specific helpers to drivers/crypto
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
                         ` (6 preceding siblings ...)
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 07/16] app/testpmd: " Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 09/16] net/bonding: use local prefix for local function Gaetan Rivet
                         ` (8 subsequent siblings)
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Those helpers rely on the PCI bus driver implementation.
Other similar libraries relied on the bus-specifics being handled in
inlined functions, to be compiled on demand by drivers, once the proper
PCI dependency has been settled. This seems unsafe.

Move the PCI-specific helpers out of the lib directory to the
drivers/crypto directory, properly following the dependency hierarchy.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/crypto/Makefile                          |   4 +-
 drivers/crypto/pci/Makefile                      |  52 +++++++++
 drivers/crypto/pci/rte_cryptodev_pci.c           | 128 +++++++++++++++++++++++
 drivers/crypto/pci/rte_cryptodev_pci.h           |  94 +++++++++++++++++
 drivers/crypto/pci/rte_cryptodev_pci_version.map |   7 ++
 lib/librte_cryptodev/Makefile                    |   1 -
 lib/librte_cryptodev/rte_cryptodev_pci.h         |  92 ----------------
 lib/librte_cryptodev/rte_cryptodev_pmd.c         |  94 -----------------
 lib/librte_cryptodev/rte_cryptodev_version.map   |   2 -
 9 files changed, 284 insertions(+), 190 deletions(-)
 create mode 100644 drivers/crypto/pci/Makefile
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.c
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.h
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci_version.map
 delete mode 100644 lib/librte_cryptodev/rte_cryptodev_pci.h

diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 7a719b9..cfd6cb6 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_cryptodev
 
+DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
+DEPDIRS-pci = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm
 DEPDIRS-aesni_gcm = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb
@@ -42,7 +44,7 @@ DEPDIRS-armv8 = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_OPENSSL) += openssl
 DEPDIRS-openssl = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat
-DEPDIRS-qat = $(core-libs)
+DEPDIRS-qat = $(core-libs) librte_cryptodev_pci
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER) += scheduler
 DEPDIRS-scheduler = $(core-libs) librte_kvargs librte_reorder
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += snow3g
diff --git a/drivers/crypto/pci/Makefile b/drivers/crypto/pci/Makefile
new file mode 100644
index 0000000..da819f2
--- /dev/null
+++ b/drivers/crypto/pci/Makefile
@@ -0,0 +1,52 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A. All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND S.A. nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_cryptodev_pci.a
+
+# library version
+LIBABIVER := 1
+
+# build flags
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# library source files
+SRCS-y += rte_cryptodev_pci.c
+
+# export include files
+SYMLINK-y-include += rte_cryptodev_pci.h
+
+# versioning export map
+EXPORT_MAP := rte_cryptodev_pci_version.map
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/crypto/pci/rte_cryptodev_pci.c b/drivers/crypto/pci/rte_cryptodev_pci.c
new file mode 100644
index 0000000..a2a1366
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci.c
@@ -0,0 +1,128 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of the copyright holder nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_malloc.h>
+
+#include "rte_cryptodev_pci.h"
+
+int
+rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
+			size_t private_data_size,
+			cryptodev_pci_init_t dev_init)
+{
+	struct rte_cryptodev *cryptodev;
+
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+
+	int retval;
+
+	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name, rte_socket_id());
+	if (cryptodev == NULL)
+		return -ENOMEM;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc_socket(
+						"cryptodev private structure",
+						private_data_size,
+						RTE_CACHE_LINE_SIZE,
+						rte_socket_id());
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private "
+					"device data");
+	}
+
+	cryptodev->device = &pci_dev->device;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	/* Invoke PMD device initialization function */
+	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
+	retval = dev_init(cryptodev);
+	if (retval == 0)
+		return 0;
+
+	CDEV_LOG_ERR("driver %s: crypto_dev_init(vendor_id=0x%x device_id=0x%x)"
+			" failed", pci_dev->device.driver->name,
+			(unsigned int) pci_dev->id.vendor_id,
+			(unsigned int) pci_dev->id.device_id);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	return -ENXIO;
+}
+
+int
+rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
+		cryptodev_pci_uninit_t dev_uninit)
+{
+	struct rte_cryptodev *cryptodev;
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+	int ret;
+
+	if (pci_dev == NULL)
+		return -EINVAL;
+
+	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
+	if (cryptodev == NULL)
+		return -ENODEV;
+
+	/* Invoke PMD device uninit function */
+	if (dev_uninit) {
+		ret = dev_uninit(cryptodev);
+		if (ret)
+			return ret;
+	}
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->device = NULL;
+	cryptodev->data = NULL;
+
+	return 0;
+}
diff --git a/drivers/crypto/pci/rte_cryptodev_pci.h b/drivers/crypto/pci/rte_cryptodev_pci.h
new file mode 100644
index 0000000..97b6f1e
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci.h
@@ -0,0 +1,94 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of the copyright holder nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_CRYPTODEV_PCI_H_
+#define _RTE_CRYPTODEV_PCI_H_
+
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
+
+/**
+ * Initialisation function of a crypto driver invoked for each matching
+ * crypto PCI device detected during the PCI probing phase.
+ *
+ * @param	dev	The dev pointer is the address of the *rte_cryptodev*
+ *			structure associated with the matching device and which
+ *			has been [automatically] allocated in the
+ *			*rte_crypto_devices* array.
+ *
+ * @return
+ *   - 0: Success, the device is properly initialised by the driver.
+ *        In particular, the driver MUST have set up the *dev_ops* pointer
+ *        of the *dev* structure.
+ *   - <0: Error code of the device initialisation failure.
+ */
+typedef int (*cryptodev_pci_init_t)(struct rte_cryptodev *dev);
+
+/**
+ * Finalisation function of a driver invoked for each matching
+ * PCI device detected during the PCI closing phase.
+ *
+ * @param	dev	The dev pointer is the address of the *rte_cryptodev*
+ *			structure associated with the matching device and which
+ *			has been [automatically] allocated in the
+ *			*rte_crypto_devices* array.
+ *
+ *  * @return
+ *   - 0: Success, the device is properly finalised by the driver.
+ *        In particular, the driver MUST free the *dev_ops* pointer
+ *        of the *dev* structure.
+ *   - <0: Error code of the device initialisation failure.
+ */
+typedef int (*cryptodev_pci_uninit_t)(struct rte_cryptodev *dev);
+
+/**
+ * @internal
+ * Wrapper for use by pci drivers as a .probe function to attach to a crypto
+ * interface.
+ */
+int
+rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
+			size_t private_data_size,
+			cryptodev_pci_init_t dev_init);
+
+/**
+ * @internal
+ * Wrapper for use by pci drivers as a .remove function to detach a crypto
+ * interface.
+ */
+int
+rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
+		cryptodev_pci_uninit_t dev_uninit);
+
+#endif /* _RTE_CRYPTODEV_PCI_H_ */
diff --git a/drivers/crypto/pci/rte_cryptodev_pci_version.map b/drivers/crypto/pci/rte_cryptodev_pci_version.map
new file mode 100644
index 0000000..0510fef
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci_version.map
@@ -0,0 +1,7 @@
+DPDK_17.11 {
+	global:
+
+	rte_cryptodev_pci_generic_probe;
+	rte_cryptodev_pci_generic_remove;
+
+};
diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index 6ac331b..bd94cf7 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -49,7 +49,6 @@ SYMLINK-y-include += rte_crypto_sym.h
 SYMLINK-y-include += rte_cryptodev.h
 SYMLINK-y-include += rte_cryptodev_pmd.h
 SYMLINK-y-include += rte_cryptodev_vdev.h
-SYMLINK-y-include += rte_cryptodev_pci.h
 
 # versioning export map
 EXPORT_MAP := rte_cryptodev_version.map
diff --git a/lib/librte_cryptodev/rte_cryptodev_pci.h b/lib/librte_cryptodev/rte_cryptodev_pci.h
deleted file mode 100644
index 67eda96..0000000
--- a/lib/librte_cryptodev/rte_cryptodev_pci.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2017 Intel Corporation. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of the copyright holder nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_CRYPTODEV_PCI_H_
-#define _RTE_CRYPTODEV_PCI_H_
-
-#include <rte_pci.h>
-#include "rte_cryptodev.h"
-
-/**
- * Initialisation function of a crypto driver invoked for each matching
- * crypto PCI device detected during the PCI probing phase.
- *
- * @param	dev	The dev pointer is the address of the *rte_cryptodev*
- *			structure associated with the matching device and which
- *			has been [automatically] allocated in the
- *			*rte_crypto_devices* array.
- *
- * @return
- *   - 0: Success, the device is properly initialised by the driver.
- *        In particular, the driver MUST have set up the *dev_ops* pointer
- *        of the *dev* structure.
- *   - <0: Error code of the device initialisation failure.
- */
-typedef int (*cryptodev_pci_init_t)(struct rte_cryptodev *dev);
-
-/**
- * Finalisation function of a driver invoked for each matching
- * PCI device detected during the PCI closing phase.
- *
- * @param	dev	The dev pointer is the address of the *rte_cryptodev*
- *			structure associated with the matching device and which
- *			has been [automatically] allocated in the
- *			*rte_crypto_devices* array.
- *
- *  * @return
- *   - 0: Success, the device is properly finalised by the driver.
- *        In particular, the driver MUST free the *dev_ops* pointer
- *        of the *dev* structure.
- *   - <0: Error code of the device initialisation failure.
- */
-typedef int (*cryptodev_pci_uninit_t)(struct rte_cryptodev *dev);
-
-/**
- * @internal
- * Wrapper for use by pci drivers as a .probe function to attach to a crypto
- * interface.
- */
-int
-rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
-			size_t private_data_size,
-			cryptodev_pci_init_t dev_init);
-
-/**
- * @internal
- * Wrapper for use by pci drivers as a .remove function to detach a crypto
- * interface.
- */
-int
-rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
-		cryptodev_pci_uninit_t dev_uninit);
-
-#endif /* _RTE_CRYPTODEV_PCI_H_ */
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.c b/lib/librte_cryptodev/rte_cryptodev_pmd.c
index a57faad..ec5c33b 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.c
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.c
@@ -33,7 +33,6 @@
 #include <rte_malloc.h>
 
 #include "rte_cryptodev_vdev.h"
-#include "rte_cryptodev_pci.h"
 #include "rte_cryptodev_pmd.h"
 
 /**
@@ -154,96 +153,3 @@ rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
 	rte_kvargs_free(kvlist);
 	return ret;
 }
-
-int
-rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
-			size_t private_data_size,
-			cryptodev_pci_init_t dev_init)
-{
-	struct rte_cryptodev *cryptodev;
-
-	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
-
-	int retval;
-
-	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
-			sizeof(cryptodev_name));
-
-	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name, rte_socket_id());
-	if (cryptodev == NULL)
-		return -ENOMEM;
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-		cryptodev->data->dev_private =
-				rte_zmalloc_socket(
-						"cryptodev private structure",
-						private_data_size,
-						RTE_CACHE_LINE_SIZE,
-						rte_socket_id());
-
-		if (cryptodev->data->dev_private == NULL)
-			rte_panic("Cannot allocate memzone for private "
-					"device data");
-	}
-
-	cryptodev->device = &pci_dev->device;
-
-	/* init user callbacks */
-	TAILQ_INIT(&(cryptodev->link_intr_cbs));
-
-	/* Invoke PMD device initialization function */
-	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
-	retval = dev_init(cryptodev);
-	if (retval == 0)
-		return 0;
-
-	CDEV_LOG_ERR("driver %s: crypto_dev_init(vendor_id=0x%x device_id=0x%x)"
-			" failed", pci_dev->device.driver->name,
-			(unsigned int) pci_dev->id.vendor_id,
-			(unsigned int) pci_dev->id.device_id);
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-		rte_free(cryptodev->data->dev_private);
-
-	/* free crypto device */
-	rte_cryptodev_pmd_release_device(cryptodev);
-
-	return -ENXIO;
-}
-
-int
-rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
-		cryptodev_pci_uninit_t dev_uninit)
-{
-	struct rte_cryptodev *cryptodev;
-	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
-	int ret;
-
-	if (pci_dev == NULL)
-		return -EINVAL;
-
-	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
-			sizeof(cryptodev_name));
-
-	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
-	if (cryptodev == NULL)
-		return -ENODEV;
-
-	/* Invoke PMD device uninit function */
-	if (dev_uninit) {
-		ret = dev_uninit(cryptodev);
-		if (ret)
-			return ret;
-	}
-
-	/* free crypto device */
-	rte_cryptodev_pmd_release_device(cryptodev);
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-		rte_free(cryptodev->data->dev_private);
-
-	cryptodev->device = NULL;
-	cryptodev->data = NULL;
-
-	return 0;
-}
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index e9ba88a..496253d 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -68,8 +68,6 @@ DPDK_17.08 {
 	rte_cryptodev_get_aead_algo_enum;
 	rte_cryptodev_get_header_session_size;
 	rte_cryptodev_get_private_session_size;
-	rte_cryptodev_pci_generic_probe;
-	rte_cryptodev_pci_generic_remove;
 	rte_cryptodev_sym_capability_check_aead;
 	rte_cryptodev_sym_session_init;
 	rte_cryptodev_sym_session_clear;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 09/16] net/bonding: use local prefix for local function
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
                         ` (7 preceding siblings ...)
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 08/16] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 10/16] pci: avoid inlining functions Gaetan Rivet
                         ` (7 subsequent siblings)
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/net/bonding/rte_eth_bond_args.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index dea0265..e816da3 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -90,7 +90,7 @@ find_port_id_by_dev_name(const char *name)
 }
 
 static inline int
-pci_addr_cmp(const struct rte_device *dev, const void *_pci_addr)
+bond_pci_addr_cmp(const struct rte_device *dev, const void *_pci_addr)
 {
 	struct rte_pci_device *pdev;
 	const struct rte_pci_addr *paddr = _pci_addr;
@@ -119,7 +119,7 @@ parse_port_id(const char *port_str)
 
 	/* try parsing as pci address, physical devices */
 	if (pci_bus->parse(port_str, &dev_addr) == 0) {
-		dev = pci_bus->find_device(NULL, pci_addr_cmp, &dev_addr);
+		dev = pci_bus->find_device(NULL, bond_pci_addr_cmp, &dev_addr);
 		if (dev == NULL) {
 			RTE_LOG(ERR, PMD, "unable to find PCI device\n");
 			return -1;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 10/16] pci: avoid inlining functions
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
                         ` (8 preceding siblings ...)
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 09/16] net/bonding: use local prefix for local function Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 11/16] pci: avoid over-complicated macro Gaetan Rivet
                         ` (6 subsequent siblings)
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Parsing operations should not happen in performance critical sections.
Headers should not propose implementations unless duly required.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_pci/include/rte_pci.h   | 69 ++++----------------------------------
 lib/librte_pci/rte_pci.c           | 65 +++++++++++++++++++++++++++++++++++
 lib/librte_pci/rte_pci_version.map |  4 +++
 3 files changed, 75 insertions(+), 63 deletions(-)

diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
index 2647568..fe4d411 100644
--- a/lib/librte_pci/include/rte_pci.h
+++ b/lib/librte_pci/include/rte_pci.h
@@ -134,19 +134,6 @@ struct mapped_pci_resource {
 /** mapped pci device list */
 TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 
-/**< Internal use only - Macro used by pci addr parsing functions **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
-do {                                                               \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
-
 /**
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided without
@@ -160,15 +147,7 @@ do {                                                               \
  * @return
  *  0 on success, negative on error.
  */
-static inline int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
+int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to produce a PCI Bus-Device-Function value
@@ -182,16 +161,7 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
  * @return
  *  0 on success, negative on error.
  */
-static inline int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-#undef GET_PCIADDR_FIELD
+int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to write a pci device name, this device name can later be
@@ -205,17 +175,9 @@ eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
  * @param size
  *	The output buffer size
  */
-static inline void
-rte_pci_device_name(const struct rte_pci_addr *addr,
-		char *output, size_t size)
-{
-	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
-	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
-			    addr->domain, addr->bus,
-			    addr->devid, addr->function) >= 0);
-}
+void rte_pci_device_name(const struct rte_pci_addr *addr,
+			 char *output, size_t size);
 
-/* Compare two PCI device addresses. */
 /**
  * Utility function to compare two PCI device addresses.
  *
@@ -228,27 +190,8 @@ rte_pci_device_name(const struct rte_pci_addr *addr,
  *	Positive on addr is greater than addr2.
  *	Negative on addr is less than addr2, or error.
  */
-static inline int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			 const struct rte_pci_addr *addr2)
-{
-	uint64_t dev_addr, dev_addr2;
-
-	if ((addr == NULL) || (addr2 == NULL))
-		return -1;
-
-	dev_addr = ((uint64_t)addr->domain << 24) |
-		(addr->bus << 16) | (addr->devid << 8) | addr->function;
-	dev_addr2 = ((uint64_t)addr2->domain << 24) |
-		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
-
-	if (dev_addr > dev_addr2)
-		return 1;
-	else if (dev_addr < dev_addr2)
-		return -1;
-	else
-		return 0;
-}
+int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			     const struct rte_pci_addr *addr2);
 
 /**
  * Map a particular resource from a file.
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index 9dfdd3f..8584b55 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -53,6 +53,71 @@
 
 #include "rte_pci.h"
 
+/* Macro used by pci addr parsing functions. **/
+#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                     \
+do {                                                            \
+	unsigned long val;                                      \
+	char *end;                                              \
+	errno = 0;                                              \
+	val = strtoul((in), &end, 16);                          \
+	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
+		return -EINVAL;                                 \
+	(fd) = (typeof (fd))val;                                \
+	(in) = end + 1;                                         \
+} while(0)
+
+int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	dev_addr->domain = 0;
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+		    char *output, size_t size)
+{
+	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+			    addr->domain, addr->bus,
+			    addr->devid, addr->function) >= 0);
+}
+
+int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			 const struct rte_pci_addr *addr2)
+{
+	uint64_t dev_addr, dev_addr2;
+
+	if ((addr == NULL) || (addr2 == NULL))
+		return -1;
+
+	dev_addr = ((uint64_t)addr->domain << 24) |
+		(addr->bus << 16) | (addr->devid << 8) | addr->function;
+	dev_addr2 = ((uint64_t)addr2->domain << 24) |
+		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+	if (dev_addr > dev_addr2)
+		return 1;
+	else if (dev_addr < dev_addr2)
+		return -1;
+	else
+		return 0;
+}
+
 /* map a particular resource from a file */
 void *
 pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index 64dec54..a940259 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -1,8 +1,12 @@
 DPDK_17.11 {
 	global:
 
+	eal_parse_pci_BDF;
+	eal_parse_pci_DomBDF;
 	pci_map_resource;
 	pci_unmap_resource;
+	rte_eal_compare_pci_addr;
+	rte_pci_device_name;
 
 	local: *;
 };
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 11/16] pci: avoid over-complicated macro
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
                         ` (9 preceding siblings ...)
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 10/16] pci: avoid inlining functions Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 12/16] pci: deprecate misnamed functions Gaetan Rivet
                         ` (5 subsequent siblings)
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Using a macro helps writing the code to the detriment of the reader in
this case. This is backward. Write once, read many.

The few LOCs gained is not worth the opacity of the implementation.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_pci/rte_pci.c | 65 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 46 insertions(+), 19 deletions(-)

diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index 8584b55..cbb5359 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -53,36 +53,63 @@
 
 #include "rte_pci.h"
 
-/* Macro used by pci addr parsing functions. **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                     \
-do {                                                            \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
+static inline const char *
+get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
+{
+	unsigned long val;
+	uint8_t *u8 = _u8;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != dlm || val > UINT8_MAX) {
+		errno = errno ? errno : EINVAL;
+		return NULL;
+	}
+	*u8 = (uint8_t)val;
+	return end + 1;
+}
 
 int
 eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	const char *in = input;
+
 	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
 	return 0;
 }
 
 int
 eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
 {
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	const char *in = input;
+	unsigned long val;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != ':' || val > UINT16_MAX)
+		return -EINVAL;
+	dev_addr->domain = (uint16_t)val;
+	in = end + 1;
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
 	return 0;
 }
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 12/16] pci: deprecate misnamed functions
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
                         ` (10 preceding siblings ...)
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 11/16] pci: avoid over-complicated macro Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 13/16] pci: introduce PCI address parsing function Gaetan Rivet
                         ` (4 subsequent siblings)
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Rename misnamed functions and describe the change in a deprecation
notice.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst | 10 ++++++
 lib/librte_pci/include/rte_pci.h     | 63 ++++++++++++++++++++++++++++++++++++
 lib/librte_pci/rte_pci.c             | 26 +++++++++++++++
 lib/librte_pci/rte_pci_version.map   |  4 +++
 4 files changed, 103 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 4e4d97b..ef2264f 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -98,3 +98,13 @@ Deprecation Notices
   The non-"do-sig" versions of the hash tables will be removed
   (including the ``signature_offset`` parameter)
   and the "do-sig" versions renamed accordingly.
+
+* pci: Several exposed functions are misnamed.
+  The following functions are deprecated starting from v17.11 and are replaced:
+
+  - ``eal_parse_pci_BDF`` replaced by ``pci_parse_BDF``
+  - ``eal_parse_pci_DomBDF`` replaced by ``pci_parse_DomBDF``
+  - ``rte_eal_compare_pci_addr`` replaced by ``pci_addr_cmp``
+  - ``rte_pci_device_name`` replaced by ``pci_device_name``
+
+  The functions are only renamed. Their behavior is not affected.
diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
index fe4d411..38cbdb3 100644
--- a/lib/librte_pci/include/rte_pci.h
+++ b/lib/librte_pci/include/rte_pci.h
@@ -135,6 +135,7 @@ struct mapped_pci_resource {
 TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 
 /**
+ * @deprecated
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided without
  * a domain prefix (i.e. domain returned is always 0)
@@ -151,6 +152,22 @@ int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided without
+ * a domain prefix (i.e. domain returned is always 0)
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned.
+ *	Domain will always be returned as 0
+ * @return
+ *  0 on success, negative on error.
+ */
+int pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
+ * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided including
  * a domain prefix.
  *
@@ -164,6 +181,21 @@ int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided including
+ * a domain prefix.
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XXXX:XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned
+ * @return
+ *  0 on success, negative on error.
+ */
+int pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
  * Utility function to write a pci device name, this device name can later be
  * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
  * BDF helpers.
@@ -179,6 +211,22 @@ void rte_pci_device_name(const struct rte_pci_addr *addr,
 			 char *output, size_t size);
 
 /**
+ * Utility function to write a pci device name, this device name can later be
+ * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
+ * BDF helpers.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ */
+void pci_device_name(const struct rte_pci_addr *addr,
+		     char *output, size_t size);
+
+/**
+ * @deprecated
  * Utility function to compare two PCI device addresses.
  *
  * @param addr
@@ -194,6 +242,21 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 			     const struct rte_pci_addr *addr2);
 
 /**
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
+int pci_addr_cmp(const struct rte_pci_addr *addr,
+		 const struct rte_pci_addr *addr2);
+
+/**
  * Map a particular resource from a file.
  *
  * @param requested_addr
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index cbb5359..fc2fc7f 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -73,6 +73,12 @@ get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
 int
 eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	return pci_bdf_parse(input, dev_addr);
+}
+
+int
+pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
+{
 	const char *in = input;
 
 	dev_addr->domain = 0;
@@ -91,6 +97,12 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 int
 eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	return pci_dbdf_parse(input, dev_addr);
+}
+
+int
+pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
+{
 	const char *in = input;
 	unsigned long val;
 	char *end;
@@ -117,6 +129,13 @@ void
 rte_pci_device_name(const struct rte_pci_addr *addr,
 		    char *output, size_t size)
 {
+	pci_device_name(addr, output, size);
+}
+
+void
+pci_device_name(const struct rte_pci_addr *addr,
+		char *output, size_t size)
+{
 	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
 	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
 			    addr->domain, addr->bus,
@@ -127,6 +146,13 @@ int
 rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 			 const struct rte_pci_addr *addr2)
 {
+	return pci_addr_cmp(addr, addr2);
+}
+
+int
+pci_addr_cmp(const struct rte_pci_addr *addr,
+	     const struct rte_pci_addr *addr2)
+{
 	uint64_t dev_addr, dev_addr2;
 
 	if ((addr == NULL) || (addr2 == NULL))
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index a940259..8d180e3 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -3,6 +3,10 @@ DPDK_17.11 {
 
 	eal_parse_pci_BDF;
 	eal_parse_pci_DomBDF;
+	pci_addr_cmp;
+	pci_bdf_parse;
+	pci_dbdf_parse;
+	pci_device_name;
 	pci_map_resource;
 	pci_unmap_resource;
 	rte_eal_compare_pci_addr;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 13/16] pci: introduce PCI address parsing function
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
                         ` (11 preceding siblings ...)
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 12/16] pci: deprecate misnamed functions Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 14/16] pci: make specialized parsing functions private Gaetan Rivet
                         ` (3 subsequent siblings)
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

A new single function that is able to parse all currently supported
format:

   * Domain-Bus-Device-Function
   *        Bus-Device-Function

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_pci/include/rte_pci.h   | 15 +++++++++++++++
 lib/librte_pci/rte_pci.c           | 10 ++++++++++
 lib/librte_pci/rte_pci_version.map |  1 +
 3 files changed, 26 insertions(+)

diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
index 38cbdb3..9e79557 100644
--- a/lib/librte_pci/include/rte_pci.h
+++ b/lib/librte_pci/include/rte_pci.h
@@ -256,6 +256,21 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 int pci_addr_cmp(const struct rte_pci_addr *addr,
 		 const struct rte_pci_addr *addr2);
 
+
+/**
+ * Utility function to parse a string into a PCI location.
+ *
+ * @param str
+ *	The string to parse
+ * @param addr
+ *	The reference to the structure where the location
+ *	is stored.
+ * @return
+ *	0 on success
+ *	<0 otherwise
+ */
+int pci_addr_parse(const char *str, struct rte_pci_addr *addr);
+
 /**
  * Map a particular resource from a file.
  *
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index fc2fc7f..7ba472c 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -171,6 +171,16 @@ pci_addr_cmp(const struct rte_pci_addr *addr,
 		return 0;
 }
 
+int
+pci_addr_parse(const char *str, struct rte_pci_addr *addr)
+{
+	if (pci_bdf_parse(str, addr) == 0 ||
+	    pci_dbdf_parse(str, addr) == 0)
+		return 0;
+	return -1;
+}
+
+
 /* map a particular resource from a file */
 void *
 pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index 8d180e3..5f50f98 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -4,6 +4,7 @@ DPDK_17.11 {
 	eal_parse_pci_BDF;
 	eal_parse_pci_DomBDF;
 	pci_addr_cmp;
+	pci_addr_parse;
 	pci_bdf_parse;
 	pci_dbdf_parse;
 	pci_device_name;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 14/16] pci: make specialized parsing functions private
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
                         ` (12 preceding siblings ...)
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 13/16] pci: introduce PCI address parsing function Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 15/16] bus/pci: use new PCI addr parsing function Gaetan Rivet
                         ` (2 subsequent siblings)
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Do not expose the minute implementations of PCI parsing.
This leaves only the all-purpose pci_addr_parse, which is simpler to
use.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_pci/include/rte_pci.h   | 29 -----------------------------
 lib/librte_pci/rte_pci.c           | 28 ++++++++++++++--------------
 lib/librte_pci/rte_pci_version.map |  2 --
 3 files changed, 14 insertions(+), 45 deletions(-)

diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
index 9e79557..ea0897c 100644
--- a/lib/librte_pci/include/rte_pci.h
+++ b/lib/librte_pci/include/rte_pci.h
@@ -151,21 +151,6 @@ TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided without
- * a domain prefix (i.e. domain returned is always 0)
- *
- * @param input
- *	The input string to be parsed. Should have the format XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned.
- *	Domain will always be returned as 0
- * @return
- *  0 on success, negative on error.
- */
-int pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr);
-
-/**
  * @deprecated
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided including
@@ -181,20 +166,6 @@ int pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr);
 int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided including
- * a domain prefix.
- *
- * @param input
- *	The input string to be parsed. Should have the format XXXX:XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned
- * @return
- *  0 on success, negative on error.
- */
-int pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr);
-
-/**
  * @deprecated
  * Utility function to write a pci device name, this device name can later be
  * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index 7ba472c..1307a18 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -70,13 +70,7 @@ get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
 	return end + 1;
 }
 
-int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	return pci_bdf_parse(input, dev_addr);
-}
-
-int
+static int
 pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 {
 	const char *in = input;
@@ -94,13 +88,7 @@ pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 	return 0;
 }
 
-int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	return pci_dbdf_parse(input, dev_addr);
-}
-
-int
+static int
 pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 {
 	const char *in = input;
@@ -125,6 +113,18 @@ pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 	return 0;
 }
 
+int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	return pci_bdf_parse(input, dev_addr);
+}
+
+int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	return pci_dbdf_parse(input, dev_addr);
+}
+
 void
 rte_pci_device_name(const struct rte_pci_addr *addr,
 		    char *output, size_t size)
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index 5f50f98..b5c9ec2 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -5,8 +5,6 @@ DPDK_17.11 {
 	eal_parse_pci_DomBDF;
 	pci_addr_cmp;
 	pci_addr_parse;
-	pci_bdf_parse;
-	pci_dbdf_parse;
 	pci_device_name;
 	pci_map_resource;
 	pci_unmap_resource;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 15/16] bus/pci: use new PCI addr parsing function
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
                         ` (13 preceding siblings ...)
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 14/16] pci: make specialized parsing functions private Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 16/16] doc: add notes on EAL PCI API update Gaetan Rivet
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/bus/pci/pci_common.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index cd95d1a..d7a1c05 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -437,8 +437,7 @@ pci_parse(const char *name, void *addr)
 	struct rte_pci_addr pci_addr;
 	bool parse;
 
-	parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
-		 eal_parse_pci_DomBDF(name, &pci_addr) == 0);
+	parse = (pci_addr_parse(name, &pci_addr) == 0);
 	if (parse && addr != NULL)
 		*out = pci_addr;
 	return parse == false;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v4 16/16] doc: add notes on EAL PCI API update
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
                         ` (14 preceding siblings ...)
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 15/16] bus/pci: use new PCI addr parsing function Gaetan Rivet
@ 2017-10-12  8:17       ` Gaetan Rivet
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
  16 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12  8:17 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Add a section related to EAL API changes to 17.11 release notes.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/rel_notes/release_17_11.rst | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 63b9869..ed3d6d8 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -232,6 +232,34 @@ API Changes
   By this way PMDs can return an error value in case of failure at stats
   getting process time.
 
+* **PCI bus API moved outside of the EAL**
+
+  The PCI bus previously implemented within the EAL has been moved.
+  A first part has been added as an RTE library providing PCI helpers to
+  parse device locations or other such utilities.
+  A second part consisting in the actual bus driver has been moved to its
+  proper subdirectory, without changing its functionalities.
+
+  As such, several PCI-related functions are not proposed by the EAL anymore:
+
+  * rte_pci_detach
+  * rte_pci_dump
+  * rte_pci_ioport_map
+  * rte_pci_ioport_read
+  * rte_pci_ioport_unmap
+  * rte_pci_ioport_write
+  * rte_pci_map_device
+  * rte_pci_probe
+  * rte_pci_probe_one
+  * rte_pci_read_config
+  * rte_pci_register
+  * rte_pci_scan
+  * rte_pci_unmap_device
+  * rte_pci_unregister
+  * rte_pci_write_config
+
+  These functions are made available either as part of ``librte_pci`` or
+  ``librte_bus_pci``.
 
 ABI Changes
 -----------
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL
  2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
                         ` (15 preceding siblings ...)
  2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 16/16] doc: add notes on EAL PCI API update Gaetan Rivet
@ 2017-10-12 10:45       ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 01/20] eal: include debug header in bus source Gaetan Rivet
                           ` (20 more replies)
  16 siblings, 21 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Hi all,

Here is a new version of the PCI bus move out of the EAL.

The EAL PCI implementation is divided in two parts:

  - librte_pci: library offering helpers to handle PCI objects
  - librte_bus_pci: bus driver for PCI devices

This allows other libraries / tools to use PCI elements (location, mappings,
parsing operations, etc) without forcing a dependency on a bus driver.

The latter should not have to export helpers that others might need. It
is focused on defining the rte_pci_device, rte_pci_driver objects and
their handling.

The cryptodev library has hard dependencies on rte_pci_devices (used by
generic probe function). Other similar libs (ether and eventdev) avoided
the issue by inlining such functions and expecting users to include the
relevant headers once the PCI bus has already been built.

After review from Declan, he proposed to submit a patch removing this dependency.
Once this patch is submitted, the relevant commit will be dropped from this
patchset.

v2:

  + Made rte_eal_using_phys_addrs common to both linux and bsd interfaces.
  + Added documentation of EAL API changes in release note.
  + Fixed a few rebase-related mistakes.
  + Fixed parallel build race condition reported by Luca Boccassi.
  + Grouped together commits breaking compilation:

    -> pci: introduce PCI lib and bus
    -> lib: include rte_bus_pci
    -> drivers: include rte_bus_pci
    -> test: include rte_bus_pci
    -> app/testpmd: include rte_bus_pci
    -> cryptodev: move PCI specific helpers to drivers/crypto

  Until all of them have been applied, compilation is broken.
  I am currently wondering whether merging some of them might
  be sensible.

  + Not included in this series:

    Several filesystem-related functions are currently
    private to the EAL and directly linked. This is not good,
    but the solution seems to be to have a new lib offering an FS abstraction.
    This seems an overreach for this patchset and should probably come in a
    second step.

v3:

  + Fixed .map versioning
  + merged one commit breaking the build into the main commit moving
    code around.

    Other such commits are still present, as they only break specific subsystems
    (lib, drivers, apps, cryptodev). Merging them all within the one main commit
    does not seem right.

    As such, build is still broken from

       * pci: introduce PCI lib and bus

    until

       * cryptodev: move PCI specific helpers to drivers/crypto

v4:

  + Rebased unto master, with new PCI functionalities integrated.
  + Removed the exposition of private EAL functions.
    While one commit did deal with this for one function, the issue is more
    widespread and should be fixed in a more generic way.
  + Introduced new PCI address parsing function,
    deprecating the old ones.
  + Fix conflict with bonding PMD regarding pci_addr_cmp function name.

v5:

  + Rebase unto master: fix a few compilation issues with the header change.
  + Make more PCI bus functions private.

               ~*~

 Compilation is still broken from

    * pci: introduce PCI lib and bus

 until

    * net/bonding: use local prefix for local function

Gaetan Rivet (20):
  eal: include debug header in bus source
  ethdev: remove useless PCI dependency
  pci: introduce PCI lib and bus
  lib: include PCI bus header
  drivers: include PCI bus header
  test: include PCI bus header
  app/testpmd: include PCI bus header
  cryptodev: move PCI specific helpers to drivers/crypto
  net/bonding: use local prefix for local function
  pci: avoid inlining functions
  pci: avoid over-complicated macro
  pci: deprecate misnamed functions
  pci: introduce PCI address parsing function
  pci: make specialized parsing functions private
  bus/pci: use new PCI addr parsing function
  bus/pci: do not expose private functions
  bus/pci: do not expose PCI match function
  bus/pci: do not expose IOVA mode getter
  doc: add notes on EAL PCI API update
  bus: rename scan policy as probe policy

 app/test-pmd/testpmd.h                           |   1 +
 config/common_base                               |  10 +
 doc/guides/rel_notes/deprecation.rst             |  10 +
 doc/guides/rel_notes/release_17_11.rst           |  28 +
 drivers/bus/Makefile                             |   2 +
 drivers/bus/pci/Makefile                         |  59 ++
 drivers/bus/pci/bsd/Makefile                     |  32 +
 drivers/bus/pci/bsd/pci.c                        | 681 +++++++++++++++++++
 drivers/bus/pci/include/rte_bus_pci.h            | 350 ++++++++++
 drivers/bus/pci/linux/Makefile                   |  37 +
 drivers/bus/pci/linux/pci.c                      | 821 +++++++++++++++++++++++
 drivers/bus/pci/linux/pci_init.h                 |  97 +++
 drivers/bus/pci/linux/pci_uio.c                  | 568 ++++++++++++++++
 drivers/bus/pci/linux/pci_vfio.c                 | 757 +++++++++++++++++++++
 drivers/bus/pci/linux/vfio_mp_sync.c             | 426 ++++++++++++
 drivers/bus/pci/pci_common.c                     | 535 +++++++++++++++
 drivers/bus/pci/pci_common_uio.c                 | 235 +++++++
 drivers/bus/pci/private.h                        | 248 +++++++
 drivers/bus/pci/rte_bus_pci_version.map          |  17 +
 drivers/crypto/Makefile                          |   4 +-
 drivers/crypto/pci/Makefile                      |  52 ++
 drivers/crypto/pci/rte_cryptodev_pci.c           | 128 ++++
 drivers/crypto/pci/rte_cryptodev_pci.h           |  94 +++
 drivers/crypto/pci/rte_cryptodev_pci_version.map |   7 +
 drivers/crypto/qat/qat_qp.c                      |   1 +
 drivers/event/octeontx/ssovf_probe.c             |   1 +
 drivers/mempool/octeontx/octeontx_fpavf.c        |   2 +-
 drivers/net/ark/ark_ethdev.c                     |   1 +
 drivers/net/avp/avp_ethdev.c                     |   2 +
 drivers/net/bnxt/bnxt.h                          |   1 +
 drivers/net/bonding/rte_eth_bond_args.c          |   5 +-
 drivers/net/cxgbe/base/adapter.h                 |   1 +
 drivers/net/cxgbe/cxgbe_ethdev.c                 |   1 +
 drivers/net/e1000/em_ethdev.c                    |   1 +
 drivers/net/e1000/igb_ethdev.c                   |   1 +
 drivers/net/e1000/igb_pf.c                       |   1 +
 drivers/net/ena/ena_ethdev.h                     |   1 +
 drivers/net/enic/base/vnic_dev.h                 |   4 +-
 drivers/net/enic/enic_ethdev.c                   |   1 +
 drivers/net/enic/enic_main.c                     |   1 +
 drivers/net/i40e/i40e_ethdev.c                   |   1 +
 drivers/net/i40e/i40e_ethdev_vf.c                |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c                 |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.h                 |   1 +
 drivers/net/mlx4/mlx4_ethdev.c                   |   2 +-
 drivers/net/mlx5/mlx5.c                          |   1 +
 drivers/net/mlx5/mlx5_ethdev.c                   |   1 +
 drivers/net/nfp/nfp_nfpu.c                       |   2 +-
 drivers/net/nfp/nfp_nfpu.h                       |   2 +-
 drivers/net/octeontx/base/octeontx_pkivf.c       |   2 +-
 drivers/net/octeontx/base/octeontx_pkovf.c       |   2 +-
 drivers/net/sfc/sfc.h                            |   1 +
 drivers/net/sfc/sfc_ethdev.c                     |   1 +
 drivers/net/thunderx/nicvf_ethdev.c              |   1 +
 drivers/net/virtio/virtio_ethdev.c               |   1 +
 drivers/net/virtio/virtio_pci.h                  |   1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c             |   1 +
 lib/Makefile                                     |   2 +
 lib/librte_cryptodev/Makefile                    |   1 -
 lib/librte_cryptodev/rte_cryptodev_pci.h         |  92 ---
 lib/librte_cryptodev/rte_cryptodev_pmd.c         |  94 ---
 lib/librte_cryptodev/rte_cryptodev_version.map   |   2 -
 lib/librte_eal/bsdapp/eal/Makefile               |   3 -
 lib/librte_eal/bsdapp/eal/eal.c                  |   1 -
 lib/librte_eal/bsdapp/eal/eal_pci.c              | 680 -------------------
 lib/librte_eal/bsdapp/eal/rte_eal_version.map    |  17 -
 lib/librte_eal/common/Makefile                   |   2 +-
 lib/librte_eal/common/eal_common_bus.c           |   1 +
 lib/librte_eal/common/eal_common_devargs.c       |   6 +-
 lib/librte_eal/common/eal_common_pci.c           | 573 ----------------
 lib/librte_eal/common/eal_common_pci_uio.c       | 233 -------
 lib/librte_eal/common/eal_private.h              | 132 ----
 lib/librte_eal/common/include/rte_bus.h          |  12 +-
 lib/librte_eal/common/include/rte_pci.h          | 633 -----------------
 lib/librte_eal/linuxapp/eal/Makefile             |  10 -
 lib/librte_eal/linuxapp/eal/eal.c                |   1 -
 lib/librte_eal/linuxapp/eal/eal_interrupts.c     |   1 -
 lib/librte_eal/linuxapp/eal/eal_pci.c            | 818 ----------------------
 lib/librte_eal/linuxapp/eal/eal_pci_init.h       |  97 ---
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c        | 567 ----------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c       | 756 ---------------------
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c   | 425 ------------
 lib/librte_eal/linuxapp/eal/rte_eal_version.map  |  17 -
 lib/librte_ether/rte_ethdev.c                    |   1 -
 lib/librte_ether/rte_ethdev.h                    |   2 -
 lib/librte_ether/rte_ethdev_pci.h                |   1 +
 lib/librte_eventdev/rte_eventdev_pmd_pci.h       |   1 +
 lib/librte_pci/Makefile                          |  48 ++
 lib/librte_pci/include/rte_pci.h                 | 279 ++++++++
 lib/librte_pci/rte_pci.c                         | 220 ++++++
 lib/librte_pci/rte_pci_version.map               |  15 +
 mk/rte.app.mk                                    |   3 +
 test/test/test_kni.c                             |   1 +
 test/test/virtual_pmd.c                          |   1 +
 94 files changed, 5818 insertions(+), 5176 deletions(-)
 create mode 100644 drivers/bus/pci/Makefile
 create mode 100644 drivers/bus/pci/bsd/Makefile
 create mode 100644 drivers/bus/pci/bsd/pci.c
 create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
 create mode 100644 drivers/bus/pci/linux/Makefile
 create mode 100644 drivers/bus/pci/linux/pci.c
 create mode 100644 drivers/bus/pci/linux/pci_init.h
 create mode 100644 drivers/bus/pci/linux/pci_uio.c
 create mode 100644 drivers/bus/pci/linux/pci_vfio.c
 create mode 100644 drivers/bus/pci/linux/vfio_mp_sync.c
 create mode 100644 drivers/bus/pci/pci_common.c
 create mode 100644 drivers/bus/pci/pci_common_uio.c
 create mode 100644 drivers/bus/pci/private.h
 create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
 create mode 100644 drivers/crypto/pci/Makefile
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.c
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.h
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci_version.map
 delete mode 100644 lib/librte_cryptodev/rte_cryptodev_pci.h
 delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
 delete mode 100644 lib/librte_eal/common/include/rte_pci.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
 create mode 100644 lib/librte_pci/Makefile
 create mode 100644 lib/librte_pci/include/rte_pci.h
 create mode 100644 lib/librte_pci/rte_pci.c
 create mode 100644 lib/librte_pci/rte_pci_version.map

-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 01/20] eal: include debug header in bus source
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 02/20] ethdev: remove useless PCI dependency Gaetan Rivet
                           ` (19 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

This header is included through rte_pci.h, which will be removed once
the PCI bus is moved out of the EAL.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_bus.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
index c3c77f4..3c66a02 100644
--- a/lib/librte_eal/common/eal_common_bus.c
+++ b/lib/librte_eal/common/eal_common_bus.c
@@ -35,6 +35,7 @@
 #include <sys/queue.h>
 
 #include <rte_bus.h>
+#include <rte_debug.h>
 
 #include "eal_private.h"
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 02/20] ethdev: remove useless PCI dependency
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 01/20] eal: include debug header in bus source Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 03/20] pci: introduce PCI lib and bus Gaetan Rivet
                           ` (18 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ether/rte_ethdev.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 9460161..bb08204 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -47,7 +47,6 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_interrupts.h>
-#include <rte_pci.h>
 #include <rte_memory.h>
 #include <rte_memcpy.h>
 #include <rte_memzone.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 03/20] pci: introduce PCI lib and bus
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 01/20] eal: include debug header in bus source Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 02/20] ethdev: remove useless PCI dependency Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 04/20] lib: include PCI bus header Gaetan Rivet
                           ` (17 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

The PCI lib defines the types and methods allowing to use PCI elements.

The PCI bus implements a bus driver for PCI devices by constructing
rte_bus elements using the PCI lib.

Move the relevant code out of the EAL to its expected place.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 config/common_base                              |  10 +
 drivers/bus/Makefile                            |   2 +
 drivers/bus/pci/Makefile                        |  59 ++
 drivers/bus/pci/bsd/Makefile                    |  32 +
 drivers/bus/pci/bsd/pci.c                       | 680 ++++++++++++++++++++
 drivers/bus/pci/include/rte_bus_pci.h           | 415 ++++++++++++
 drivers/bus/pci/linux/Makefile                  |  37 ++
 drivers/bus/pci/linux/pci.c                     | 820 ++++++++++++++++++++++++
 drivers/bus/pci/linux/pci_init.h                |  97 +++
 drivers/bus/pci/linux/pci_uio.c                 | 567 ++++++++++++++++
 drivers/bus/pci/linux/pci_vfio.c                | 756 ++++++++++++++++++++++
 drivers/bus/pci/linux/vfio_mp_sync.c            | 425 ++++++++++++
 drivers/bus/pci/pci_common.c                    | 535 ++++++++++++++++
 drivers/bus/pci/pci_common_uio.c                | 234 +++++++
 drivers/bus/pci/private.h                       | 173 +++++
 drivers/bus/pci/rte_bus_pci_version.map         |  21 +
 lib/Makefile                                    |   2 +
 lib/librte_eal/bsdapp/eal/Makefile              |   3 -
 lib/librte_eal/bsdapp/eal/eal.c                 |   1 -
 lib/librte_eal/bsdapp/eal/eal_pci.c             | 680 --------------------
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  15 -
 lib/librte_eal/common/Makefile                  |   2 +-
 lib/librte_eal/common/eal_common_pci.c          | 573 -----------------
 lib/librte_eal/common/eal_common_pci_uio.c      | 233 -------
 lib/librte_eal/common/eal_private.h             | 132 ----
 lib/librte_eal/common/include/rte_pci.h         | 633 ------------------
 lib/librte_eal/linuxapp/eal/Makefile            |  10 -
 lib/librte_eal/linuxapp/eal/eal.c               |   1 -
 lib/librte_eal/linuxapp/eal/eal_interrupts.c    |   1 -
 lib/librte_eal/linuxapp/eal/eal_pci.c           | 818 -----------------------
 lib/librte_eal/linuxapp/eal/eal_pci_init.h      |  97 ---
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c       | 567 ----------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c      | 756 ----------------------
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c  | 425 ------------
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  15 -
 lib/librte_ether/rte_ethdev.h                   |   2 -
 lib/librte_pci/Makefile                         |  48 ++
 lib/librte_pci/include/rte_pci.h                | 287 +++++++++
 lib/librte_pci/rte_pci.c                        |  92 +++
 lib/librte_pci/rte_pci_version.map              |   8 +
 mk/rte.app.mk                                   |   3 +
 41 files changed, 5304 insertions(+), 4963 deletions(-)
 create mode 100644 drivers/bus/pci/Makefile
 create mode 100644 drivers/bus/pci/bsd/Makefile
 create mode 100644 drivers/bus/pci/bsd/pci.c
 create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
 create mode 100644 drivers/bus/pci/linux/Makefile
 create mode 100644 drivers/bus/pci/linux/pci.c
 create mode 100644 drivers/bus/pci/linux/pci_init.h
 create mode 100644 drivers/bus/pci/linux/pci_uio.c
 create mode 100644 drivers/bus/pci/linux/pci_vfio.c
 create mode 100644 drivers/bus/pci/linux/vfio_mp_sync.c
 create mode 100644 drivers/bus/pci/pci_common.c
 create mode 100644 drivers/bus/pci/pci_common_uio.c
 create mode 100644 drivers/bus/pci/private.h
 create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
 delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
 delete mode 100644 lib/librte_eal/common/include/rte_pci.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
 create mode 100644 lib/librte_pci/Makefile
 create mode 100644 lib/librte_pci/include/rte_pci.h
 create mode 100644 lib/librte_pci/rte_pci.c
 create mode 100644 lib/librte_pci/rte_pci_version.map

diff --git a/config/common_base b/config/common_base
index dc4da9a..39ec7f0 100644
--- a/config/common_base
+++ b/config/common_base
@@ -123,6 +123,11 @@ CONFIG_RTE_EAL_PMD_PATH=""
 CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
 
 #
+# Compile the PCI library
+#
+CONFIG_RTE_LIBRTE_PCI=y
+
+#
 # Compile the argument parser library
 #
 CONFIG_RTE_LIBRTE_KVARGS=y
@@ -148,6 +153,11 @@ CONFIG_RTE_ETHDEV_PROFILE_ITT_WASTED_RX_ITERATIONS=n
 CONFIG_RTE_ETHDEV_TX_PREPARE_NOOP=n
 
 #
+# Compile PCI bus driver
+#
+CONFIG_RTE_LIBRTE_PCI_BUS=y
+
+#
 # Compile burst-oriented Amazon ENA PMD driver
 #
 CONFIG_RTE_LIBRTE_ENA_PMD=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 6cb6466..40b9e96 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -37,5 +37,7 @@ DEPDIRS-dpaa = $(core-libs)
 
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 DEPDIRS-fslmc = $(core-libs)
+DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
+DEPDIRS-pci = $(core-libs)
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/pci/Makefile b/drivers/bus/pci/Makefile
new file mode 100644
index 0000000..2260dd4
--- /dev/null
+++ b/drivers/bus/pci/Makefile
@@ -0,0 +1,59 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+LIB = librte_bus_pci.a
+LIBABIVER := 1
+EXPORT_MAP := rte_bus_pci_version.map
+
+CFLAGS := -I$(SRCDIR)/include -I$(SRCDIR) $(CFLAGS)
+CFLAGS += -O3 $(WERROR_FLAGS)
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),)
+SYSTEM := linux
+endif
+ifneq ($(CONFIG_RTE_EXEC_ENV_BSDAPP),)
+SYSTEM := bsd
+endif
+
+CFLAGS += -I$(RTE_SDK)/drivers/bus/pci/$(SYSTEM)
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/$(SYSTEM)app/eal
+
+include $(RTE_SDK)/drivers/bus/pci/$(SYSTEM)/Makefile
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) := $(addprefix $(SYSTEM)/,$(SRCS))
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci_common.c
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci_common_uio.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI_BUS)-include += include/rte_bus_pci.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/pci/bsd/Makefile b/drivers/bus/pci/bsd/Makefile
new file mode 100644
index 0000000..4450913
--- /dev/null
+++ b/drivers/bus/pci/bsd/Makefile
@@ -0,0 +1,32 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += pci.c
diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
new file mode 100644
index 0000000..599519a
--- /dev/null
+++ b/drivers/bus/pci/bsd/pci.c
@@ -0,0 +1,680 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/pciio.h>
+#include <dev/pci/pcireg.h>
+
+#if defined(RTE_ARCH_X86)
+#include <machine/cpufunc.h>
+#endif
+
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_common.h>
+#include <rte_launch.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+#include <rte_debug.h>
+#include <rte_devargs.h>
+
+#include "eal_filesystem.h"
+#include "private.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in
+ * sysfs. Moreover, when a registered driver matches a device, the
+ * kernel driver currently using it is unloaded and replaced by
+ * igb_uio module, which is a very minimal userland driver for Intel
+ * network card, only providing access to PCI BAR to applications, and
+ * enabling bus master.
+ */
+
+extern struct rte_pci_bus rte_pci_bus;
+
+/* Map pci device */
+int
+rte_pci_map_device(struct rte_pci_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources */
+	switch (dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		/* map resources for devices that use uio */
+		ret = pci_uio_map_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+/* Unmap pci device */
+void
+rte_pci_unmap_device(struct rte_pci_device *dev)
+{
+	/* try unmapping the NIC resources */
+	switch (dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		/* unmap resources for devices that use uio */
+		pci_uio_unmap_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+void
+pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res)
+{
+	rte_free(uio_res);
+
+	if (dev->intr_handle.fd) {
+		close(dev->intr_handle.fd);
+		dev->intr_handle.fd = -1;
+		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	}
+}
+
+int
+pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res)
+{
+	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+
+	snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
+			dev->addr.bus, dev->addr.devid, dev->addr.function);
+
+	if (access(devname, O_RDWR) < 0) {
+		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+		return 1;
+	}
+
+	/* save fd if in primary process */
+	dev->intr_handle.fd = open(devname, O_RDWR);
+	if (dev->intr_handle.fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			devname, strerror(errno));
+		goto error;
+	}
+	dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+
+	/* allocate the mapping details for secondary processes*/
+	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
+	if (*uio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto error;
+	}
+
+	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
+	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
+
+	return 0;
+
+error:
+	pci_uio_free_resource(dev, *uio_res);
+	return -1;
+}
+
+int
+pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx)
+{
+	int fd;
+	char *devname;
+	void *mapaddr;
+	uint64_t offset;
+	uint64_t pagesz;
+	struct pci_map *maps;
+
+	maps = uio_res->maps;
+	devname = uio_res->path;
+	pagesz = sysconf(_SC_PAGESIZE);
+
+	/* allocate memory to keep path */
+	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+	if (maps[map_idx].path == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+				strerror(errno));
+		return -1;
+	}
+
+	/*
+	 * open resource file, to mmap it
+	 */
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				devname, strerror(errno));
+		goto error;
+	}
+
+	/* if matching map is found, then use it */
+	offset = res_idx * pagesz;
+	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
+			(size_t)dev->mem_resource[res_idx].len, 0);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		goto error;
+
+	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+	maps[map_idx].size = dev->mem_resource[res_idx].len;
+	maps[map_idx].addr = mapaddr;
+	maps[map_idx].offset = offset;
+	strcpy(maps[map_idx].path, devname);
+	dev->mem_resource[res_idx].addr = mapaddr;
+
+	return 0;
+
+error:
+	rte_free(maps[map_idx].path);
+	return -1;
+}
+
+static int
+pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
+{
+	struct rte_pci_device *dev;
+	struct pci_bar_io bar;
+	unsigned i, max;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL) {
+		return -1;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr.domain = conf->pc_sel.pc_domain;
+	dev->addr.bus = conf->pc_sel.pc_bus;
+	dev->addr.devid = conf->pc_sel.pc_dev;
+	dev->addr.function = conf->pc_sel.pc_func;
+
+	/* get vendor id */
+	dev->id.vendor_id = conf->pc_vendor;
+
+	/* get device id */
+	dev->id.device_id = conf->pc_device;
+
+	/* get subsystem_vendor id */
+	dev->id.subsystem_vendor_id = conf->pc_subvendor;
+
+	/* get subsystem_device id */
+	dev->id.subsystem_device_id = conf->pc_subdevice;
+
+	/* get class id */
+	dev->id.class_id = (conf->pc_class << 16) |
+			   (conf->pc_subclass << 8) |
+			   (conf->pc_progif);
+
+	/* TODO: get max_vfs */
+	dev->max_vfs = 0;
+
+	/* FreeBSD has no NUMA support (yet) */
+	dev->device.numa_node = 0;
+
+	pci_name_set(dev);
+
+	/* FreeBSD has only one pass through driver */
+	dev->kdrv = RTE_KDRV_NIC_UIO;
+
+	/* parse resources */
+	switch (conf->pc_hdr & PCIM_HDRTYPE) {
+	case PCIM_HDRTYPE_NORMAL:
+		max = PCIR_MAX_BAR_0;
+		break;
+	case PCIM_HDRTYPE_BRIDGE:
+		max = PCIR_MAX_BAR_1;
+		break;
+	case PCIM_HDRTYPE_CARDBUS:
+		max = PCIR_MAX_BAR_2;
+		break;
+	default:
+		goto skipdev;
+	}
+
+	for (i = 0; i <= max; i++) {
+		bar.pbi_sel = conf->pc_sel;
+		bar.pbi_reg = PCIR_BAR(i);
+		if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
+			continue;
+
+		dev->mem_resource[i].len = bar.pbi_length;
+		if (PCI_BAR_IO(bar.pbi_base)) {
+			dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
+			continue;
+		}
+		dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
+	}
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
+		rte_pci_add_device(dev);
+	}
+	else {
+		struct rte_pci_device *dev2 = NULL;
+		int ret;
+
+		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
+			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+			else if (ret < 0) {
+				rte_pci_insert_device(dev2, dev);
+			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->max_vfs = dev->max_vfs;
+				pci_name_set(dev2);
+				memmove(dev2->mem_resource,
+					dev->mem_resource,
+					sizeof(dev->mem_resource));
+				free(dev);
+			}
+			return 0;
+		}
+		rte_pci_add_device(dev);
+	}
+
+	return 0;
+
+skipdev:
+	free(dev);
+	return 0;
+}
+
+/*
+ * Scan the content of the PCI bus, and add the devices in the devices
+ * list. Call pci_scan_one() for each pci entry found.
+ */
+int
+rte_pci_scan(void)
+{
+	int fd;
+	unsigned dev_count = 0;
+	struct pci_conf matches[16];
+	struct pci_conf_io conf_io = {
+			.pat_buf_len = 0,
+			.num_patterns = 0,
+			.patterns = NULL,
+			.match_buf_len = sizeof(matches),
+			.matches = &matches[0],
+	};
+
+	/* for debug purposes, PCI can be disabled */
+	if (internal_config.no_pci)
+		return 0;
+
+	fd = open("/dev/pci", O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	do {
+		unsigned i;
+		if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+			RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+					__func__, strerror(errno));
+			goto error;
+		}
+
+		for (i = 0; i < conf_io.num_matches; i++)
+			if (pci_scan_one(fd, &matches[i]) < 0)
+				goto error;
+
+		dev_count += conf_io.num_matches;
+	} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
+
+	close(fd);
+
+	RTE_LOG(DEBUG, EAL, "PCI scan found %u devices\n", dev_count);
+	return 0;
+
+error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/*
+ * Get iommu class of PCI devices on the bus.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void)
+{
+	/* Supports only RTE_KDRV_NIC_UIO */
+	return RTE_IOVA_PA;
+}
+
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+	int fd;
+	struct pci_conf matches[2];
+	struct pci_match_conf match = {
+		.pc_sel = {
+			.pc_domain = addr->domain,
+			.pc_bus = addr->bus,
+			.pc_dev = addr->devid,
+			.pc_func = addr->function,
+		},
+	};
+	struct pci_conf_io conf_io = {
+		.pat_buf_len = 0,
+		.num_patterns = 1,
+		.patterns = &match,
+		.match_buf_len = sizeof(matches),
+		.matches = &matches[0],
+	};
+
+	fd = open("/dev/pci", O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+				__func__, strerror(errno));
+		goto error;
+	}
+
+	if (conf_io.num_matches != 1)
+		goto error;
+
+	if (pci_scan_one(fd, &matches[0]) < 0)
+		goto error;
+
+	close(fd);
+
+	return 0;
+
+error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/* Read PCI config space. */
+int rte_pci_read_config(const struct rte_pci_device *dev,
+		void *buf, size_t len, off_t offset)
+{
+	int fd = -1;
+	int size;
+	struct pci_io pi = {
+		.pi_sel = {
+			.pc_domain = dev->addr.domain,
+			.pc_bus = dev->addr.bus,
+			.pc_dev = dev->addr.devid,
+			.pc_func = dev->addr.function,
+		},
+		.pi_reg = offset,
+	};
+
+	fd = open("/dev/pci", O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	while (len > 0) {
+		size = (len >= 4) ? 4 : ((len >= 2) ? 2 : 1);
+		pi.pi_width = size;
+
+		if (ioctl(fd, PCIOCREAD, &pi) < 0)
+			goto error;
+		memcpy(buf, &pi.pi_data, size);
+
+		buf = (char *)buf + size;
+		pi.pi_reg += size;
+		len -= size;
+	}
+	close(fd);
+
+	return 0;
+
+ error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/* Write PCI config space. */
+int rte_pci_write_config(const struct rte_pci_device *dev,
+		const void *buf, size_t len, off_t offset)
+{
+	int fd = -1;
+
+	struct pci_io pi = {
+		.pi_sel = {
+			.pc_domain = dev->addr.domain,
+			.pc_bus = dev->addr.bus,
+			.pc_dev = dev->addr.devid,
+			.pc_func = dev->addr.function,
+		},
+		.pi_reg = offset,
+		.pi_data = *(const uint32_t *)buf,
+		.pi_width = len,
+	};
+
+	if (len == 3 || len > sizeof(pi.pi_data)) {
+		RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__);
+		goto error;
+	}
+
+	memcpy(&pi.pi_data, buf, len);
+
+	fd = open("/dev/pci", O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	if (ioctl(fd, PCIOCWRITE, &pi) < 0)
+		goto error;
+
+	close(fd);
+	return 0;
+
+ error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+int
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p)
+{
+	int ret;
+
+	switch (dev->kdrv) {
+#if defined(RTE_ARCH_X86)
+	case RTE_KDRV_NIC_UIO:
+		if ((uintptr_t) dev->mem_resource[bar].addr <= UINT16_MAX) {
+			p->base = (uintptr_t)dev->mem_resource[bar].addr;
+			ret = 0;
+		} else
+			ret = -1;
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	if (!ret)
+		p->dev = dev;
+
+	return ret;
+}
+
+static void
+pci_uio_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+#if defined(RTE_ARCH_X86)
+	uint8_t *d;
+	int size;
+	unsigned short reg = p->base + offset;
+
+	for (d = data; len > 0; d += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+			*(uint32_t *)d = inl(reg);
+		} else if (len >= 2) {
+			size = 2;
+			*(uint16_t *)d = inw(reg);
+		} else {
+			size = 1;
+			*d = inb(reg);
+		}
+	}
+#else
+	RTE_SET_USED(p);
+	RTE_SET_USED(data);
+	RTE_SET_USED(len);
+	RTE_SET_USED(offset);
+#endif
+}
+
+void
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+pci_uio_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+#if defined(RTE_ARCH_X86)
+	const uint8_t *s;
+	int size;
+	unsigned short reg = p->base + offset;
+
+	for (s = data; len > 0; s += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+			outl(reg, *(const uint32_t *)s);
+		} else if (len >= 2) {
+			size = 2;
+			outw(reg, *(const uint16_t *)s);
+		} else {
+			size = 1;
+			outb(reg, *s);
+		}
+	}
+#else
+	RTE_SET_USED(p);
+	RTE_SET_USED(data);
+	RTE_SET_USED(len);
+	RTE_SET_USED(offset);
+#endif
+}
+
+void
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	default:
+		break;
+	}
+}
+
+int
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
+{
+	int ret;
+
+	switch (p->dev->kdrv) {
+#if defined(RTE_ARCH_X86)
+	case RTE_KDRV_NIC_UIO:
+		ret = 0;
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/bus/pci/include/rte_bus_pci.h b/drivers/bus/pci/include/rte_bus_pci.h
new file mode 100644
index 0000000..e6a7998
--- /dev/null
+++ b/drivers/bus/pci/include/rte_bus_pci.h
@@ -0,0 +1,415 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_BUS_PCI_H_
+#define _RTE_BUS_PCI_H_
+
+/**
+ * @file
+ *
+ * RTE PCI Bus Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+
+/** Pathname of PCI devices directory. */
+const char *pci_get_sysfs_path(void);
+
+/* Forward declarations */
+struct rte_pci_device;
+struct rte_pci_driver;
+
+/** List of PCI devices */
+TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
+/** List of PCI drivers */
+TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
+
+/* PCI Bus iterators */
+#define FOREACH_DEVICE_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
+
+#define FOREACH_DRIVER_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
+
+struct rte_devargs;
+
+/**
+ * A structure describing a PCI device.
+ */
+struct rte_pci_device {
+	TAILQ_ENTRY(rte_pci_device) next;   /**< Next probed PCI device. */
+	struct rte_device device;           /**< Inherit core device */
+	struct rte_pci_addr addr;           /**< PCI location. */
+	struct rte_pci_id id;               /**< PCI ID. */
+	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
+					    /**< PCI Memory Resource */
+	struct rte_intr_handle intr_handle; /**< Interrupt handle */
+	struct rte_pci_driver *driver;      /**< Associated driver */
+	uint16_t max_vfs;                   /**< sriov enable if not zero */
+	enum rte_kernel_driver kdrv;        /**< Kernel driver passthrough */
+	char name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_pci_device.
+ */
+#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
+
+#define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
+
+/** Any PCI device identifier (vendor, device, ...) */
+#define PCI_ANY_ID (0xffff)
+#define RTE_CLASS_ANY_ID (0xffffff)
+
+#ifdef __cplusplus
+/** C++ macro used to help building up tables of device IDs */
+#define RTE_PCI_DEVICE(vend, dev) \
+	RTE_CLASS_ANY_ID,         \
+	(vend),                   \
+	(dev),                    \
+	PCI_ANY_ID,               \
+	PCI_ANY_ID
+#else
+/** Macro used to help building up tables of device IDs */
+#define RTE_PCI_DEVICE(vend, dev)          \
+	.class_id = RTE_CLASS_ANY_ID,      \
+	.vendor_id = (vend),               \
+	.device_id = (dev),                \
+	.subsystem_vendor_id = PCI_ANY_ID, \
+	.subsystem_device_id = PCI_ANY_ID
+#endif
+
+/**
+ * Initialisation function for the driver called during PCI probing.
+ */
+typedef int (pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
+
+/**
+ * Uninitialisation function for the driver called during hotplugging.
+ */
+typedef int (pci_remove_t)(struct rte_pci_device *);
+
+/**
+ * A structure describing a PCI driver.
+ */
+struct rte_pci_driver {
+	TAILQ_ENTRY(rte_pci_driver) next;  /**< Next in list. */
+	struct rte_driver driver;          /**< Inherit core driver. */
+	struct rte_pci_bus *bus;           /**< PCI bus reference. */
+	pci_probe_t *probe;                /**< Device Probe function. */
+	pci_remove_t *remove;              /**< Device Remove function. */
+	const struct rte_pci_id *id_table; /**< ID table, NULL terminated. */
+	uint32_t drv_flags;                /**< Flags contolling handling of device. */
+};
+
+/**
+ * Structure describing the PCI bus
+ */
+struct rte_pci_bus {
+	struct rte_bus bus;               /**< Inherit the generic class */
+	struct rte_pci_device_list device_list;  /**< List of PCI devices */
+	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
+};
+
+/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
+#define RTE_PCI_DRV_NEED_MAPPING 0x0001
+/** Device driver supports link state interrupt */
+#define RTE_PCI_DRV_INTR_LSC	0x0008
+/** Device driver supports device removal interrupt */
+#define RTE_PCI_DRV_INTR_RMV 0x0010
+/** Device driver needs to keep mapped resources if unsupported dev detected */
+#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
+/** Device driver supports IOVA as VA */
+#define RTE_PCI_DRV_IOVA_AS_VA 0X0040
+
+/**
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ *
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_pci_scan(void);
+
+/**
+ * Probe the PCI bus
+ *
+ * @return
+ *   - 0 on success.
+ *   - !0 on error.
+ */
+int
+rte_pci_probe(void);
+
+/*
+ * Match the PCI Driver and Device using the ID Table
+ *
+ * @param pci_drv
+ *      PCI driver from which ID table would be extracted
+ * @param pci_dev
+ *      PCI device to match against the driver
+ * @return
+ *      1 for successful match
+ *      0 for unsuccessful match
+ */
+int
+rte_pci_match(const struct rte_pci_driver *pci_drv,
+	      const struct rte_pci_device *pci_dev);
+
+
+/**
+ * Get iommu class of PCI devices on the bus.
+ * And return their preferred iova mapping mode.
+ *
+ * @return
+ *   - enum rte_iova_mode.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void);
+
+/**
+ * Map the PCI device resources in user space virtual memory address
+ *
+ * Note that driver should not call this function when flag
+ * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for
+ * you when it's on.
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ *
+ * @return
+ *   0 on success, negative on error and positive if no driver
+ *   is found for the device.
+ */
+int rte_pci_map_device(struct rte_pci_device *dev);
+
+/**
+ * Unmap this device
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ */
+void rte_pci_unmap_device(struct rte_pci_device *dev);
+
+/**
+ * Probe the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the probe() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to probe.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_probe_one(const struct rte_pci_addr *addr);
+
+/**
+ * Close the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the remove() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_detach(const struct rte_pci_addr *addr);
+
+/**
+ * Dump the content of the PCI bus.
+ *
+ * @param f
+ *   A pointer to a file for output
+ */
+void rte_pci_dump(FILE *f);
+
+/**
+ * Register a PCI driver.
+ *
+ * @param driver
+ *   A pointer to a rte_pci_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_pci_register(struct rte_pci_driver *driver);
+
+/** Helper for PCI device registration from driver (eth, crypto) instance */
+#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
+RTE_INIT(pciinitfn_ ##nm); \
+static void pciinitfn_ ##nm(void) \
+{\
+	(pci_drv).driver.name = RTE_STR(nm);\
+	rte_pci_register(&pci_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a PCI driver.
+ *
+ * @param driver
+ *   A pointer to a rte_pci_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_pci_unregister(struct rte_pci_driver *driver);
+
+/**
+ * Read PCI config space.
+ *
+ * @param device
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ * @param buf
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into PCI config space
+ */
+int rte_pci_read_config(const struct rte_pci_device *device,
+		void *buf, size_t len, off_t offset);
+
+/**
+ * Write PCI config space.
+ *
+ * @param device
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ * @param buf
+ *   A data buffer containing the bytes should be written
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into PCI config space
+ */
+int rte_pci_write_config(const struct rte_pci_device *device,
+		const void *buf, size_t len, off_t offset);
+
+/**
+ * A structure used to access io resources for a pci device.
+ * rte_pci_ioport is arch, os, driver specific, and should not be used outside
+ * of pci ioport api.
+ */
+struct rte_pci_ioport {
+	struct rte_pci_device *dev;
+	uint64_t base;
+	uint64_t len; /* only filled for memory mapped ports */
+};
+
+/**
+ * Initialize a rte_pci_ioport object for a pci device io resource.
+ *
+ * This object is then used to gain access to those io resources (see below).
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use.
+ * @param bar
+ *   Index of the io pci resource we want to access.
+ * @param p
+ *   The rte_pci_ioport object to be initialized.
+ * @return
+ *  0 on success, negative on error.
+ */
+int rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p);
+
+/**
+ * Release any resources used in a rte_pci_ioport object.
+ *
+ * @param p
+ *   The rte_pci_ioport object to be uninitialized.
+ * @return
+ *  0 on success, negative on error.
+ */
+int rte_pci_ioport_unmap(struct rte_pci_ioport *p);
+
+/**
+ * Read from a io pci resource.
+ *
+ * @param p
+ *   The rte_pci_ioport object from which we want to read.
+ * @param data
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into the pci io resource.
+ */
+void rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset);
+
+/**
+ * Write to a io pci resource.
+ *
+ * @param p
+ *   The rte_pci_ioport object to which we want to write.
+ * @param data
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into the pci io resource.
+ */
+void rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_BUS_PCI_H_ */
diff --git a/drivers/bus/pci/linux/Makefile b/drivers/bus/pci/linux/Makefile
new file mode 100644
index 0000000..5410566
--- /dev/null
+++ b/drivers/bus/pci/linux/Makefile
@@ -0,0 +1,37 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += pci.c
+SRCS += pci_uio.c
+SRCS += pci_vfio.c
+SRCS += vfio_mp_sync.c
+
+CFLAGS += -D_GNU_SOURCE
diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c
new file mode 100644
index 0000000..c1fcc56
--- /dev/null
+++ b/drivers/bus/pci/linux/pci.c
@@ -0,0 +1,820 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <dirent.h>
+
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+#include <rte_devargs.h>
+#include <rte_memcpy.h>
+
+#include "eal_private.h"
+#include "eal_filesystem.h"
+#include "eal_vfio.h"
+
+#include "private.h"
+#include "pci_init.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in sysfs.
+ * When a registered device matches a driver, it is then initialized with
+ * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
+ */
+
+extern struct rte_pci_bus rte_pci_bus;
+
+static int
+pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
+{
+	int count;
+	char path[PATH_MAX];
+	char *name;
+
+	if (!filename || !dri_name)
+		return -1;
+
+	count = readlink(filename, path, PATH_MAX);
+	if (count >= PATH_MAX)
+		return -1;
+
+	/* For device does not have a driver */
+	if (count < 0)
+		return 1;
+
+	path[count] = '\0';
+
+	name = strrchr(path, '/');
+	if (name) {
+		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
+		return 0;
+	}
+
+	return -1;
+}
+
+/* Map pci device */
+int
+rte_pci_map_device(struct rte_pci_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_map_resource(dev);
+#endif
+		break;
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+		if (rte_eal_using_phys_addrs()) {
+			/* map resources for devices that use uio */
+			ret = pci_uio_map_resource(dev);
+		}
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+/* Unmap pci device */
+void
+rte_pci_unmap_device(struct rte_pci_device *dev)
+{
+	/* try unmapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+		if (pci_vfio_is_enabled())
+			pci_vfio_unmap_resource(dev);
+#endif
+		break;
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+		/* unmap resources for devices that use uio */
+		pci_uio_unmap_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+void *
+pci_find_max_end_va(void)
+{
+	const struct rte_memseg *seg = rte_eal_get_physmem_layout();
+	const struct rte_memseg *last = seg;
+	unsigned i = 0;
+
+	for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
+		if (seg->addr == NULL)
+			break;
+
+		if (seg->addr > last->addr)
+			last = seg;
+
+	}
+	return RTE_PTR_ADD(last->addr, last->len);
+}
+
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int
+pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+	uint64_t *end_addr, uint64_t *flags)
+{
+	union pci_resource_info {
+		struct {
+			char *phys_addr;
+			char *end_addr;
+			char *flags;
+		};
+		char *ptrs[PCI_RESOURCE_FMT_NVAL];
+	} res_info;
+
+	if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
+		RTE_LOG(ERR, EAL,
+			"%s(): bad resource format\n", __func__);
+		return -1;
+	}
+	errno = 0;
+	*phys_addr = strtoull(res_info.phys_addr, NULL, 16);
+	*end_addr = strtoull(res_info.end_addr, NULL, 16);
+	*flags = strtoull(res_info.flags, NULL, 16);
+	if (errno != 0) {
+		RTE_LOG(ERR, EAL,
+			"%s(): bad resource format\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
+
+/* parse the "resource" sysfs file */
+static int
+pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
+{
+	FILE *f;
+	char buf[BUFSIZ];
+	int i;
+	uint64_t phys_addr, end_addr, flags;
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
+		return -1;
+	}
+
+	for (i = 0; i<PCI_MAX_RESOURCE; i++) {
+
+		if (fgets(buf, sizeof(buf), f) == NULL) {
+			RTE_LOG(ERR, EAL,
+				"%s(): cannot read resource\n", __func__);
+			goto error;
+		}
+		if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+				&end_addr, &flags) < 0)
+			goto error;
+
+		if (flags & IORESOURCE_MEM) {
+			dev->mem_resource[i].phys_addr = phys_addr;
+			dev->mem_resource[i].len = end_addr - phys_addr + 1;
+			/* not mapped for now */
+			dev->mem_resource[i].addr = NULL;
+		}
+	}
+	fclose(f);
+	return 0;
+
+error:
+	fclose(f);
+	return -1;
+}
+
+/* Scan one pci sysfs entry, and fill the devices list from it. */
+static int
+pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
+{
+	char filename[PATH_MAX];
+	unsigned long tmp;
+	struct rte_pci_device *dev;
+	char driver[PATH_MAX];
+	int ret;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL)
+		return -1;
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr = *addr;
+
+	/* get vendor id */
+	snprintf(filename, sizeof(filename), "%s/vendor", dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.vendor_id = (uint16_t)tmp;
+
+	/* get device id */
+	snprintf(filename, sizeof(filename), "%s/device", dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.device_id = (uint16_t)tmp;
+
+	/* get subsystem_vendor id */
+	snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.subsystem_vendor_id = (uint16_t)tmp;
+
+	/* get subsystem_device id */
+	snprintf(filename, sizeof(filename), "%s/subsystem_device",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.subsystem_device_id = (uint16_t)tmp;
+
+	/* get class_id */
+	snprintf(filename, sizeof(filename), "%s/class",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	/* the least 24 bits are valid: class, subclass, program interface */
+	dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
+
+	/* get max_vfs */
+	dev->max_vfs = 0;
+	snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
+	if (!access(filename, F_OK) &&
+	    eal_parse_sysfs_value(filename, &tmp) == 0)
+		dev->max_vfs = (uint16_t)tmp;
+	else {
+		/* for non igb_uio driver, need kernel version >= 3.8 */
+		snprintf(filename, sizeof(filename),
+			 "%s/sriov_numvfs", dirname);
+		if (!access(filename, F_OK) &&
+		    eal_parse_sysfs_value(filename, &tmp) == 0)
+			dev->max_vfs = (uint16_t)tmp;
+	}
+
+	/* get numa node, default to 0 if not present */
+	snprintf(filename, sizeof(filename), "%s/numa_node",
+		 dirname);
+
+	if (access(filename, F_OK) != -1) {
+		if (eal_parse_sysfs_value(filename, &tmp) == 0)
+			dev->device.numa_node = tmp;
+		else
+			dev->device.numa_node = -1;
+	} else {
+		dev->device.numa_node = 0;
+	}
+
+	pci_name_set(dev);
+
+	/* parse resources */
+	snprintf(filename, sizeof(filename), "%s/resource", dirname);
+	if (pci_parse_sysfs_resource(filename, dev) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
+		free(dev);
+		return -1;
+	}
+
+	/* parse driver */
+	snprintf(filename, sizeof(filename), "%s/driver", dirname);
+	ret = pci_get_kernel_driver_by_path(filename, driver);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
+		free(dev);
+		return -1;
+	}
+
+	if (!ret) {
+		if (!strcmp(driver, "vfio-pci"))
+			dev->kdrv = RTE_KDRV_VFIO;
+		else if (!strcmp(driver, "igb_uio"))
+			dev->kdrv = RTE_KDRV_IGB_UIO;
+		else if (!strcmp(driver, "uio_pci_generic"))
+			dev->kdrv = RTE_KDRV_UIO_GENERIC;
+		else
+			dev->kdrv = RTE_KDRV_UNKNOWN;
+	} else
+		dev->kdrv = RTE_KDRV_NONE;
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
+		rte_pci_add_device(dev);
+	} else {
+		struct rte_pci_device *dev2;
+		int ret;
+
+		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
+			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+
+			if (ret < 0) {
+				rte_pci_insert_device(dev2, dev);
+			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->max_vfs = dev->max_vfs;
+				pci_name_set(dev2);
+				memmove(dev2->mem_resource, dev->mem_resource,
+					sizeof(dev->mem_resource));
+				free(dev);
+			}
+			return 0;
+		}
+
+		rte_pci_add_device(dev);
+	}
+
+	return 0;
+}
+
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+	char filename[PATH_MAX];
+
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
+		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
+		 addr->function);
+
+	return pci_scan_one(filename, addr);
+}
+
+/*
+ * split up a pci address into its constituent parts.
+ */
+static int
+parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
+{
+	/* first split on ':' */
+	union splitaddr {
+		struct {
+			char *domain;
+			char *bus;
+			char *devid;
+			char *function;
+		};
+		char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
+	} splitaddr;
+
+	char *buf_copy = strndup(buf, bufsize);
+	if (buf_copy == NULL)
+		return -1;
+
+	if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
+			!= PCI_FMT_NVAL - 1)
+		goto error;
+	/* final split is on '.' between devid and function */
+	splitaddr.function = strchr(splitaddr.devid,'.');
+	if (splitaddr.function == NULL)
+		goto error;
+	*splitaddr.function++ = '\0';
+
+	/* now convert to int values */
+	errno = 0;
+	addr->domain = strtoul(splitaddr.domain, NULL, 16);
+	addr->bus = strtoul(splitaddr.bus, NULL, 16);
+	addr->devid = strtoul(splitaddr.devid, NULL, 16);
+	addr->function = strtoul(splitaddr.function, NULL, 10);
+	if (errno != 0)
+		goto error;
+
+	free(buf_copy); /* free the copy made with strdup */
+	return 0;
+error:
+	free(buf_copy);
+	return -1;
+}
+
+/*
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ */
+int
+rte_pci_scan(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+	struct rte_pci_addr addr;
+
+	/* for debug purposes, PCI can be disabled */
+	if (internal_config.no_pci)
+		return 0;
+
+	dir = opendir(pci_get_sysfs_path());
+	if (dir == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
+			continue;
+
+		snprintf(dirname, sizeof(dirname), "%s/%s",
+				pci_get_sysfs_path(), e->d_name);
+
+		if (pci_scan_one(dirname, &addr) < 0)
+			goto error;
+	}
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
+
+/*
+ * Is pci device bound to any kdrv
+ */
+static inline int
+pci_one_device_is_bound(void)
+{
+	struct rte_pci_device *dev = NULL;
+	int ret = 0;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (dev->kdrv == RTE_KDRV_UNKNOWN ||
+		    dev->kdrv == RTE_KDRV_NONE) {
+			continue;
+		} else {
+			ret = 1;
+			break;
+		}
+	}
+	return ret;
+}
+
+/*
+ * Any one of the device bound to uio
+ */
+static inline int
+pci_one_device_bound_uio(void)
+{
+	struct rte_pci_device *dev = NULL;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (dev->kdrv == RTE_KDRV_IGB_UIO ||
+		   dev->kdrv == RTE_KDRV_UIO_GENERIC) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * Any one of the device has iova as va
+ */
+static inline int
+pci_one_device_has_iova_va(void)
+{
+	struct rte_pci_device *dev = NULL;
+	struct rte_pci_driver *drv = NULL;
+
+	FOREACH_DRIVER_ON_PCIBUS(drv) {
+		if (drv && drv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) {
+			FOREACH_DEVICE_ON_PCIBUS(dev) {
+				if (dev->kdrv == RTE_KDRV_VFIO &&
+				    rte_pci_match(drv, dev))
+					return 1;
+			}
+		}
+	}
+	return 0;
+}
+
+/*
+ * Get iommu class of PCI devices on the bus.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void)
+{
+	bool is_bound;
+	bool is_vfio_noiommu_enabled = true;
+	bool has_iova_va;
+	bool is_bound_uio;
+
+	is_bound = pci_one_device_is_bound();
+	if (!is_bound)
+		return RTE_IOVA_DC;
+
+	has_iova_va = pci_one_device_has_iova_va();
+	is_bound_uio = pci_one_device_bound_uio();
+#ifdef VFIO_PRESENT
+	is_vfio_noiommu_enabled = vfio_noiommu_is_enabled() == true ?
+					true : false;
+#endif
+
+	if (has_iova_va && !is_bound_uio && !is_vfio_noiommu_enabled)
+		return RTE_IOVA_VA;
+
+	if (has_iova_va) {
+		RTE_LOG(WARNING, EAL, "Some devices want iova as va but pa will be used because.. ");
+		if (is_vfio_noiommu_enabled)
+			RTE_LOG(WARNING, EAL, "vfio-noiommu mode configured\n");
+		if (is_bound_uio)
+			RTE_LOG(WARNING, EAL, "few device bound to UIO\n");
+	}
+
+	return RTE_IOVA_PA;
+}
+
+/* Read PCI config space. */
+int rte_pci_read_config(const struct rte_pci_device *device,
+		void *buf, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &device->intr_handle;
+
+	switch (intr_handle->type) {
+	case RTE_INTR_HANDLE_UIO:
+	case RTE_INTR_HANDLE_UIO_INTX:
+		return pci_uio_read_config(intr_handle, buf, len, offset);
+
+#ifdef VFIO_PRESENT
+	case RTE_INTR_HANDLE_VFIO_MSIX:
+	case RTE_INTR_HANDLE_VFIO_MSI:
+	case RTE_INTR_HANDLE_VFIO_LEGACY:
+		return pci_vfio_read_config(intr_handle, buf, len, offset);
+#endif
+	default:
+		RTE_LOG(ERR, EAL,
+			"Unknown handle type of fd %d\n",
+					intr_handle->fd);
+		return -1;
+	}
+}
+
+/* Write PCI config space. */
+int rte_pci_write_config(const struct rte_pci_device *device,
+		const void *buf, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &device->intr_handle;
+
+	switch (intr_handle->type) {
+	case RTE_INTR_HANDLE_UIO:
+	case RTE_INTR_HANDLE_UIO_INTX:
+		return pci_uio_write_config(intr_handle, buf, len, offset);
+
+#ifdef VFIO_PRESENT
+	case RTE_INTR_HANDLE_VFIO_MSIX:
+	case RTE_INTR_HANDLE_VFIO_MSI:
+	case RTE_INTR_HANDLE_VFIO_LEGACY:
+		return pci_vfio_write_config(intr_handle, buf, len, offset);
+#endif
+	default:
+		RTE_LOG(ERR, EAL,
+			"Unknown handle type of fd %d\n",
+					intr_handle->fd);
+		return -1;
+	}
+}
+
+#if defined(RTE_ARCH_X86)
+static int
+pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
+		struct rte_pci_ioport *p)
+{
+	uint16_t start, end;
+	FILE *fp;
+	char *line = NULL;
+	char pci_id[16];
+	int found = 0;
+	size_t linesz;
+
+	snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
+		 dev->addr.domain, dev->addr.bus,
+		 dev->addr.devid, dev->addr.function);
+
+	fp = fopen("/proc/ioports", "r");
+	if (fp == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);
+		return -1;
+	}
+
+	while (getdelim(&line, &linesz, '\n', fp) > 0) {
+		char *ptr = line;
+		char *left;
+		int n;
+
+		n = strcspn(ptr, ":");
+		ptr[n] = 0;
+		left = &ptr[n + 1];
+
+		while (*left && isspace(*left))
+			left++;
+
+		if (!strncmp(left, pci_id, strlen(pci_id))) {
+			found = 1;
+
+			while (*ptr && isspace(*ptr))
+				ptr++;
+
+			sscanf(ptr, "%04hx-%04hx", &start, &end);
+
+			break;
+		}
+	}
+
+	free(line);
+	fclose(fp);
+
+	if (!found)
+		return -1;
+
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	p->base = start;
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
+
+	return 0;
+}
+#endif
+
+int
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p)
+{
+	int ret = -1;
+
+	switch (dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_ioport_map(dev, bar, p);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		ret = pci_uio_ioport_map(dev, bar, p);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+		ret = pci_ioport_map(dev, bar, p);
+#else
+		ret = pci_uio_ioport_map(dev, bar, p);
+#endif
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		ret = pci_ioport_map(dev, bar, p);
+#endif
+		break;
+	default:
+		break;
+	}
+
+	if (!ret)
+		p->dev = dev;
+
+	return ret;
+}
+
+void
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		pci_vfio_ioport_read(p, data, len, offset);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		pci_uio_ioport_read(p, data, len, offset);
+#endif
+		break;
+	default:
+		break;
+	}
+}
+
+void
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		pci_vfio_ioport_write(p, data, len, offset);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		pci_uio_ioport_write(p, data, len, offset);
+#endif
+		break;
+	default:
+		break;
+	}
+}
+
+int
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
+{
+	int ret = -1;
+
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_ioport_unmap(p);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		ret = pci_uio_ioport_unmap(p);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+		ret = 0;
+#else
+		ret = pci_uio_ioport_unmap(p);
+#endif
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		ret = 0;
+#endif
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/bus/pci/linux/pci_init.h b/drivers/bus/pci/linux/pci_init.h
new file mode 100644
index 0000000..ae2980d
--- /dev/null
+++ b/drivers/bus/pci/linux/pci_init.h
@@ -0,0 +1,97 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EAL_PCI_INIT_H_
+#define EAL_PCI_INIT_H_
+
+#include "eal_vfio.h"
+
+/** IO resource type: */
+#define IORESOURCE_IO         0x00000100
+#define IORESOURCE_MEM        0x00000200
+
+/*
+ * Helper function to map PCI resources right after hugepages in virtual memory
+ */
+extern void *pci_map_addr;
+void *pci_find_max_end_va(void);
+
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+	uint64_t *end_addr, uint64_t *flags);
+
+int pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res);
+void pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res);
+int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx);
+
+int pci_uio_read_config(const struct rte_intr_handle *intr_handle,
+			void *buf, size_t len, off_t offs);
+int pci_uio_write_config(const struct rte_intr_handle *intr_handle,
+			 const void *buf, size_t len, off_t offs);
+
+int pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		       struct rte_pci_ioport *p);
+void pci_uio_ioport_read(struct rte_pci_ioport *p,
+			 void *data, size_t len, off_t offset);
+void pci_uio_ioport_write(struct rte_pci_ioport *p,
+			  const void *data, size_t len, off_t offset);
+int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
+
+#ifdef VFIO_PRESENT
+
+/* access config space */
+int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
+			 void *buf, size_t len, off_t offs);
+int pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
+			  const void *buf, size_t len, off_t offs);
+
+int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
+		        struct rte_pci_ioport *p);
+void pci_vfio_ioport_read(struct rte_pci_ioport *p,
+			  void *data, size_t len, off_t offset);
+void pci_vfio_ioport_write(struct rte_pci_ioport *p,
+			   const void *data, size_t len, off_t offset);
+int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
+
+/* map/unmap VFIO resource prototype */
+int pci_vfio_map_resource(struct rte_pci_device *dev);
+int pci_vfio_unmap_resource(struct rte_pci_device *dev);
+
+#endif
+
+#endif /* EAL_PCI_INIT_H_ */
diff --git a/drivers/bus/pci/linux/pci_uio.c b/drivers/bus/pci/linux/pci_uio.c
new file mode 100644
index 0000000..d3f0556
--- /dev/null
+++ b/drivers/bus/pci/linux/pci_uio.c
@@ -0,0 +1,567 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/sysmacros.h>
+#include <linux/pci_regs.h>
+
+#if defined(RTE_ARCH_X86)
+#include <sys/io.h>
+#endif
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_common.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "pci_init.h"
+
+void *pci_map_addr = NULL;
+
+#define OFF_MAX              ((uint64_t)(off_t)-1)
+
+int
+pci_uio_read_config(const struct rte_intr_handle *intr_handle,
+		    void *buf, size_t len, off_t offset)
+{
+	return pread(intr_handle->uio_cfg_fd, buf, len, offset);
+}
+
+int
+pci_uio_write_config(const struct rte_intr_handle *intr_handle,
+		     const void *buf, size_t len, off_t offset)
+{
+	return pwrite(intr_handle->uio_cfg_fd, buf, len, offset);
+}
+
+static int
+pci_uio_set_bus_master(int dev_fd)
+{
+	uint16_t reg;
+	int ret;
+
+	ret = pread(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL,
+			"Cannot read command from PCI config space!\n");
+		return -1;
+	}
+
+	/* return if bus mastering is already on */
+	if (reg & PCI_COMMAND_MASTER)
+		return 0;
+
+	reg |= PCI_COMMAND_MASTER;
+
+	ret = pwrite(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL,
+			"Cannot write command to PCI config space!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
+{
+	FILE *f;
+	char filename[PATH_MAX];
+	int ret;
+	unsigned major, minor;
+	dev_t dev;
+
+	/* get the name of the sysfs file that contains the major and minor
+	 * of the uio device and read its content */
+	snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path);
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n",
+			__func__);
+		return -1;
+	}
+
+	ret = fscanf(f, "%u:%u", &major, &minor);
+	if (ret != 2) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n",
+			__func__);
+		fclose(f);
+		return -1;
+	}
+	fclose(f);
+
+	/* create the char device "mknod /dev/uioX c major minor" */
+	snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
+	dev = makedev(major, minor);
+	ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
+	if (ret != 0) {
+		RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	return ret;
+}
+
+/*
+ * Return the uioX char device used for a pci device. On success, return
+ * the UIO number and fill dstbuf string with the path of the device in
+ * sysfs. On error, return a negative value. In this case dstbuf is
+ * invalid.
+ */
+static int
+pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
+			   unsigned int buflen, int create)
+{
+	struct rte_pci_addr *loc = &dev->addr;
+	int uio_num = -1;
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+
+	/* depending on kernel version, uio can be located in uio/uioX
+	 * or uio:uioX */
+
+	snprintf(dirname, sizeof(dirname),
+			"%s/" PCI_PRI_FMT "/uio", pci_get_sysfs_path(),
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	dir = opendir(dirname);
+	if (dir == NULL) {
+		/* retry with the parent directory */
+		snprintf(dirname, sizeof(dirname),
+				"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
+				loc->domain, loc->bus, loc->devid, loc->function);
+		dir = opendir(dirname);
+
+		if (dir == NULL) {
+			RTE_LOG(ERR, EAL, "Cannot opendir %s\n", dirname);
+			return -1;
+		}
+	}
+
+	/* take the first file starting with "uio" */
+	while ((e = readdir(dir)) != NULL) {
+		/* format could be uio%d ...*/
+		int shortprefix_len = sizeof("uio") - 1;
+		/* ... or uio:uio%d */
+		int longprefix_len = sizeof("uio:uio") - 1;
+		char *endptr;
+
+		if (strncmp(e->d_name, "uio", 3) != 0)
+			continue;
+
+		/* first try uio%d */
+		errno = 0;
+		uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
+		if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
+			snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
+			break;
+		}
+
+		/* then try uio:uio%d */
+		errno = 0;
+		uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
+		if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
+			snprintf(dstbuf, buflen, "%s/uio:uio%u", dirname, uio_num);
+			break;
+		}
+	}
+	closedir(dir);
+
+	/* No uio resource found */
+	if (e == NULL)
+		return -1;
+
+	/* create uio device if we've been asked to */
+	if (internal_config.create_uio_dev && create &&
+			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
+		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
+
+	return uio_num;
+}
+
+void
+pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res)
+{
+	rte_free(uio_res);
+
+	if (dev->intr_handle.uio_cfg_fd >= 0) {
+		close(dev->intr_handle.uio_cfg_fd);
+		dev->intr_handle.uio_cfg_fd = -1;
+	}
+	if (dev->intr_handle.fd >= 0) {
+		close(dev->intr_handle.fd);
+		dev->intr_handle.fd = -1;
+		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	}
+}
+
+int
+pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res)
+{
+	char dirname[PATH_MAX];
+	char cfgname[PATH_MAX];
+	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	int uio_num;
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+
+	/* find uio resource */
+	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 1);
+	if (uio_num < 0) {
+		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+		return 1;
+	}
+	snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
+
+	/* save fd if in primary process */
+	dev->intr_handle.fd = open(devname, O_RDWR);
+	if (dev->intr_handle.fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			devname, strerror(errno));
+		goto error;
+	}
+
+	snprintf(cfgname, sizeof(cfgname),
+			"/sys/class/uio/uio%u/device/config", uio_num);
+	dev->intr_handle.uio_cfg_fd = open(cfgname, O_RDWR);
+	if (dev->intr_handle.uio_cfg_fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			cfgname, strerror(errno));
+		goto error;
+	}
+
+	if (dev->kdrv == RTE_KDRV_IGB_UIO)
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+	else {
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
+
+		/* set bus master that is not done by uio_pci_generic */
+		if (pci_uio_set_bus_master(dev->intr_handle.uio_cfg_fd)) {
+			RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
+			goto error;
+		}
+	}
+
+	/* allocate the mapping details for secondary processes*/
+	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
+	if (*uio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto error;
+	}
+
+	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
+	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
+
+	return 0;
+
+error:
+	pci_uio_free_resource(dev, *uio_res);
+	return -1;
+}
+
+int
+pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx)
+{
+	int fd;
+	char devname[PATH_MAX];
+	void *mapaddr;
+	struct rte_pci_addr *loc;
+	struct pci_map *maps;
+
+	loc = &dev->addr;
+	maps = uio_res->maps;
+
+	/* update devname for mmap  */
+	snprintf(devname, sizeof(devname),
+			"%s/" PCI_PRI_FMT "/resource%d",
+			pci_get_sysfs_path(),
+			loc->domain, loc->bus, loc->devid,
+			loc->function, res_idx);
+
+	/* allocate memory to keep path */
+	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+	if (maps[map_idx].path == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+				strerror(errno));
+		return -1;
+	}
+
+	/*
+	 * open resource file, to mmap it
+	 */
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				devname, strerror(errno));
+		goto error;
+	}
+
+	/* try mapping somewhere close to the end of hugepages */
+	if (pci_map_addr == NULL)
+		pci_map_addr = pci_find_max_end_va();
+
+	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
+			(size_t)dev->mem_resource[res_idx].len, 0);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		goto error;
+
+	pci_map_addr = RTE_PTR_ADD(mapaddr,
+			(size_t)dev->mem_resource[res_idx].len);
+
+	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+	maps[map_idx].size = dev->mem_resource[res_idx].len;
+	maps[map_idx].addr = mapaddr;
+	maps[map_idx].offset = 0;
+	strcpy(maps[map_idx].path, devname);
+	dev->mem_resource[res_idx].addr = mapaddr;
+
+	return 0;
+
+error:
+	rte_free(maps[map_idx].path);
+	return -1;
+}
+
+#if defined(RTE_ARCH_X86)
+int
+pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		   struct rte_pci_ioport *p)
+{
+	char dirname[PATH_MAX];
+	char filename[PATH_MAX];
+	int uio_num;
+	unsigned long start;
+
+	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 0);
+	if (uio_num < 0)
+		return -1;
+
+	/* get portio start */
+	snprintf(filename, sizeof(filename),
+		 "%s/portio/port%d/start", dirname, bar);
+	if (eal_parse_sysfs_value(filename, &start) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
+			__func__);
+		return -1;
+	}
+	/* ensure we don't get anything funny here, read/write will cast to
+	 * uin16_t */
+	if (start > UINT16_MAX)
+		return -1;
+
+	/* FIXME only for primary process ? */
+	if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {
+
+		snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
+		dev->intr_handle.fd = open(filename, O_RDWR);
+		if (dev->intr_handle.fd < 0) {
+			RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				filename, strerror(errno));
+			return -1;
+		}
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+	}
+
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);
+
+	p->base = start;
+	p->len = 0;
+	return 0;
+}
+#else
+int
+pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		   struct rte_pci_ioport *p)
+{
+	FILE *f;
+	char buf[BUFSIZ];
+	char filename[PATH_MAX];
+	uint64_t phys_addr, end_addr, flags;
+	int fd, i;
+	void *addr;
+
+	/* open and read addresses of the corresponding resource in sysfs */
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
+		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function);
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",
+			strerror(errno));
+		return -1;
+	}
+	for (i = 0; i < bar + 1; i++) {
+		if (fgets(buf, sizeof(buf), f) == NULL) {
+			RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");
+			goto error;
+		}
+	}
+	if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+			&end_addr, &flags) < 0)
+		goto error;
+	if ((flags & IORESOURCE_IO) == 0) {
+		RTE_LOG(ERR, EAL, "BAR %d is not an IO resource\n", bar);
+		goto error;
+	}
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
+		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function, bar);
+
+	/* mmap the pci resource */
+	fd = open(filename, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
+			strerror(errno));
+		goto error;
+	}
+	addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
+		MAP_SHARED, fd, 0);
+	close(fd);
+	if (addr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s\n",
+			strerror(errno));
+		goto error;
+	}
+
+	/* strangely, the base address is mmap addr + phys_addr */
+	p->base = (uintptr_t)addr + phys_addr;
+	p->len = end_addr + 1;
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"\n", p->base);
+	fclose(f);
+
+	return 0;
+
+error:
+	fclose(f);
+	return -1;
+}
+#endif
+
+void
+pci_uio_ioport_read(struct rte_pci_ioport *p,
+		    void *data, size_t len, off_t offset)
+{
+	uint8_t *d;
+	int size;
+	uintptr_t reg = p->base + offset;
+
+	for (d = data; len > 0; d += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+#if defined(RTE_ARCH_X86)
+			*(uint32_t *)d = inl(reg);
+#else
+			*(uint32_t *)d = *(volatile uint32_t *)reg;
+#endif
+		} else if (len >= 2) {
+			size = 2;
+#if defined(RTE_ARCH_X86)
+			*(uint16_t *)d = inw(reg);
+#else
+			*(uint16_t *)d = *(volatile uint16_t *)reg;
+#endif
+		} else {
+			size = 1;
+#if defined(RTE_ARCH_X86)
+			*d = inb(reg);
+#else
+			*d = *(volatile uint8_t *)reg;
+#endif
+		}
+	}
+}
+
+void
+pci_uio_ioport_write(struct rte_pci_ioport *p,
+		     const void *data, size_t len, off_t offset)
+{
+	const uint8_t *s;
+	int size;
+	uintptr_t reg = p->base + offset;
+
+	for (s = data; len > 0; s += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+#if defined(RTE_ARCH_X86)
+			outl_p(*(const uint32_t *)s, reg);
+#else
+			*(volatile uint32_t *)reg = *(const uint32_t *)s;
+#endif
+		} else if (len >= 2) {
+			size = 2;
+#if defined(RTE_ARCH_X86)
+			outw_p(*(const uint16_t *)s, reg);
+#else
+			*(volatile uint16_t *)reg = *(const uint16_t *)s;
+#endif
+		} else {
+			size = 1;
+#if defined(RTE_ARCH_X86)
+			outb_p(*s, reg);
+#else
+			*(volatile uint8_t *)reg = *s;
+#endif
+		}
+	}
+}
+
+int
+pci_uio_ioport_unmap(struct rte_pci_ioport *p)
+{
+#if defined(RTE_ARCH_X86)
+	RTE_SET_USED(p);
+	/* FIXME close intr fd ? */
+	return 0;
+#else
+	return munmap((void *)(uintptr_t)p->base, p->len);
+#endif
+}
diff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c
new file mode 100644
index 0000000..e69e4d3
--- /dev/null
+++ b/drivers/bus/pci/linux/pci_vfio.c
@@ -0,0 +1,756 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <fcntl.h>
+#include <linux/pci_regs.h>
+#include <sys/eventfd.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "pci_init.h"
+#include "eal_vfio.h"
+#include "private.h"
+
+/**
+ * @file
+ * PCI probing under linux (VFIO version)
+ *
+ * This code tries to determine if the PCI device is bound to VFIO driver,
+ * and initialize it (map BARs, set up interrupts) if that's the case.
+ *
+ * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
+ */
+
+#ifdef VFIO_PRESENT
+
+#define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
+#define PAGE_MASK   (~(PAGE_SIZE - 1))
+
+static struct rte_tailq_elem rte_vfio_tailq = {
+	.name = "VFIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_vfio_tailq)
+
+int
+pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
+		    void *buf, size_t len, off_t offs)
+{
+	return pread64(intr_handle->vfio_dev_fd, buf, len,
+	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
+}
+
+int
+pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
+		    const void *buf, size_t len, off_t offs)
+{
+	return pwrite64(intr_handle->vfio_dev_fd, buf, len,
+	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
+}
+
+/* get PCI BAR number where MSI-X interrupts are */
+static int
+pci_vfio_get_msix_bar(int fd, struct pci_msix_table *msix_table)
+{
+	int ret;
+	uint32_t reg;
+	uint16_t flags;
+	uint8_t cap_id, cap_offset;
+
+	/* read PCI capability pointer from config space */
+	ret = pread64(fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_CAPABILITY_LIST);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
+				"config space!\n");
+		return -1;
+	}
+
+	/* we need first byte */
+	cap_offset = reg & 0xFF;
+
+	while (cap_offset) {
+
+		/* read PCI capability ID */
+		ret = pread64(fd, &reg, sizeof(reg),
+				VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+				cap_offset);
+		if (ret != sizeof(reg)) {
+			RTE_LOG(ERR, EAL, "Cannot read capability ID from PCI "
+					"config space!\n");
+			return -1;
+		}
+
+		/* we need first byte */
+		cap_id = reg & 0xFF;
+
+		/* if we haven't reached MSI-X, check next capability */
+		if (cap_id != PCI_CAP_ID_MSIX) {
+			ret = pread64(fd, &reg, sizeof(reg),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset);
+			if (ret != sizeof(reg)) {
+				RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
+						"config space!\n");
+				return -1;
+			}
+
+			/* we need second byte */
+			cap_offset = (reg & 0xFF00) >> 8;
+
+			continue;
+		}
+		/* else, read table offset */
+		else {
+			/* table offset resides in the next 4 bytes */
+			ret = pread64(fd, &reg, sizeof(reg),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset + 4);
+			if (ret != sizeof(reg)) {
+				RTE_LOG(ERR, EAL, "Cannot read table offset from PCI config "
+						"space!\n");
+				return -1;
+			}
+
+			ret = pread64(fd, &flags, sizeof(flags),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset + 2);
+			if (ret != sizeof(flags)) {
+				RTE_LOG(ERR, EAL, "Cannot read table flags from PCI config "
+						"space!\n");
+				return -1;
+			}
+
+			msix_table->bar_index = reg & RTE_PCI_MSIX_TABLE_BIR;
+			msix_table->offset = reg & RTE_PCI_MSIX_TABLE_OFFSET;
+			msix_table->size =
+				16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE));
+
+			return 0;
+		}
+	}
+	return 0;
+}
+
+/* set PCI bus mastering */
+static int
+pci_vfio_set_bus_master(int dev_fd, bool op)
+{
+	uint16_t reg;
+	int ret;
+
+	ret = pread64(dev_fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n");
+		return -1;
+	}
+
+	if (op)
+		/* set the master bit */
+		reg |= PCI_COMMAND_MASTER;
+	else
+		reg &= ~(PCI_COMMAND_MASTER);
+
+	ret = pwrite64(dev_fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_COMMAND);
+
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* set up interrupt support (but not enable interrupts) */
+static int
+pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
+{
+	int i, ret, intr_idx;
+
+	/* default to invalid index */
+	intr_idx = VFIO_PCI_NUM_IRQS;
+
+	/* get interrupt type from internal config (MSI-X by default, can be
+	 * overridden from the command line
+	 */
+	switch (internal_config.vfio_intr_mode) {
+	case RTE_INTR_MODE_MSIX:
+		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
+		break;
+	case RTE_INTR_MODE_MSI:
+		intr_idx = VFIO_PCI_MSI_IRQ_INDEX;
+		break;
+	case RTE_INTR_MODE_LEGACY:
+		intr_idx = VFIO_PCI_INTX_IRQ_INDEX;
+		break;
+	/* don't do anything if we want to automatically determine interrupt type */
+	case RTE_INTR_MODE_NONE:
+		break;
+	default:
+		RTE_LOG(ERR, EAL, "  unknown default interrupt type!\n");
+		return -1;
+	}
+
+	/* start from MSI-X interrupt type */
+	for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) {
+		struct vfio_irq_info irq = { .argsz = sizeof(irq) };
+		int fd = -1;
+
+		/* skip interrupt modes we don't want */
+		if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE &&
+				i != intr_idx)
+			continue;
+
+		irq.index = i;
+
+		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  cannot get IRQ info, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+
+		/* if this vector cannot be used with eventfd, fail if we explicitly
+		 * specified interrupt type, otherwise continue */
+		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
+			if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE) {
+				RTE_LOG(ERR, EAL,
+						"  interrupt vector does not support eventfd!\n");
+				return -1;
+			} else
+				continue;
+		}
+
+		/* set up an eventfd for interrupts */
+		fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
+		if (fd < 0) {
+			RTE_LOG(ERR, EAL, "  cannot set up eventfd, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+
+		dev->intr_handle.fd = fd;
+		dev->intr_handle.vfio_dev_fd = vfio_dev_fd;
+
+		switch (i) {
+		case VFIO_PCI_MSIX_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSIX;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
+			break;
+		case VFIO_PCI_MSI_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSI;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
+			break;
+		case VFIO_PCI_INTX_IRQ_INDEX:
+			internal_config.vfio_intr_mode = RTE_INTR_MODE_LEGACY;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
+			break;
+		default:
+			RTE_LOG(ERR, EAL, "  unknown interrupt type!\n");
+			return -1;
+		}
+
+		return 0;
+	}
+
+	/* if we're here, we haven't found a suitable interrupt vector */
+	return -1;
+}
+
+static int
+pci_vfio_is_ioport_bar(int vfio_dev_fd, int bar_index)
+{
+	uint32_t ioport_bar;
+	int ret;
+
+	ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar),
+			  VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX)
+			  + PCI_BASE_ADDRESS_0 + bar_index*4);
+	if (ret != sizeof(ioport_bar)) {
+		RTE_LOG(ERR, EAL, "Cannot read command (%x) from config space!\n",
+			PCI_BASE_ADDRESS_0 + bar_index*4);
+		return -1;
+	}
+
+	return (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) != 0;
+}
+
+static int
+pci_vfio_setup_device(struct rte_pci_device *dev, int vfio_dev_fd)
+{
+	if (pci_vfio_setup_interrupts(dev, vfio_dev_fd) != 0) {
+		RTE_LOG(ERR, EAL, "Error setting up interrupts!\n");
+		return -1;
+	}
+
+	/* set bus mastering for the device */
+	if (pci_vfio_set_bus_master(vfio_dev_fd, true)) {
+		RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
+		return -1;
+	}
+
+	/* Reset the device */
+	ioctl(vfio_dev_fd, VFIO_DEVICE_RESET);
+
+	return 0;
+}
+
+static int
+pci_vfio_mmap_bar(int vfio_dev_fd, struct mapped_pci_resource *vfio_res,
+		int bar_index, int additional_flags)
+{
+	struct memreg {
+		unsigned long offset, size;
+	} memreg[2] = {};
+	void *bar_addr;
+	struct pci_msix_table *msix_table = &vfio_res->msix_table;
+	struct pci_map *bar = &vfio_res->maps[bar_index];
+
+	if (bar->size == 0)
+		/* Skip this BAR */
+		return 0;
+
+	if (msix_table->bar_index == bar_index) {
+		/*
+		 * VFIO will not let us map the MSI-X table,
+		 * but we can map around it.
+		 */
+		uint32_t table_start = msix_table->offset;
+		uint32_t table_end = table_start + msix_table->size;
+		table_end = (table_end + ~PAGE_MASK) & PAGE_MASK;
+		table_start &= PAGE_MASK;
+
+		if (table_start == 0 && table_end >= bar->size) {
+			/* Cannot map this BAR */
+			RTE_LOG(DEBUG, EAL, "Skipping BAR%d\n", bar_index);
+			bar->size = 0;
+			bar->addr = 0;
+			return 0;
+		}
+
+		memreg[0].offset = bar->offset;
+		memreg[0].size = table_start;
+		memreg[1].offset = bar->offset + table_end;
+		memreg[1].size = bar->size - table_end;
+
+		RTE_LOG(DEBUG, EAL,
+			"Trying to map BAR%d that contains the MSI-X "
+			"table. Trying offsets: "
+			"0x%04lx:0x%04lx, 0x%04lx:0x%04lx\n", bar_index,
+			memreg[0].offset, memreg[0].size,
+			memreg[1].offset, memreg[1].size);
+	} else {
+		memreg[0].offset = bar->offset;
+		memreg[0].size = bar->size;
+	}
+
+	/* reserve the address using an inaccessible mapping */
+	bar_addr = mmap(bar->addr, bar->size, 0, MAP_PRIVATE |
+			MAP_ANONYMOUS | additional_flags, -1, 0);
+	if (bar_addr != MAP_FAILED) {
+		void *map_addr = NULL;
+		if (memreg[0].size) {
+			/* actual map of first part */
+			map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
+							memreg[0].offset,
+							memreg[0].size,
+							MAP_FIXED);
+		}
+
+		/* if there's a second part, try to map it */
+		if (map_addr != MAP_FAILED
+			&& memreg[1].offset && memreg[1].size) {
+			void *second_addr = RTE_PTR_ADD(bar_addr,
+							memreg[1].offset -
+							(uintptr_t)bar->offset);
+			map_addr = pci_map_resource(second_addr,
+							vfio_dev_fd,
+							memreg[1].offset,
+							memreg[1].size,
+							MAP_FIXED);
+		}
+
+		if (map_addr == MAP_FAILED || !map_addr) {
+			munmap(bar_addr, bar->size);
+			bar_addr = MAP_FAILED;
+			RTE_LOG(ERR, EAL, "Failed to map pci BAR%d\n",
+					bar_index);
+			return -1;
+		}
+	} else {
+		RTE_LOG(ERR, EAL,
+				"Failed to create inaccessible mapping for BAR%d\n",
+				bar_index);
+		return -1;
+	}
+
+	bar->addr = bar_addr;
+	return 0;
+}
+
+static int
+pci_vfio_map_resource_primary(struct rte_pci_device *dev)
+{
+	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+	char pci_addr[PATH_MAX] = {0};
+	int vfio_dev_fd;
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list =
+		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+
+	struct pci_map *maps;
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
+					&vfio_dev_fd, &device_info);
+	if (ret)
+		return ret;
+
+	/* allocate vfio_res and get region info */
+	vfio_res = rte_zmalloc("VFIO_RES", sizeof(*vfio_res), 0);
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto err_vfio_dev_fd;
+	}
+	memcpy(&vfio_res->pci_addr, &dev->addr, sizeof(vfio_res->pci_addr));
+
+	/* get number of registers (up to BAR5) */
+	vfio_res->nb_maps = RTE_MIN((int) device_info.num_regions,
+			VFIO_PCI_BAR5_REGION_INDEX + 1);
+
+	/* map BARs */
+	maps = vfio_res->maps;
+
+	vfio_res->msix_table.bar_index = -1;
+	/* get MSI-X BAR, if any (we have to know where it is because we can't
+	 * easily mmap it when using VFIO)
+	 */
+	ret = pci_vfio_get_msix_bar(vfio_dev_fd, &vfio_res->msix_table);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "  %s cannot get MSI-X BAR number!\n",
+				pci_addr);
+		goto err_vfio_dev_fd;
+	}
+
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+		struct vfio_region_info reg = { .argsz = sizeof(reg) };
+		void *bar_addr;
+
+		reg.index = i;
+
+		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg);
+		if (ret) {
+			RTE_LOG(ERR, EAL, "  %s cannot get device region info "
+					"error %i (%s)\n", pci_addr, errno, strerror(errno));
+			goto err_vfio_res;
+		}
+
+		/* chk for io port region */
+		ret = pci_vfio_is_ioport_bar(vfio_dev_fd, i);
+		if (ret < 0)
+			goto err_vfio_res;
+		else if (ret) {
+			RTE_LOG(INFO, EAL, "Ignore mapping IO port bar(%d)\n",
+					i);
+			continue;
+		}
+
+		/* skip non-mmapable BARs */
+		if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0)
+			continue;
+
+		/* try mapping somewhere close to the end of hugepages */
+		if (pci_map_addr == NULL)
+			pci_map_addr = pci_find_max_end_va();
+
+		bar_addr = pci_map_addr;
+		pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
+
+		maps[i].addr = bar_addr;
+		maps[i].offset = reg.offset;
+		maps[i].size = reg.size;
+		maps[i].path = NULL; /* vfio doesn't have per-resource paths */
+
+		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, 0);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
+					pci_addr, i, strerror(errno));
+			goto err_vfio_res;
+		}
+
+		dev->mem_resource[i].addr = maps[i].addr;
+	}
+
+	if (pci_vfio_setup_device(dev, vfio_dev_fd) < 0) {
+		RTE_LOG(ERR, EAL, "  %s setup device failed\n", pci_addr);
+		goto err_vfio_res;
+	}
+
+	TAILQ_INSERT_TAIL(vfio_res_list, vfio_res, next);
+
+	return 0;
+err_vfio_res:
+	rte_free(vfio_res);
+err_vfio_dev_fd:
+	close(vfio_dev_fd);
+	return -1;
+}
+
+static int
+pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
+{
+	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+	char pci_addr[PATH_MAX] = {0};
+	int vfio_dev_fd;
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list =
+		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+
+	struct pci_map *maps;
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
+					&vfio_dev_fd, &device_info);
+	if (ret)
+		return ret;
+
+	/* if we're in a secondary process, just find our tailq entry */
+	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
+		if (rte_eal_compare_pci_addr(&vfio_res->pci_addr,
+						 &dev->addr))
+			continue;
+		break;
+	}
+	/* if we haven't found our tailq entry, something's wrong */
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
+				pci_addr);
+		goto err_vfio_dev_fd;
+	}
+
+	/* map BARs */
+	maps = vfio_res->maps;
+
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, MAP_FIXED);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
+					pci_addr, i, strerror(errno));
+			goto err_vfio_dev_fd;
+		}
+
+		dev->mem_resource[i].addr = maps[i].addr;
+	}
+
+	return 0;
+err_vfio_dev_fd:
+	close(vfio_dev_fd);
+	return -1;
+}
+
+/*
+ * map the PCI resources of a PCI device in virtual memory (VFIO version).
+ * primary and secondary processes follow almost exactly the same path
+ */
+int
+pci_vfio_map_resource(struct rte_pci_device *dev)
+{
+	if (internal_config.process_type == RTE_PROC_PRIMARY)
+		return pci_vfio_map_resource_primary(dev);
+	else
+		return pci_vfio_map_resource_secondary(dev);
+}
+
+int
+pci_vfio_unmap_resource(struct rte_pci_device *dev)
+{
+	char pci_addr[PATH_MAX] = {0};
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list;
+
+	struct pci_map *maps;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+
+	if (close(dev->intr_handle.fd) < 0) {
+		RTE_LOG(INFO, EAL, "Error when closing eventfd file descriptor for %s\n",
+			pci_addr);
+		return -1;
+	}
+
+	if (pci_vfio_set_bus_master(dev->intr_handle.vfio_dev_fd, false)) {
+		RTE_LOG(ERR, EAL, "  %s cannot unset bus mastering for PCI device!\n",
+				pci_addr);
+		return -1;
+	}
+
+	ret = vfio_release_device(pci_get_sysfs_path(), pci_addr,
+				  dev->intr_handle.vfio_dev_fd);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot release device\n", __func__);
+		return ret;
+	}
+
+	vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+	/* Get vfio_res */
+	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
+		if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
+			continue;
+		break;
+	}
+	/* if we haven't found our tailq entry, something's wrong */
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
+				pci_addr);
+		return -1;
+	}
+
+	/* unmap BARs */
+	maps = vfio_res->maps;
+
+	RTE_LOG(INFO, EAL, "Releasing pci mapped resource for %s\n",
+		pci_addr);
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+
+		/*
+		 * We do not need to be aware of MSI-X table BAR mappings as
+		 * when mapping. Just using current maps array is enough
+		 */
+		if (maps[i].addr) {
+			RTE_LOG(INFO, EAL, "Calling pci_unmap_resource for %s at %p\n",
+				pci_addr, maps[i].addr);
+			pci_unmap_resource(maps[i].addr, maps[i].size);
+		}
+	}
+
+	TAILQ_REMOVE(vfio_res_list, vfio_res, next);
+
+	return 0;
+}
+
+int
+pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
+		    struct rte_pci_ioport *p)
+{
+	if (bar < VFIO_PCI_BAR0_REGION_INDEX ||
+	    bar > VFIO_PCI_BAR5_REGION_INDEX) {
+		RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar);
+		return -1;
+	}
+
+	p->dev = dev;
+	p->base = VFIO_GET_REGION_ADDR(bar);
+	return 0;
+}
+
+void
+pci_vfio_ioport_read(struct rte_pci_ioport *p,
+		     void *data, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
+
+	if (pread64(intr_handle->vfio_dev_fd, data,
+		    len, p->base + offset) <= 0)
+		RTE_LOG(ERR, EAL,
+			"Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n",
+			VFIO_GET_REGION_IDX(p->base), (int)offset);
+}
+
+void
+pci_vfio_ioport_write(struct rte_pci_ioport *p,
+		      const void *data, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
+
+	if (pwrite64(intr_handle->vfio_dev_fd, data,
+		     len, p->base + offset) <= 0)
+		RTE_LOG(ERR, EAL,
+			"Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n",
+			VFIO_GET_REGION_IDX(p->base), (int)offset);
+}
+
+int
+pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
+{
+	RTE_SET_USED(p);
+	return -1;
+}
+
+int
+pci_vfio_enable(void)
+{
+	return vfio_enable("vfio_pci");
+}
+
+int
+pci_vfio_is_enabled(void)
+{
+	return vfio_is_enabled("vfio_pci");
+}
+#endif
diff --git a/drivers/bus/pci/linux/vfio_mp_sync.c b/drivers/bus/pci/linux/vfio_mp_sync.c
new file mode 100644
index 0000000..dd24e86
--- /dev/null
+++ b/drivers/bus/pci/linux/vfio_mp_sync.c
@@ -0,0 +1,425 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <pthread.h>
+
+/* sys/un.h with __USE_MISC uses strlen, which is unsafe */
+#ifdef __USE_MISC
+#define REMOVED_USE_MISC
+#undef __USE_MISC
+#endif
+#include <sys/un.h>
+/* make sure we redefine __USE_MISC only if it was previously undefined */
+#ifdef REMOVED_USE_MISC
+#define __USE_MISC
+#undef REMOVED_USE_MISC
+#endif
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "eal_thread.h"
+#include "pci_init.h"
+
+/**
+ * @file
+ * VFIO socket for communication between primary and secondary processes.
+ *
+ * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
+ */
+
+#ifdef VFIO_PRESENT
+
+#define SOCKET_PATH_FMT "%s/.%s_mp_socket"
+#define CMSGLEN (CMSG_LEN(sizeof(int)))
+#define FD_TO_CMSGHDR(fd, chdr) \
+		do {\
+			(chdr).cmsg_len = CMSGLEN;\
+			(chdr).cmsg_level = SOL_SOCKET;\
+			(chdr).cmsg_type = SCM_RIGHTS;\
+			memcpy((chdr).__cmsg_data, &(fd), sizeof(fd));\
+		} while (0)
+#define CMSGHDR_TO_FD(chdr, fd) \
+			memcpy(&(fd), (chdr).__cmsg_data, sizeof(fd))
+
+static pthread_t socket_thread;
+static int mp_socket_fd;
+
+
+/* get socket path (/var/run if root, $HOME otherwise) */
+static void
+get_socket_path(char *buffer, int bufsz)
+{
+	const char *dir = "/var/run";
+	const char *home_dir = getenv("HOME");
+
+	if (getuid() != 0 && home_dir != NULL)
+		dir = home_dir;
+
+	/* use current prefix as file path */
+	snprintf(buffer, bufsz, SOCKET_PATH_FMT, dir,
+			internal_config.hugefile_prefix);
+}
+
+
+
+/*
+ * data flow for socket comm protocol:
+ * 1. client sends SOCKET_REQ_CONTAINER or SOCKET_REQ_GROUP
+ * 1a. in case of SOCKET_REQ_GROUP, client also then sends group number
+ * 2. server receives message
+ * 2a. in case of invalid group, SOCKET_ERR is sent back to client
+ * 2b. in case of unbound group, SOCKET_NO_FD is sent back to client
+ * 2c. in case of valid group, SOCKET_OK is sent and immediately followed by fd
+ *
+ * in case of any error, socket is closed.
+ */
+
+/* send a request, return -1 on error */
+int
+vfio_mp_sync_send_request(int socket, int req)
+{
+	struct msghdr hdr;
+	struct iovec iov;
+	int buf;
+	int ret;
+
+	memset(&hdr, 0, sizeof(hdr));
+
+	buf = req;
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+
+	ret = sendmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+	return 0;
+}
+
+/* receive a request and return it */
+int
+vfio_mp_sync_receive_request(int socket)
+{
+	int buf;
+	struct msghdr hdr;
+	struct iovec iov;
+	int ret, req;
+
+	memset(&hdr, 0, sizeof(hdr));
+
+	buf = SOCKET_ERR;
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+
+	ret = recvmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+
+	req = buf;
+
+	return req;
+}
+
+/* send OK in message, fd in control message */
+int
+vfio_mp_sync_send_fd(int socket, int fd)
+{
+	int buf;
+	struct msghdr hdr;
+	struct cmsghdr *chdr;
+	char chdr_buf[CMSGLEN];
+	struct iovec iov;
+	int ret;
+
+	chdr = (struct cmsghdr *) chdr_buf;
+	memset(chdr, 0, sizeof(chdr_buf));
+	memset(&hdr, 0, sizeof(hdr));
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+	hdr.msg_control = chdr;
+	hdr.msg_controllen = CMSGLEN;
+
+	buf = SOCKET_OK;
+	FD_TO_CMSGHDR(fd, *chdr);
+
+	ret = sendmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+	return 0;
+}
+
+/* receive OK in message, fd in control message */
+int
+vfio_mp_sync_receive_fd(int socket)
+{
+	int buf;
+	struct msghdr hdr;
+	struct cmsghdr *chdr;
+	char chdr_buf[CMSGLEN];
+	struct iovec iov;
+	int ret, req, fd;
+
+	buf = SOCKET_ERR;
+
+	chdr = (struct cmsghdr *) chdr_buf;
+	memset(chdr, 0, sizeof(chdr_buf));
+	memset(&hdr, 0, sizeof(hdr));
+
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	iov.iov_base = (char *) &buf;
+	iov.iov_len = sizeof(buf);
+	hdr.msg_control = chdr;
+	hdr.msg_controllen = CMSGLEN;
+
+	ret = recvmsg(socket, &hdr, 0);
+	if (ret < 0)
+		return -1;
+
+	req = buf;
+
+	if (req != SOCKET_OK)
+		return -1;
+
+	CMSGHDR_TO_FD(*chdr, fd);
+
+	return fd;
+}
+
+/* connect socket_fd in secondary process to the primary process's socket */
+int
+vfio_mp_sync_connect_to_primary(void)
+{
+	struct sockaddr_un addr;
+	socklen_t sockaddr_len;
+	int socket_fd;
+
+	/* set up a socket */
+	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+	if (socket_fd < 0) {
+		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
+		return -1;
+	}
+
+	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
+	addr.sun_family = AF_UNIX;
+
+	sockaddr_len = sizeof(struct sockaddr_un);
+
+	if (connect(socket_fd, (struct sockaddr *) &addr, sockaddr_len) == 0)
+		return socket_fd;
+
+	/* if connect failed */
+	close(socket_fd);
+	return -1;
+}
+
+
+
+/*
+ * socket listening thread for primary process
+ */
+static __attribute__((noreturn)) void *
+vfio_mp_sync_thread(void __rte_unused * arg)
+{
+	int ret, fd, vfio_data;
+
+	/* wait for requests on the socket */
+	for (;;) {
+		int conn_sock;
+		struct sockaddr_un addr;
+		socklen_t sockaddr_len = sizeof(addr);
+
+		/* this is a blocking call */
+		conn_sock = accept(mp_socket_fd, (struct sockaddr *) &addr,
+				&sockaddr_len);
+
+		/* just restart on error */
+		if (conn_sock == -1)
+			continue;
+
+		/* set socket to linger after close */
+		struct linger l;
+		l.l_onoff = 1;
+		l.l_linger = 60;
+
+		if (setsockopt(conn_sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0)
+			RTE_LOG(WARNING, EAL, "Cannot set SO_LINGER option "
+					"on listen socket (%s)\n", strerror(errno));
+
+		ret = vfio_mp_sync_receive_request(conn_sock);
+
+		switch (ret) {
+		case SOCKET_REQ_CONTAINER:
+			fd = vfio_get_container_fd();
+			if (fd < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			else
+				vfio_mp_sync_send_fd(conn_sock, fd);
+			if (fd >= 0)
+				close(fd);
+			break;
+		case SOCKET_REQ_GROUP:
+			/* wait for group number */
+			vfio_data = vfio_mp_sync_receive_request(conn_sock);
+			if (vfio_data < 0) {
+				close(conn_sock);
+				continue;
+			}
+
+			fd = vfio_get_group_fd(vfio_data);
+
+			if (fd < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			/* if VFIO group exists but isn't bound to VFIO driver */
+			else if (fd == 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
+			/* if group exists and is bound to VFIO driver */
+			else {
+				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
+				vfio_mp_sync_send_fd(conn_sock, fd);
+			}
+			break;
+		case SOCKET_CLR_GROUP:
+			/* wait for group fd */
+			vfio_data = vfio_mp_sync_receive_request(conn_sock);
+			if (vfio_data < 0) {
+				close(conn_sock);
+				continue;
+			}
+
+			ret = clear_group(vfio_data);
+
+			if (ret < 0)
+				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
+			else
+				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
+			break;
+		default:
+			vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
+			break;
+		}
+		close(conn_sock);
+	}
+}
+
+static int
+vfio_mp_sync_socket_setup(void)
+{
+	int ret, socket_fd;
+	struct sockaddr_un addr;
+	socklen_t sockaddr_len;
+
+	/* set up a socket */
+	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+	if (socket_fd < 0) {
+		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
+		return -1;
+	}
+
+	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
+	addr.sun_family = AF_UNIX;
+
+	sockaddr_len = sizeof(struct sockaddr_un);
+
+	unlink(addr.sun_path);
+
+	ret = bind(socket_fd, (struct sockaddr *) &addr, sockaddr_len);
+	if (ret) {
+		RTE_LOG(ERR, EAL, "Failed to bind socket: %s!\n", strerror(errno));
+		close(socket_fd);
+		return -1;
+	}
+
+	ret = listen(socket_fd, 50);
+	if (ret) {
+		RTE_LOG(ERR, EAL, "Failed to listen: %s!\n", strerror(errno));
+		close(socket_fd);
+		return -1;
+	}
+
+	/* save the socket in local configuration */
+	mp_socket_fd = socket_fd;
+
+	return 0;
+}
+
+/*
+ * set up a local socket and tell it to listen for incoming connections
+ */
+int
+vfio_mp_sync_setup(void)
+{
+	int ret;
+	char thread_name[RTE_MAX_THREAD_NAME_LEN];
+
+	if (vfio_mp_sync_socket_setup() < 0) {
+		RTE_LOG(ERR, EAL, "Failed to set up local socket!\n");
+		return -1;
+	}
+
+	ret = pthread_create(&socket_thread, NULL,
+			vfio_mp_sync_thread, NULL);
+	if (ret) {
+		RTE_LOG(ERR, EAL,
+			"Failed to create thread for communication with secondary processes!\n");
+		close(mp_socket_fd);
+		return -1;
+	}
+
+	/* Set thread_name for aid in debugging. */
+	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "vfio-sync");
+	ret = rte_thread_setname(socket_thread, thread_name);
+	if (ret)
+		RTE_LOG(DEBUG, EAL,
+			"Failed to set thread name for secondary processes!\n");
+
+	return 0;
+}
+
+#endif
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
new file mode 100644
index 0000000..7b68e99
--- /dev/null
+++ b/drivers/bus/pci/pci_common.c
@@ -0,0 +1,535 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+
+#include "private.h"
+
+extern struct rte_pci_bus rte_pci_bus;
+
+#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
+
+const char *pci_get_sysfs_path(void)
+{
+	const char *path = NULL;
+
+	path = getenv("SYSFS_PCI_DEVICES");
+	if (path == NULL)
+		return SYSFS_PCI_DEVICES;
+
+	return path;
+}
+
+static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
+{
+	struct rte_devargs *devargs;
+	struct rte_pci_addr addr;
+	struct rte_bus *pbus;
+
+	pbus = rte_bus_find_by_name("pci");
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->bus != pbus)
+			continue;
+		devargs->bus->parse(devargs->name, &addr);
+		if (!rte_eal_compare_pci_addr(&dev->addr, &addr))
+			return devargs;
+	}
+	return NULL;
+}
+
+void
+pci_name_set(struct rte_pci_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	/* Each device has its internal, canonical name set. */
+	rte_pci_device_name(&dev->addr,
+			dev->name, sizeof(dev->name));
+	devargs = pci_devargs_lookup(dev);
+	dev->device.devargs = devargs;
+	/* In blacklist mode, if the device is not blacklisted, no
+	 * rte_devargs exists for it.
+	 */
+	if (devargs != NULL)
+		/* If an rte_devargs exists, the generic rte_device uses the
+		 * given name as its namea
+		 */
+		dev->device.name = dev->device.devargs->name;
+	else
+		/* Otherwise, it uses the internal, canonical form. */
+		dev->device.name = dev->name;
+}
+
+/*
+ * Match the PCI Driver and Device using the ID Table
+ */
+int
+rte_pci_match(const struct rte_pci_driver *pci_drv,
+	      const struct rte_pci_device *pci_dev)
+{
+	const struct rte_pci_id *id_table;
+
+	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
+	     id_table++) {
+		/* check if device's identifiers match the driver's ones */
+		if (id_table->vendor_id != pci_dev->id.vendor_id &&
+				id_table->vendor_id != PCI_ANY_ID)
+			continue;
+		if (id_table->device_id != pci_dev->id.device_id &&
+				id_table->device_id != PCI_ANY_ID)
+			continue;
+		if (id_table->subsystem_vendor_id !=
+		    pci_dev->id.subsystem_vendor_id &&
+		    id_table->subsystem_vendor_id != PCI_ANY_ID)
+			continue;
+		if (id_table->subsystem_device_id !=
+		    pci_dev->id.subsystem_device_id &&
+		    id_table->subsystem_device_id != PCI_ANY_ID)
+			continue;
+		if (id_table->class_id != pci_dev->id.class_id &&
+				id_table->class_id != RTE_CLASS_ANY_ID)
+			continue;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * If vendor/device ID match, call the probe() function of the
+ * driver.
+ */
+static int
+rte_pci_probe_one_driver(struct rte_pci_driver *dr,
+			 struct rte_pci_device *dev)
+{
+	int ret;
+	struct rte_pci_addr *loc;
+
+	if ((dr == NULL) || (dev == NULL))
+		return -EINVAL;
+
+	loc = &dev->addr;
+
+	/* The device is not blacklisted; Check if driver supports it */
+	if (!rte_pci_match(dr, dev))
+		/* Match of device and driver failed */
+		return 1;
+
+	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			loc->domain, loc->bus, loc->devid, loc->function,
+			dev->device.numa_node);
+
+	/* no initialization when blacklisted, return without error */
+	if (dev->device.devargs != NULL &&
+		dev->device.devargs->policy ==
+			RTE_DEV_BLACKLISTED) {
+		RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
+			" initializing\n");
+		return 1;
+	}
+
+	if (dev->device.numa_node < 0) {
+		RTE_LOG(WARNING, EAL, "  Invalid NUMA socket, default to 0\n");
+		dev->device.numa_node = 0;
+	}
+
+	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
+		dev->id.device_id, dr->driver.name);
+
+	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+		/* map resources for devices that use igb_uio */
+		ret = rte_pci_map_device(dev);
+		if (ret != 0)
+			return ret;
+	}
+
+	/* reference driver structure */
+	dev->driver = dr;
+	dev->device.driver = &dr->driver;
+
+	/* call the driver probe() function */
+	ret = dr->probe(dr, dev);
+	if (ret) {
+		dev->driver = NULL;
+		dev->device.driver = NULL;
+		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
+			/* Don't unmap if device is unsupported and
+			 * driver needs mapped resources.
+			 */
+			!(ret > 0 &&
+				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
+			rte_pci_unmap_device(dev);
+	}
+
+	return ret;
+}
+
+/*
+ * If vendor/device ID match, call the remove() function of the
+ * driver.
+ */
+static int
+rte_pci_detach_dev(struct rte_pci_device *dev)
+{
+	struct rte_pci_addr *loc;
+	struct rte_pci_driver *dr;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	dr = dev->driver;
+	loc = &dev->addr;
+
+	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			loc->domain, loc->bus, loc->devid,
+			loc->function, dev->device.numa_node);
+
+	RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
+			dev->id.device_id, dr->driver.name);
+
+	if (dr->remove && (dr->remove(dev) < 0))
+		return -1;	/* negative value is an error */
+
+	/* clear driver structure */
+	dev->driver = NULL;
+
+	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
+		/* unmap resources for devices that use igb_uio */
+		rte_pci_unmap_device(dev);
+
+	return 0;
+}
+
+/*
+ * If vendor/device ID match, call the probe() function of all
+ * registered driver for the given device. Return -1 if initialization
+ * failed, return 1 if no driver is found for this device.
+ */
+static int
+pci_probe_all_drivers(struct rte_pci_device *dev)
+{
+	struct rte_pci_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	/* Check if a driver is already loaded */
+	if (dev->driver != NULL)
+		return 0;
+
+	FOREACH_DRIVER_ON_PCIBUS(dr) {
+		rc = rte_pci_probe_one_driver(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * Find the pci device specified by pci address, then invoke probe function of
+ * the driver of the device.
+ */
+int
+rte_pci_probe_one(const struct rte_pci_addr *addr)
+{
+	struct rte_pci_device *dev = NULL;
+
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	/* update current pci device in global list, kernel bindings might have
+	 * changed since last time we looked at it.
+	 */
+	if (pci_update_device(addr) < 0)
+		goto err_return;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (rte_eal_compare_pci_addr(&dev->addr, addr))
+			continue;
+
+		ret = pci_probe_all_drivers(dev);
+		if (ret)
+			goto err_return;
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL,
+		"Requested device " PCI_PRI_FMT " cannot be used\n",
+		addr->domain, addr->bus, addr->devid, addr->function);
+	return -1;
+}
+
+/*
+ * Detach device specified by its pci address.
+ */
+int
+rte_pci_detach(const struct rte_pci_addr *addr)
+{
+	struct rte_pci_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (rte_eal_compare_pci_addr(&dev->addr, addr))
+			continue;
+
+		ret = rte_pci_detach_dev(dev);
+		if (ret < 0)
+			/* negative value is an error */
+			goto err_return;
+		if (ret > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+
+		rte_pci_remove_device(dev);
+		free(dev);
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
+			" cannot be used\n", dev->addr.domain, dev->addr.bus,
+			dev->addr.devid, dev->addr.function);
+	return -1;
+}
+
+/*
+ * Scan the content of the PCI bus, and call the probe() function for
+ * all registered drivers that have a matching entry in its id_table
+ * for discovered devices.
+ */
+int
+rte_pci_probe(void)
+{
+	struct rte_pci_device *dev = NULL;
+	size_t probed = 0, failed = 0;
+	struct rte_devargs *devargs;
+	int probe_all = 0;
+	int ret = 0;
+
+	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
+		probe_all = 1;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		probed++;
+
+		devargs = dev->device.devargs;
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = pci_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->policy == RTE_DEV_WHITELISTED)
+			ret = pci_probe_all_drivers(dev);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
+				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
+				 dev->addr.devid, dev->addr.function);
+			rte_errno = errno;
+			failed++;
+			ret = 0;
+		}
+	}
+
+	return (probed && probed == failed) ? -1 : 0;
+}
+
+/* dump one device */
+static int
+pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
+{
+	int i;
+
+	fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
+	       dev->addr.devid, dev->addr.function);
+	fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
+	       dev->id.device_id);
+
+	for (i = 0; i != sizeof(dev->mem_resource) /
+		sizeof(dev->mem_resource[0]); i++) {
+		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
+			dev->mem_resource[i].phys_addr,
+			dev->mem_resource[i].len);
+	}
+	return 0;
+}
+
+/* dump devices on the bus */
+void
+rte_pci_dump(FILE *f)
+{
+	struct rte_pci_device *dev = NULL;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		pci_dump_one_device(f, dev);
+	}
+}
+
+static int
+pci_parse(const char *name, void *addr)
+{
+	struct rte_pci_addr *out = addr;
+	struct rte_pci_addr pci_addr;
+	bool parse;
+
+	parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
+		 eal_parse_pci_DomBDF(name, &pci_addr) == 0);
+	if (parse && addr != NULL)
+		*out = pci_addr;
+	return parse == false;
+}
+
+/* register a driver */
+void
+rte_pci_register(struct rte_pci_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
+	driver->bus = &rte_pci_bus;
+}
+
+/* unregister a driver */
+void
+rte_pci_unregister(struct rte_pci_driver *driver)
+{
+	TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
+	driver->bus = NULL;
+}
+
+/* Add a device to PCI bus */
+void
+rte_pci_add_device(struct rte_pci_device *pci_dev)
+{
+	TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
+}
+
+/* Insert a device into a predefined position in PCI bus */
+void
+rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+		      struct rte_pci_device *new_pci_dev)
+{
+	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
+}
+
+/* Remove a device from PCI bus */
+void
+rte_pci_remove_device(struct rte_pci_device *pci_dev)
+{
+	TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
+}
+
+static struct rte_device *
+pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		const void *data)
+{
+	struct rte_pci_device *dev;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (start && &dev->device == start) {
+			start = NULL; /* starting point found */
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+
+	return NULL;
+}
+
+static int
+pci_plug(struct rte_device *dev)
+{
+	return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
+}
+
+static int
+pci_unplug(struct rte_device *dev)
+{
+	struct rte_pci_device *pdev;
+	int ret;
+
+	pdev = RTE_DEV_TO_PCI(dev);
+	ret = rte_pci_detach_dev(pdev);
+	rte_pci_remove_device(pdev);
+	free(pdev);
+	return ret;
+}
+
+struct rte_pci_bus rte_pci_bus = {
+	.bus = {
+		.scan = rte_pci_scan,
+		.probe = rte_pci_probe,
+		.find_device = pci_find_device,
+		.plug = pci_plug,
+		.unplug = pci_unplug,
+		.parse = pci_parse,
+		.get_iommu_class = rte_pci_get_iommu_class,
+	},
+	.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
+	.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(pci, rte_pci_bus.bus);
diff --git a/drivers/bus/pci/pci_common_uio.c b/drivers/bus/pci/pci_common_uio.c
new file mode 100644
index 0000000..4365660
--- /dev/null
+++ b/drivers/bus/pci/pci_common_uio.c
@@ -0,0 +1,234 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_tailq.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+
+#include "private.h"
+
+static struct rte_tailq_elem rte_uio_tailq = {
+	.name = "UIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_uio_tailq)
+
+static int
+pci_uio_map_secondary(struct rte_pci_device *dev)
+{
+	int fd, i, j;
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	TAILQ_FOREACH(uio_res, uio_res_list, next) {
+
+		/* skip this element if it doesn't match our PCI address */
+		if (rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+			continue;
+
+		for (i = 0; i != uio_res->nb_maps; i++) {
+			/*
+			 * open devname, to mmap it
+			 */
+			fd = open(uio_res->maps[i].path, O_RDWR);
+			if (fd < 0) {
+				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+					uio_res->maps[i].path, strerror(errno));
+				return -1;
+			}
+
+			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
+					fd, (off_t)uio_res->maps[i].offset,
+					(size_t)uio_res->maps[i].size, 0);
+			/* fd is not needed in slave process, close it */
+			close(fd);
+			if (mapaddr != uio_res->maps[i].addr) {
+				RTE_LOG(ERR, EAL,
+					"Cannot mmap device resource file %s to address: %p\n",
+					uio_res->maps[i].path,
+					uio_res->maps[i].addr);
+				if (mapaddr != MAP_FAILED) {
+					/* unmap addrs correctly mapped */
+					for (j = 0; j < i; j++)
+						pci_unmap_resource(
+							uio_res->maps[j].addr,
+							(size_t)uio_res->maps[j].size);
+					/* unmap addr wrongly mapped */
+					pci_unmap_resource(mapaddr,
+						(size_t)uio_res->maps[i].size);
+				}
+				return -1;
+			}
+		}
+		return 0;
+	}
+
+	RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
+	return 1;
+}
+
+/* map the PCI resource of a PCI device in virtual memory */
+int
+pci_uio_map_resource(struct rte_pci_device *dev)
+{
+	int i, map_idx = 0, ret;
+	uint64_t phaddr;
+	struct mapped_pci_resource *uio_res = NULL;
+	struct mapped_pci_res_list *uio_res_list =
+		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.uio_cfg_fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* secondary processes - use already recorded details */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return pci_uio_map_secondary(dev);
+
+	/* allocate uio resource */
+	ret = pci_uio_alloc_resource(dev, &uio_res);
+	if (ret)
+		return ret;
+
+	/* Map all BARs */
+	for (i = 0; i != PCI_MAX_RESOURCE; i++) {
+		/* skip empty BAR */
+		phaddr = dev->mem_resource[i].phys_addr;
+		if (phaddr == 0)
+			continue;
+
+		ret = pci_uio_map_resource_by_index(dev, i,
+				uio_res, map_idx);
+		if (ret)
+			goto error;
+
+		map_idx++;
+	}
+
+	uio_res->nb_maps = map_idx;
+
+	TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
+
+	return 0;
+error:
+	for (i = 0; i < map_idx; i++) {
+		pci_unmap_resource(uio_res->maps[i].addr,
+				(size_t)uio_res->maps[i].size);
+		rte_free(uio_res->maps[i].path);
+	}
+	pci_uio_free_resource(dev, uio_res);
+	return -1;
+}
+
+static void
+pci_uio_unmap(struct mapped_pci_resource *uio_res)
+{
+	int i;
+
+	if (uio_res == NULL)
+		return;
+
+	for (i = 0; i != uio_res->nb_maps; i++) {
+		pci_unmap_resource(uio_res->maps[i].addr,
+				(size_t)uio_res->maps[i].size);
+		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+			rte_free(uio_res->maps[i].path);
+	}
+}
+
+static struct mapped_pci_resource *
+pci_uio_find_resource(struct rte_pci_device *dev)
+{
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	if (dev == NULL)
+		return NULL;
+
+	TAILQ_FOREACH(uio_res, uio_res_list, next) {
+
+		/* skip this element if it doesn't match our PCI address */
+		if (!rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+			return uio_res;
+	}
+	return NULL;
+}
+
+/* unmap the PCI resource of a PCI device in virtual memory */
+void
+pci_uio_unmap_resource(struct rte_pci_device *dev)
+{
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	if (dev == NULL)
+		return;
+
+	/* find an entry for the device */
+	uio_res = pci_uio_find_resource(dev);
+	if (uio_res == NULL)
+		return;
+
+	/* secondary processes - just free maps */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return pci_uio_unmap(uio_res);
+
+	TAILQ_REMOVE(uio_res_list, uio_res, next);
+
+	/* unmap all resources */
+	pci_uio_unmap(uio_res);
+
+	/* free uio resource */
+	rte_free(uio_res);
+
+	/* close fd if in primary process */
+	close(dev->intr_handle.fd);
+	if (dev->intr_handle.uio_cfg_fd >= 0) {
+		close(dev->intr_handle.uio_cfg_fd);
+		dev->intr_handle.uio_cfg_fd = -1;
+	}
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+}
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
new file mode 100644
index 0000000..7ff1fc4
--- /dev/null
+++ b/drivers/bus/pci/private.h
@@ -0,0 +1,173 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PCI_PRIVATE_H_
+#define _PCI_PRIVATE_H_
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <rte_pci.h>
+
+struct rte_pci_driver;
+struct rte_pci_device;
+
+/**
+ * Find the name of a PCI device.
+ */
+void
+pci_name_set(struct rte_pci_device *dev);
+
+/**
+ * Add a PCI device to the PCI Bus (append to PCI Device list). This function
+ * also updates the bus references of the PCI Device (and the generic device
+ * object embedded within.
+ *
+ * @param pci_dev
+ *	PCI device to add
+ * @return void
+ */
+void rte_pci_add_device(struct rte_pci_device *pci_dev);
+
+/**
+ * Insert a PCI device in the PCI Bus at a particular location in the device
+ * list. It also updates the PCI Bus reference of the new devices to be
+ * inserted.
+ *
+ * @param exist_pci_dev
+ *	Existing PCI device in PCI Bus
+ * @param new_pci_dev
+ *	PCI device to be added before exist_pci_dev
+ * @return void
+ */
+void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+		struct rte_pci_device *new_pci_dev);
+
+/**
+ * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
+ * in the PCI device object as well as the generic device object.
+ *
+ * @param pci_device
+ *	PCI device to be removed from PCI Bus
+ * @return void
+ */
+void rte_pci_remove_device(struct rte_pci_device *pci_device);
+
+/**
+ * Update a pci device object by asking the kernel for the latest information.
+ *
+ * This function is private to EAL.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to look for
+ * @return
+ *   - 0 on success.
+ *   - negative on error.
+ */
+int pci_update_device(const struct rte_pci_addr *addr);
+
+/**
+ * Unbind kernel driver for this device
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_unbind_kernel_driver(struct rte_pci_device *dev);
+
+/**
+ * Map the PCI resource of a PCI device in virtual memory
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_map_resource(struct rte_pci_device *dev);
+
+/**
+ * Unmap the PCI resource of a PCI device
+ *
+ * This function is private to EAL.
+ */
+void pci_uio_unmap_resource(struct rte_pci_device *dev);
+
+/**
+ * Allocate uio resource for PCI device
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device to allocate uio resource
+ * @param uio_res
+ *   Pointer to uio resource.
+ *   If the function returns 0, the pointer will be filled.
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res);
+
+/**
+ * Free uio resource for PCI device
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device to free uio resource
+ * @param uio_res
+ *   Pointer to uio resource.
+ */
+void pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res);
+
+/**
+ * Map device memory to uio resource
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device that has memory information.
+ * @param res_idx
+ *   Memory resource index of the PCI device.
+ * @param uio_res
+ *  uio resource that will keep mapping information.
+ * @param map_idx
+ *   Mapping information index of the uio resource.
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx);
+
+#endif /* _PCI_PRIVATE_H_ */
diff --git a/drivers/bus/pci/rte_bus_pci_version.map b/drivers/bus/pci/rte_bus_pci_version.map
new file mode 100644
index 0000000..c1973f6
--- /dev/null
+++ b/drivers/bus/pci/rte_bus_pci_version.map
@@ -0,0 +1,21 @@
+DPDK_17.11 {
+	global:
+
+	rte_pci_detach;
+	rte_pci_dump;
+	rte_pci_ioport_map;
+	rte_pci_ioport_read;
+	rte_pci_ioport_unmap;
+	rte_pci_ioport_write;
+	rte_pci_map_device;
+	rte_pci_probe;
+	rte_pci_probe_one;
+	rte_pci_read_config;
+	rte_pci_register;
+	rte_pci_scan;
+	rte_pci_unmap_device;
+	rte_pci_unregister;
+	rte_pci_write_config;
+
+	local: *;
+};
diff --git a/lib/Makefile b/lib/Makefile
index 86d475f..abe6467 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-y += librte_compat
 DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
+DIRS-$(CONFIG_RTE_LIBRTE_PCI) += librte_pci
+DEPDIRS-librte_pci := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
 DEPDIRS-librte_ring := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 317a75e..518832f 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -55,7 +55,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
@@ -69,8 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_errno.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 30d3bd5..2917808 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -66,7 +66,6 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_bus.h>
-#include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_version.h>
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
deleted file mode 100644
index 1595988..0000000
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ /dev/null
@@ -1,680 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-#include <limits.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/pciio.h>
-#include <dev/pci/pcireg.h>
-
-#if defined(RTE_ARCH_X86)
-#include <machine/cpufunc.h>
-#endif
-
-#include <rte_interrupts.h>
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_common.h>
-#include <rte_launch.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_eal.h>
-#include <rte_eal_memconfig.h>
-#include <rte_per_lcore.h>
-#include <rte_lcore.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-#include <rte_debug.h>
-#include <rte_devargs.h>
-
-#include "eal_filesystem.h"
-#include "eal_private.h"
-
-/**
- * @file
- * PCI probing under linux
- *
- * This code is used to simulate a PCI probe by parsing information in
- * sysfs. Moreover, when a registered driver matches a device, the
- * kernel driver currently using it is unloaded and replaced by
- * igb_uio module, which is a very minimal userland driver for Intel
- * network card, only providing access to PCI BAR to applications, and
- * enabling bus master.
- */
-
-extern struct rte_pci_bus rte_pci_bus;
-
-/* Map pci device */
-int
-rte_pci_map_device(struct rte_pci_device *dev)
-{
-	int ret = -1;
-
-	/* try mapping the NIC resources */
-	switch (dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		/* map resources for devices that use uio */
-		ret = pci_uio_map_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		ret = 1;
-		break;
-	}
-
-	return ret;
-}
-
-/* Unmap pci device */
-void
-rte_pci_unmap_device(struct rte_pci_device *dev)
-{
-	/* try unmapping the NIC resources */
-	switch (dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		/* unmap resources for devices that use uio */
-		pci_uio_unmap_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		break;
-	}
-}
-
-void
-pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res)
-{
-	rte_free(uio_res);
-
-	if (dev->intr_handle.fd) {
-		close(dev->intr_handle.fd);
-		dev->intr_handle.fd = -1;
-		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	}
-}
-
-int
-pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res)
-{
-	char devname[PATH_MAX]; /* contains the /dev/uioX */
-	struct rte_pci_addr *loc;
-
-	loc = &dev->addr;
-
-	snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
-			dev->addr.bus, dev->addr.devid, dev->addr.function);
-
-	if (access(devname, O_RDWR) < 0) {
-		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
-				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
-		return 1;
-	}
-
-	/* save fd if in primary process */
-	dev->intr_handle.fd = open(devname, O_RDWR);
-	if (dev->intr_handle.fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			devname, strerror(errno));
-		goto error;
-	}
-	dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-
-	/* allocate the mapping details for secondary processes*/
-	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
-	if (*uio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto error;
-	}
-
-	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
-	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
-
-	return 0;
-
-error:
-	pci_uio_free_resource(dev, *uio_res);
-	return -1;
-}
-
-int
-pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx)
-{
-	int fd;
-	char *devname;
-	void *mapaddr;
-	uint64_t offset;
-	uint64_t pagesz;
-	struct pci_map *maps;
-
-	maps = uio_res->maps;
-	devname = uio_res->path;
-	pagesz = sysconf(_SC_PAGESIZE);
-
-	/* allocate memory to keep path */
-	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
-	if (maps[map_idx].path == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
-				strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * open resource file, to mmap it
-	 */
-	fd = open(devname, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				devname, strerror(errno));
-		goto error;
-	}
-
-	/* if matching map is found, then use it */
-	offset = res_idx * pagesz;
-	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
-			(size_t)dev->mem_resource[res_idx].len, 0);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		goto error;
-
-	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
-	maps[map_idx].size = dev->mem_resource[res_idx].len;
-	maps[map_idx].addr = mapaddr;
-	maps[map_idx].offset = offset;
-	strcpy(maps[map_idx].path, devname);
-	dev->mem_resource[res_idx].addr = mapaddr;
-
-	return 0;
-
-error:
-	rte_free(maps[map_idx].path);
-	return -1;
-}
-
-static int
-pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
-{
-	struct rte_pci_device *dev;
-	struct pci_bar_io bar;
-	unsigned i, max;
-
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL) {
-		return -1;
-	}
-
-	memset(dev, 0, sizeof(*dev));
-	dev->addr.domain = conf->pc_sel.pc_domain;
-	dev->addr.bus = conf->pc_sel.pc_bus;
-	dev->addr.devid = conf->pc_sel.pc_dev;
-	dev->addr.function = conf->pc_sel.pc_func;
-
-	/* get vendor id */
-	dev->id.vendor_id = conf->pc_vendor;
-
-	/* get device id */
-	dev->id.device_id = conf->pc_device;
-
-	/* get subsystem_vendor id */
-	dev->id.subsystem_vendor_id = conf->pc_subvendor;
-
-	/* get subsystem_device id */
-	dev->id.subsystem_device_id = conf->pc_subdevice;
-
-	/* get class id */
-	dev->id.class_id = (conf->pc_class << 16) |
-			   (conf->pc_subclass << 8) |
-			   (conf->pc_progif);
-
-	/* TODO: get max_vfs */
-	dev->max_vfs = 0;
-
-	/* FreeBSD has no NUMA support (yet) */
-	dev->device.numa_node = 0;
-
-	pci_name_set(dev);
-
-	/* FreeBSD has only one pass through driver */
-	dev->kdrv = RTE_KDRV_NIC_UIO;
-
-	/* parse resources */
-	switch (conf->pc_hdr & PCIM_HDRTYPE) {
-	case PCIM_HDRTYPE_NORMAL:
-		max = PCIR_MAX_BAR_0;
-		break;
-	case PCIM_HDRTYPE_BRIDGE:
-		max = PCIR_MAX_BAR_1;
-		break;
-	case PCIM_HDRTYPE_CARDBUS:
-		max = PCIR_MAX_BAR_2;
-		break;
-	default:
-		goto skipdev;
-	}
-
-	for (i = 0; i <= max; i++) {
-		bar.pbi_sel = conf->pc_sel;
-		bar.pbi_reg = PCIR_BAR(i);
-		if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
-			continue;
-
-		dev->mem_resource[i].len = bar.pbi_length;
-		if (PCI_BAR_IO(bar.pbi_base)) {
-			dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
-			continue;
-		}
-		dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
-	}
-
-	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-		rte_pci_add_device(dev);
-	}
-	else {
-		struct rte_pci_device *dev2 = NULL;
-		int ret;
-
-		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
-			if (ret > 0)
-				continue;
-			else if (ret < 0) {
-				rte_pci_insert_device(dev2, dev);
-			} else { /* already registered */
-				dev2->kdrv = dev->kdrv;
-				dev2->max_vfs = dev->max_vfs;
-				pci_name_set(dev2);
-				memmove(dev2->mem_resource,
-					dev->mem_resource,
-					sizeof(dev->mem_resource));
-				free(dev);
-			}
-			return 0;
-		}
-		rte_pci_add_device(dev);
-	}
-
-	return 0;
-
-skipdev:
-	free(dev);
-	return 0;
-}
-
-/*
- * Scan the content of the PCI bus, and add the devices in the devices
- * list. Call pci_scan_one() for each pci entry found.
- */
-int
-rte_pci_scan(void)
-{
-	int fd;
-	unsigned dev_count = 0;
-	struct pci_conf matches[16];
-	struct pci_conf_io conf_io = {
-			.pat_buf_len = 0,
-			.num_patterns = 0,
-			.patterns = NULL,
-			.match_buf_len = sizeof(matches),
-			.matches = &matches[0],
-	};
-
-	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
-		return 0;
-
-	fd = open("/dev/pci", O_RDONLY);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	do {
-		unsigned i;
-		if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
-			RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
-					__func__, strerror(errno));
-			goto error;
-		}
-
-		for (i = 0; i < conf_io.num_matches; i++)
-			if (pci_scan_one(fd, &matches[i]) < 0)
-				goto error;
-
-		dev_count += conf_io.num_matches;
-	} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
-
-	close(fd);
-
-	RTE_LOG(DEBUG, EAL, "PCI scan found %u devices\n", dev_count);
-	return 0;
-
-error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/*
- * Get iommu class of PCI devices on the bus.
- */
-enum rte_iova_mode
-rte_pci_get_iommu_class(void)
-{
-	/* Supports only RTE_KDRV_NIC_UIO */
-	return RTE_IOVA_PA;
-}
-
-int
-pci_update_device(const struct rte_pci_addr *addr)
-{
-	int fd;
-	struct pci_conf matches[2];
-	struct pci_match_conf match = {
-		.pc_sel = {
-			.pc_domain = addr->domain,
-			.pc_bus = addr->bus,
-			.pc_dev = addr->devid,
-			.pc_func = addr->function,
-		},
-	};
-	struct pci_conf_io conf_io = {
-		.pat_buf_len = 0,
-		.num_patterns = 1,
-		.patterns = &match,
-		.match_buf_len = sizeof(matches),
-		.matches = &matches[0],
-	};
-
-	fd = open("/dev/pci", O_RDONLY);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
-				__func__, strerror(errno));
-		goto error;
-	}
-
-	if (conf_io.num_matches != 1)
-		goto error;
-
-	if (pci_scan_one(fd, &matches[0]) < 0)
-		goto error;
-
-	close(fd);
-
-	return 0;
-
-error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/* Read PCI config space. */
-int rte_pci_read_config(const struct rte_pci_device *dev,
-		void *buf, size_t len, off_t offset)
-{
-	int fd = -1;
-	int size;
-	struct pci_io pi = {
-		.pi_sel = {
-			.pc_domain = dev->addr.domain,
-			.pc_bus = dev->addr.bus,
-			.pc_dev = dev->addr.devid,
-			.pc_func = dev->addr.function,
-		},
-		.pi_reg = offset,
-	};
-
-	fd = open("/dev/pci", O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	while (len > 0) {
-		size = (len >= 4) ? 4 : ((len >= 2) ? 2 : 1);
-		pi.pi_width = size;
-
-		if (ioctl(fd, PCIOCREAD, &pi) < 0)
-			goto error;
-		memcpy(buf, &pi.pi_data, size);
-
-		buf = (char *)buf + size;
-		pi.pi_reg += size;
-		len -= size;
-	}
-	close(fd);
-
-	return 0;
-
- error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/* Write PCI config space. */
-int rte_pci_write_config(const struct rte_pci_device *dev,
-		const void *buf, size_t len, off_t offset)
-{
-	int fd = -1;
-
-	struct pci_io pi = {
-		.pi_sel = {
-			.pc_domain = dev->addr.domain,
-			.pc_bus = dev->addr.bus,
-			.pc_dev = dev->addr.devid,
-			.pc_func = dev->addr.function,
-		},
-		.pi_reg = offset,
-		.pi_data = *(const uint32_t *)buf,
-		.pi_width = len,
-	};
-
-	if (len == 3 || len > sizeof(pi.pi_data)) {
-		RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__);
-		goto error;
-	}
-
-	memcpy(&pi.pi_data, buf, len);
-
-	fd = open("/dev/pci", O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	if (ioctl(fd, PCIOCWRITE, &pi) < 0)
-		goto error;
-
-	close(fd);
-	return 0;
-
- error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-int
-rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p)
-{
-	int ret;
-
-	switch (dev->kdrv) {
-#if defined(RTE_ARCH_X86)
-	case RTE_KDRV_NIC_UIO:
-		if ((uintptr_t) dev->mem_resource[bar].addr <= UINT16_MAX) {
-			p->base = (uintptr_t)dev->mem_resource[bar].addr;
-			ret = 0;
-		} else
-			ret = -1;
-		break;
-#endif
-	default:
-		ret = -1;
-		break;
-	}
-
-	if (!ret)
-		p->dev = dev;
-
-	return ret;
-}
-
-static void
-pci_uio_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-#if defined(RTE_ARCH_X86)
-	uint8_t *d;
-	int size;
-	unsigned short reg = p->base + offset;
-
-	for (d = data; len > 0; d += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-			*(uint32_t *)d = inl(reg);
-		} else if (len >= 2) {
-			size = 2;
-			*(uint16_t *)d = inw(reg);
-		} else {
-			size = 1;
-			*d = inb(reg);
-		}
-	}
-#else
-	RTE_SET_USED(p);
-	RTE_SET_USED(data);
-	RTE_SET_USED(len);
-	RTE_SET_USED(offset);
-#endif
-}
-
-void
-rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	default:
-		break;
-	}
-}
-
-static void
-pci_uio_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-#if defined(RTE_ARCH_X86)
-	const uint8_t *s;
-	int size;
-	unsigned short reg = p->base + offset;
-
-	for (s = data; len > 0; s += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-			outl(reg, *(const uint32_t *)s);
-		} else if (len >= 2) {
-			size = 2;
-			outw(reg, *(const uint16_t *)s);
-		} else {
-			size = 1;
-			outb(reg, *s);
-		}
-	}
-#else
-	RTE_SET_USED(p);
-	RTE_SET_USED(data);
-	RTE_SET_USED(len);
-	RTE_SET_USED(offset);
-#endif
-}
-
-void
-rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	default:
-		break;
-	}
-}
-
-int
-rte_pci_ioport_unmap(struct rte_pci_ioport *p)
-{
-	int ret;
-
-	switch (p->dev->kdrv) {
-#if defined(RTE_ARCH_X86)
-	case RTE_KDRV_NIC_UIO:
-		ret = 0;
-		break;
-#endif
-	default:
-		ret = -1;
-		break;
-	}
-
-	return ret;
-}
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index d19f264..97b3918 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -166,21 +166,6 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_pci_detach;
-	rte_pci_dump;
-	rte_pci_ioport_map;
-	rte_pci_ioport_read;
-	rte_pci_ioport_unmap;
-	rte_pci_ioport_write;
-	rte_pci_map_device;
-	rte_pci_probe;
-	rte_pci_probe_one;
-	rte_pci_read_config;
-	rte_pci_register;
-	rte_pci_scan;
-	rte_pci_unmap_device;
-	rte_pci_unregister;
-	rte_pci_write_config;
 	rte_vdev_init;
 	rte_vdev_register;
 	rte_vdev_uninit;
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index e8fd67a..ac8d3bb 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h
 INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
deleted file mode 100644
index 0f0e4b9..0000000
--- a/lib/librte_eal/common/eal_common_pci.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   Copyright 2013-2014 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-
-#include <rte_errno.h>
-#include <rte_interrupts.h>
-#include <rte_log.h>
-#include <rte_bus.h>
-#include <rte_pci.h>
-#include <rte_per_lcore.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_eal.h>
-#include <rte_string_fns.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-
-#include "eal_private.h"
-
-extern struct rte_pci_bus rte_pci_bus;
-
-#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
-
-const char *pci_get_sysfs_path(void)
-{
-	const char *path = NULL;
-
-	path = getenv("SYSFS_PCI_DEVICES");
-	if (path == NULL)
-		return SYSFS_PCI_DEVICES;
-
-	return path;
-}
-
-static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_pci_addr addr;
-	struct rte_bus *pbus;
-
-	pbus = rte_bus_find_by_name("pci");
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-		if (devargs->bus != pbus)
-			continue;
-		devargs->bus->parse(devargs->name, &addr);
-		if (!rte_eal_compare_pci_addr(&dev->addr, &addr))
-			return devargs;
-	}
-	return NULL;
-}
-
-void
-pci_name_set(struct rte_pci_device *dev)
-{
-	struct rte_devargs *devargs;
-
-	/* Each device has its internal, canonical name set. */
-	rte_pci_device_name(&dev->addr,
-			dev->name, sizeof(dev->name));
-	devargs = pci_devargs_lookup(dev);
-	dev->device.devargs = devargs;
-	/* In blacklist mode, if the device is not blacklisted, no
-	 * rte_devargs exists for it.
-	 */
-	if (devargs != NULL)
-		/* If an rte_devargs exists, the generic rte_device uses the
-		 * given name as its namea
-		 */
-		dev->device.name = dev->device.devargs->name;
-	else
-		/* Otherwise, it uses the internal, canonical form. */
-		dev->device.name = dev->name;
-}
-
-/* map a particular resource from a file */
-void *
-pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
-		 int additional_flags)
-{
-	void *mapaddr;
-
-	/* Map the PCI memory resource of device */
-	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
-			MAP_SHARED | additional_flags, fd, offset);
-	if (mapaddr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
-			__func__, fd, requested_addr,
-			(unsigned long)size, (unsigned long)offset,
-			strerror(errno), mapaddr);
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
-
-	return mapaddr;
-}
-
-/* unmap a particular resource */
-void
-pci_unmap_resource(void *requested_addr, size_t size)
-{
-	if (requested_addr == NULL)
-		return;
-
-	/* Unmap the PCI memory resource of device */
-	if (munmap(requested_addr, size)) {
-		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
-			__func__, requested_addr, (unsigned long)size,
-			strerror(errno));
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
-				requested_addr);
-}
-
-/*
- * Match the PCI Driver and Device using the ID Table
- */
-int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev)
-{
-	const struct rte_pci_id *id_table;
-
-	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
-	     id_table++) {
-		/* check if device's identifiers match the driver's ones */
-		if (id_table->vendor_id != pci_dev->id.vendor_id &&
-				id_table->vendor_id != PCI_ANY_ID)
-			continue;
-		if (id_table->device_id != pci_dev->id.device_id &&
-				id_table->device_id != PCI_ANY_ID)
-			continue;
-		if (id_table->subsystem_vendor_id !=
-		    pci_dev->id.subsystem_vendor_id &&
-		    id_table->subsystem_vendor_id != PCI_ANY_ID)
-			continue;
-		if (id_table->subsystem_device_id !=
-		    pci_dev->id.subsystem_device_id &&
-		    id_table->subsystem_device_id != PCI_ANY_ID)
-			continue;
-		if (id_table->class_id != pci_dev->id.class_id &&
-				id_table->class_id != RTE_CLASS_ANY_ID)
-			continue;
-
-		return 1;
-	}
-
-	return 0;
-}
-
-/*
- * If vendor/device ID match, call the probe() function of the
- * driver.
- */
-static int
-rte_pci_probe_one_driver(struct rte_pci_driver *dr,
-			 struct rte_pci_device *dev)
-{
-	int ret;
-	struct rte_pci_addr *loc;
-
-	if ((dr == NULL) || (dev == NULL))
-		return -EINVAL;
-
-	loc = &dev->addr;
-
-	/* The device is not blacklisted; Check if driver supports it */
-	if (!rte_pci_match(dr, dev))
-		/* Match of device and driver failed */
-		return 1;
-
-	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-			loc->domain, loc->bus, loc->devid, loc->function,
-			dev->device.numa_node);
-
-	/* no initialization when blacklisted, return without error */
-	if (dev->device.devargs != NULL &&
-		dev->device.devargs->policy ==
-			RTE_DEV_BLACKLISTED) {
-		RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
-			" initializing\n");
-		return 1;
-	}
-
-	if (dev->device.numa_node < 0) {
-		RTE_LOG(WARNING, EAL, "  Invalid NUMA socket, default to 0\n");
-		dev->device.numa_node = 0;
-	}
-
-	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
-		dev->id.device_id, dr->driver.name);
-
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
-		/* map resources for devices that use igb_uio */
-		ret = rte_pci_map_device(dev);
-		if (ret != 0)
-			return ret;
-	}
-
-	/* reference driver structure */
-	dev->driver = dr;
-	dev->device.driver = &dr->driver;
-
-	/* call the driver probe() function */
-	ret = dr->probe(dr, dev);
-	if (ret) {
-		dev->driver = NULL;
-		dev->device.driver = NULL;
-		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
-			/* Don't unmap if device is unsupported and
-			 * driver needs mapped resources.
-			 */
-			!(ret > 0 &&
-				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
-			rte_pci_unmap_device(dev);
-	}
-
-	return ret;
-}
-
-/*
- * If vendor/device ID match, call the remove() function of the
- * driver.
- */
-static int
-rte_pci_detach_dev(struct rte_pci_device *dev)
-{
-	struct rte_pci_addr *loc;
-	struct rte_pci_driver *dr;
-
-	if (dev == NULL)
-		return -EINVAL;
-
-	dr = dev->driver;
-	loc = &dev->addr;
-
-	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-			loc->domain, loc->bus, loc->devid,
-			loc->function, dev->device.numa_node);
-
-	RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
-			dev->id.device_id, dr->driver.name);
-
-	if (dr->remove && (dr->remove(dev) < 0))
-		return -1;	/* negative value is an error */
-
-	/* clear driver structure */
-	dev->driver = NULL;
-
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
-		/* unmap resources for devices that use igb_uio */
-		rte_pci_unmap_device(dev);
-
-	return 0;
-}
-
-/*
- * If vendor/device ID match, call the probe() function of all
- * registered driver for the given device. Return -1 if initialization
- * failed, return 1 if no driver is found for this device.
- */
-static int
-pci_probe_all_drivers(struct rte_pci_device *dev)
-{
-	struct rte_pci_driver *dr = NULL;
-	int rc = 0;
-
-	if (dev == NULL)
-		return -1;
-
-	/* Check if a driver is already loaded */
-	if (dev->driver != NULL)
-		return 0;
-
-	FOREACH_DRIVER_ON_PCIBUS(dr) {
-		rc = rte_pci_probe_one_driver(dr, dev);
-		if (rc < 0)
-			/* negative value is an error */
-			return -1;
-		if (rc > 0)
-			/* positive value means driver doesn't support it */
-			continue;
-		return 0;
-	}
-	return 1;
-}
-
-/*
- * Find the pci device specified by pci address, then invoke probe function of
- * the driver of the device.
- */
-int
-rte_pci_probe_one(const struct rte_pci_addr *addr)
-{
-	struct rte_pci_device *dev = NULL;
-
-	int ret = 0;
-
-	if (addr == NULL)
-		return -1;
-
-	/* update current pci device in global list, kernel bindings might have
-	 * changed since last time we looked at it.
-	 */
-	if (pci_update_device(addr) < 0)
-		goto err_return;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_eal_compare_pci_addr(&dev->addr, addr))
-			continue;
-
-		ret = pci_probe_all_drivers(dev);
-		if (ret)
-			goto err_return;
-		return 0;
-	}
-	return -1;
-
-err_return:
-	RTE_LOG(WARNING, EAL,
-		"Requested device " PCI_PRI_FMT " cannot be used\n",
-		addr->domain, addr->bus, addr->devid, addr->function);
-	return -1;
-}
-
-/*
- * Detach device specified by its pci address.
- */
-int
-rte_pci_detach(const struct rte_pci_addr *addr)
-{
-	struct rte_pci_device *dev = NULL;
-	int ret = 0;
-
-	if (addr == NULL)
-		return -1;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_eal_compare_pci_addr(&dev->addr, addr))
-			continue;
-
-		ret = rte_pci_detach_dev(dev);
-		if (ret < 0)
-			/* negative value is an error */
-			goto err_return;
-		if (ret > 0)
-			/* positive value means driver doesn't support it */
-			continue;
-
-		rte_pci_remove_device(dev);
-		free(dev);
-		return 0;
-	}
-	return -1;
-
-err_return:
-	RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
-			" cannot be used\n", dev->addr.domain, dev->addr.bus,
-			dev->addr.devid, dev->addr.function);
-	return -1;
-}
-
-/*
- * Scan the content of the PCI bus, and call the probe() function for
- * all registered drivers that have a matching entry in its id_table
- * for discovered devices.
- */
-int
-rte_pci_probe(void)
-{
-	struct rte_pci_device *dev = NULL;
-	size_t probed = 0, failed = 0;
-	struct rte_devargs *devargs;
-	int probe_all = 0;
-	int ret = 0;
-
-	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
-		probe_all = 1;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		probed++;
-
-		devargs = dev->device.devargs;
-		/* probe all or only whitelisted devices */
-		if (probe_all)
-			ret = pci_probe_all_drivers(dev);
-		else if (devargs != NULL &&
-			devargs->policy == RTE_DEV_WHITELISTED)
-			ret = pci_probe_all_drivers(dev);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
-				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
-				 dev->addr.devid, dev->addr.function);
-			rte_errno = errno;
-			failed++;
-			ret = 0;
-		}
-	}
-
-	return (probed && probed == failed) ? -1 : 0;
-}
-
-/* dump one device */
-static int
-pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
-{
-	int i;
-
-	fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
-	       dev->addr.devid, dev->addr.function);
-	fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
-	       dev->id.device_id);
-
-	for (i = 0; i != sizeof(dev->mem_resource) /
-		sizeof(dev->mem_resource[0]); i++) {
-		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
-			dev->mem_resource[i].phys_addr,
-			dev->mem_resource[i].len);
-	}
-	return 0;
-}
-
-/* dump devices on the bus */
-void
-rte_pci_dump(FILE *f)
-{
-	struct rte_pci_device *dev = NULL;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		pci_dump_one_device(f, dev);
-	}
-}
-
-static int
-pci_parse(const char *name, void *addr)
-{
-	struct rte_pci_addr *out = addr;
-	struct rte_pci_addr pci_addr;
-	bool parse;
-
-	parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
-		 eal_parse_pci_DomBDF(name, &pci_addr) == 0);
-	if (parse && addr != NULL)
-		*out = pci_addr;
-	return parse == false;
-}
-
-/* register a driver */
-void
-rte_pci_register(struct rte_pci_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
-	driver->bus = &rte_pci_bus;
-}
-
-/* unregister a driver */
-void
-rte_pci_unregister(struct rte_pci_driver *driver)
-{
-	TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
-	driver->bus = NULL;
-}
-
-/* Add a device to PCI bus */
-void
-rte_pci_add_device(struct rte_pci_device *pci_dev)
-{
-	TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
-}
-
-/* Insert a device into a predefined position in PCI bus */
-void
-rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
-		      struct rte_pci_device *new_pci_dev)
-{
-	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
-}
-
-/* Remove a device from PCI bus */
-void
-rte_pci_remove_device(struct rte_pci_device *pci_dev)
-{
-	TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
-}
-
-static struct rte_device *
-pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		const void *data)
-{
-	struct rte_pci_device *dev;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (start && &dev->device == start) {
-			start = NULL; /* starting point found */
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-
-	return NULL;
-}
-
-static int
-pci_plug(struct rte_device *dev)
-{
-	return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
-}
-
-static int
-pci_unplug(struct rte_device *dev)
-{
-	struct rte_pci_device *pdev;
-	int ret;
-
-	pdev = RTE_DEV_TO_PCI(dev);
-	ret = rte_pci_detach_dev(pdev);
-	rte_pci_remove_device(pdev);
-	free(pdev);
-	return ret;
-}
-
-struct rte_pci_bus rte_pci_bus = {
-	.bus = {
-		.scan = rte_pci_scan,
-		.probe = rte_pci_probe,
-		.find_device = pci_find_device,
-		.plug = pci_plug,
-		.unplug = pci_unplug,
-		.parse = pci_parse,
-		.get_iommu_class = rte_pci_get_iommu_class,
-	},
-	.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
-	.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
-};
-
-RTE_REGISTER_BUS(pci, rte_pci_bus.bus);
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
deleted file mode 100644
index 367a681..0000000
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include <rte_eal.h>
-#include <rte_tailq.h>
-#include <rte_log.h>
-#include <rte_malloc.h>
-
-#include "eal_private.h"
-
-static struct rte_tailq_elem rte_uio_tailq = {
-	.name = "UIO_RESOURCE_LIST",
-};
-EAL_REGISTER_TAILQ(rte_uio_tailq)
-
-static int
-pci_uio_map_secondary(struct rte_pci_device *dev)
-{
-	int fd, i, j;
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	TAILQ_FOREACH(uio_res, uio_res_list, next) {
-
-		/* skip this element if it doesn't match our PCI address */
-		if (rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
-			continue;
-
-		for (i = 0; i != uio_res->nb_maps; i++) {
-			/*
-			 * open devname, to mmap it
-			 */
-			fd = open(uio_res->maps[i].path, O_RDWR);
-			if (fd < 0) {
-				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-					uio_res->maps[i].path, strerror(errno));
-				return -1;
-			}
-
-			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
-					fd, (off_t)uio_res->maps[i].offset,
-					(size_t)uio_res->maps[i].size, 0);
-			/* fd is not needed in slave process, close it */
-			close(fd);
-			if (mapaddr != uio_res->maps[i].addr) {
-				RTE_LOG(ERR, EAL,
-					"Cannot mmap device resource file %s to address: %p\n",
-					uio_res->maps[i].path,
-					uio_res->maps[i].addr);
-				if (mapaddr != MAP_FAILED) {
-					/* unmap addrs correctly mapped */
-					for (j = 0; j < i; j++)
-						pci_unmap_resource(
-							uio_res->maps[j].addr,
-							(size_t)uio_res->maps[j].size);
-					/* unmap addr wrongly mapped */
-					pci_unmap_resource(mapaddr,
-						(size_t)uio_res->maps[i].size);
-				}
-				return -1;
-			}
-		}
-		return 0;
-	}
-
-	RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
-	return 1;
-}
-
-/* map the PCI resource of a PCI device in virtual memory */
-int
-pci_uio_map_resource(struct rte_pci_device *dev)
-{
-	int i, map_idx = 0, ret;
-	uint64_t phaddr;
-	struct mapped_pci_resource *uio_res = NULL;
-	struct mapped_pci_res_list *uio_res_list =
-		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.uio_cfg_fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* secondary processes - use already recorded details */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return pci_uio_map_secondary(dev);
-
-	/* allocate uio resource */
-	ret = pci_uio_alloc_resource(dev, &uio_res);
-	if (ret)
-		return ret;
-
-	/* Map all BARs */
-	for (i = 0; i != PCI_MAX_RESOURCE; i++) {
-		/* skip empty BAR */
-		phaddr = dev->mem_resource[i].phys_addr;
-		if (phaddr == 0)
-			continue;
-
-		ret = pci_uio_map_resource_by_index(dev, i,
-				uio_res, map_idx);
-		if (ret)
-			goto error;
-
-		map_idx++;
-	}
-
-	uio_res->nb_maps = map_idx;
-
-	TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
-
-	return 0;
-error:
-	for (i = 0; i < map_idx; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
-				(size_t)uio_res->maps[i].size);
-		rte_free(uio_res->maps[i].path);
-	}
-	pci_uio_free_resource(dev, uio_res);
-	return -1;
-}
-
-static void
-pci_uio_unmap(struct mapped_pci_resource *uio_res)
-{
-	int i;
-
-	if (uio_res == NULL)
-		return;
-
-	for (i = 0; i != uio_res->nb_maps; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
-				(size_t)uio_res->maps[i].size);
-		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-			rte_free(uio_res->maps[i].path);
-	}
-}
-
-static struct mapped_pci_resource *
-pci_uio_find_resource(struct rte_pci_device *dev)
-{
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	if (dev == NULL)
-		return NULL;
-
-	TAILQ_FOREACH(uio_res, uio_res_list, next) {
-
-		/* skip this element if it doesn't match our PCI address */
-		if (!rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
-			return uio_res;
-	}
-	return NULL;
-}
-
-/* unmap the PCI resource of a PCI device in virtual memory */
-void
-pci_uio_unmap_resource(struct rte_pci_device *dev)
-{
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	if (dev == NULL)
-		return;
-
-	/* find an entry for the device */
-	uio_res = pci_uio_find_resource(dev);
-	if (uio_res == NULL)
-		return;
-
-	/* secondary processes - just free maps */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return pci_uio_unmap(uio_res);
-
-	TAILQ_REMOVE(uio_res_list, uio_res, next);
-
-	/* unmap all resources */
-	pci_uio_unmap(uio_res);
-
-	/* free uio resource */
-	rte_free(uio_res);
-
-	/* close fd if in primary process */
-	close(dev->intr_handle.fd);
-	if (dev->intr_handle.uio_cfg_fd >= 0) {
-		close(dev->intr_handle.uio_cfg_fd);
-		dev->intr_handle.uio_cfg_fd = -1;
-	}
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 597d82e..6baa667 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,7 +36,6 @@
 
 #include <stdbool.h>
 #include <stdio.h>
-#include <rte_pci.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -109,137 +108,6 @@ int rte_eal_timer_init(void);
  */
 int rte_eal_log_init(const char *id, int facility);
 
-struct rte_pci_driver;
-struct rte_pci_device;
-
-/**
- * Find the name of a PCI device.
- */
-void pci_name_set(struct rte_pci_device *dev);
-
-/**
- * Add a PCI device to the PCI Bus (append to PCI Device list). This function
- * also updates the bus references of the PCI Device (and the generic device
- * object embedded within.
- *
- * @param pci_dev
- *	PCI device to add
- * @return void
- */
-void rte_pci_add_device(struct rte_pci_device *pci_dev);
-
-/**
- * Insert a PCI device in the PCI Bus at a particular location in the device
- * list. It also updates the PCI Bus reference of the new devices to be
- * inserted.
- *
- * @param exist_pci_dev
- *	Existing PCI device in PCI Bus
- * @param new_pci_dev
- *	PCI device to be added before exist_pci_dev
- * @return void
- */
-void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
-		struct rte_pci_device *new_pci_dev);
-
-/**
- * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
- * in the PCI device object as well as the generic device object.
- *
- * @param pci_device
- *	PCI device to be removed from PCI Bus
- * @return void
- */
-void rte_pci_remove_device(struct rte_pci_device *pci_device);
-
-/**
- * Update a pci device object by asking the kernel for the latest information.
- *
- * This function is private to EAL.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to look for
- * @return
- *   - 0 on success.
- *   - negative on error.
- */
-int pci_update_device(const struct rte_pci_addr *addr);
-
-/**
- * Unbind kernel driver for this device
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int pci_unbind_kernel_driver(struct rte_pci_device *dev);
-
-/**
- * Map the PCI resource of a PCI device in virtual memory
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_map_resource(struct rte_pci_device *dev);
-
-/**
- * Unmap the PCI resource of a PCI device
- *
- * This function is private to EAL.
- */
-void pci_uio_unmap_resource(struct rte_pci_device *dev);
-
-/**
- * Allocate uio resource for PCI device
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device to allocate uio resource
- * @param uio_res
- *   Pointer to uio resource.
- *   If the function returns 0, the pointer will be filled.
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res);
-
-/**
- * Free uio resource for PCI device
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device to free uio resource
- * @param uio_res
- *   Pointer to uio resource.
- */
-void pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res);
-
-/**
- * Map device memory to uio resource
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device that has memory information.
- * @param res_idx
- *   Memory resource index of the PCI device.
- * @param uio_res
- *  uio resource that will keep mapping information.
- * @param map_idx
- *   Mapping information index of the uio resource.
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx);
-
 /**
  * Init tail queues for non-EAL library structures. This is to allow
  * the rings, mempools, etc. lists to be shared among multiple processes
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
deleted file mode 100644
index 1c5f469..0000000
--- a/lib/librte_eal/common/include/rte_pci.h
+++ /dev/null
@@ -1,633 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   Copyright 2013-2014 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_PCI_H_
-#define _RTE_PCI_H_
-
-/**
- * @file
- *
- * RTE PCI Interface
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <errno.h>
-#include <sys/queue.h>
-#include <stdint.h>
-#include <inttypes.h>
-
-#include <rte_debug.h>
-#include <rte_interrupts.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-
-/** Pathname of PCI devices directory. */
-const char *pci_get_sysfs_path(void);
-
-/** Formatting string for PCI device identifier: Ex: 0000:00:01.0 */
-#define PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
-#define PCI_PRI_STR_SIZE sizeof("XXXXXXXX:XX:XX.X")
-
-/** Short formatting string, without domain, for PCI device: Ex: 00:01.0 */
-#define PCI_SHORT_PRI_FMT "%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
-
-/** Nb. of values in PCI device identifier format string. */
-#define PCI_FMT_NVAL 4
-
-/** Nb. of values in PCI resource format. */
-#define PCI_RESOURCE_FMT_NVAL 3
-
-/** Maximum number of PCI resources. */
-#define PCI_MAX_RESOURCE 6
-
-/* Forward declarations */
-struct rte_pci_device;
-struct rte_pci_driver;
-
-/** List of PCI devices */
-TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
-/** List of PCI drivers */
-TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
-
-/* PCI Bus iterators */
-#define FOREACH_DEVICE_ON_PCIBUS(p)	\
-		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
-
-#define FOREACH_DRIVER_ON_PCIBUS(p)	\
-		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
-
-/**
- * A structure describing an ID for a PCI driver. Each driver provides a
- * table of these IDs for each device that it supports.
- */
-struct rte_pci_id {
-	uint32_t class_id;            /**< Class ID (class, subclass, pi) or RTE_CLASS_ANY_ID. */
-	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
-	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
-	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
-	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
-};
-
-/**
- * A structure describing the location of a PCI device.
- */
-struct rte_pci_addr {
-	uint32_t domain;                /**< Device domain */
-	uint8_t bus;                    /**< Device bus */
-	uint8_t devid;                  /**< Device ID */
-	uint8_t function;               /**< Device function. */
-};
-
-struct rte_devargs;
-
-/**
- * A structure describing a PCI device.
- */
-struct rte_pci_device {
-	TAILQ_ENTRY(rte_pci_device) next;       /**< Next probed PCI device. */
-	struct rte_device device;               /**< Inherit core device */
-	struct rte_pci_addr addr;               /**< PCI location. */
-	struct rte_pci_id id;                   /**< PCI ID. */
-	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
-						/**< PCI Memory Resource */
-	struct rte_intr_handle intr_handle;     /**< Interrupt handle */
-	struct rte_pci_driver *driver;          /**< Associated driver */
-	uint16_t max_vfs;                       /**< sriov enable if not zero */
-	enum rte_kernel_driver kdrv;            /**< Kernel driver passthrough */
-	char name[PCI_PRI_STR_SIZE+1];          /**< PCI location (ASCII) */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_pci_device.
- */
-#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
-
-/** Any PCI device identifier (vendor, device, ...) */
-#define PCI_ANY_ID (0xffff)
-#define RTE_CLASS_ANY_ID (0xffffff)
-
-#ifdef __cplusplus
-/** C++ macro used to help building up tables of device IDs */
-#define RTE_PCI_DEVICE(vend, dev) \
-	RTE_CLASS_ANY_ID,         \
-	(vend),                   \
-	(dev),                    \
-	PCI_ANY_ID,               \
-	PCI_ANY_ID
-#else
-/** Macro used to help building up tables of device IDs */
-#define RTE_PCI_DEVICE(vend, dev)          \
-	.class_id = RTE_CLASS_ANY_ID,      \
-	.vendor_id = (vend),               \
-	.device_id = (dev),                \
-	.subsystem_vendor_id = PCI_ANY_ID, \
-	.subsystem_device_id = PCI_ANY_ID
-#endif
-
-/**
- * Initialisation function for the driver called during PCI probing.
- */
-typedef int (pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
-
-/**
- * Uninitialisation function for the driver called during hotplugging.
- */
-typedef int (pci_remove_t)(struct rte_pci_device *);
-
-/**
- * A structure describing a PCI driver.
- */
-struct rte_pci_driver {
-	TAILQ_ENTRY(rte_pci_driver) next;       /**< Next in list. */
-	struct rte_driver driver;               /**< Inherit core driver. */
-	struct rte_pci_bus *bus;                /**< PCI bus reference. */
-	pci_probe_t *probe;                     /**< Device Probe function. */
-	pci_remove_t *remove;                   /**< Device Remove function. */
-	const struct rte_pci_id *id_table;	/**< ID table, NULL terminated. */
-	uint32_t drv_flags;                     /**< Flags contolling handling of device. */
-};
-
-/**
- * Structure describing the PCI bus
- */
-struct rte_pci_bus {
-	struct rte_bus bus;               /**< Inherit the generic class */
-	struct rte_pci_device_list device_list;  /**< List of PCI devices */
-	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
-};
-
-/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
-#define RTE_PCI_DRV_NEED_MAPPING 0x0001
-/** Device driver supports link state interrupt */
-#define RTE_PCI_DRV_INTR_LSC	0x0008
-/** Device driver supports device removal interrupt */
-#define RTE_PCI_DRV_INTR_RMV 0x0010
-/** Device driver needs to keep mapped resources if unsupported dev detected */
-#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
-/** Device driver supports IOVA as VA */
-#define RTE_PCI_DRV_IOVA_AS_VA 0X0040
-
-/**
- * A structure describing a PCI mapping.
- */
-struct pci_map {
-	void *addr;
-	char *path;
-	uint64_t offset;
-	uint64_t size;
-	uint64_t phaddr;
-};
-
-struct pci_msix_table {
-	int bar_index;
-	uint32_t offset;
-	uint32_t size;
-};
-
-/**
- * A structure describing a mapped PCI resource.
- * For multi-process we need to reproduce all PCI mappings in secondary
- * processes, so save them in a tailq.
- */
-struct mapped_pci_resource {
-	TAILQ_ENTRY(mapped_pci_resource) next;
-
-	struct rte_pci_addr pci_addr;
-	char path[PATH_MAX];
-	int nb_maps;
-	struct pci_map maps[PCI_MAX_RESOURCE];
-	struct pci_msix_table msix_table;
-};
-
-/** mapped pci device list */
-TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
-
-/**< Internal use only - Macro used by pci addr parsing functions **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
-do {                                                               \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
-
-/**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided without
- * a domain prefix (i.e. domain returned is always 0)
- *
- * @param input
- *	The input string to be parsed. Should have the format XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned. Domain will always be
- *	returned as 0
- * @return
- *  0 on success, negative on error.
- */
-static inline int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-
-/**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided including
- * a domain prefix.
- *
- * @param input
- *	The input string to be parsed. Should have the format XXXX:XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned
- * @return
- *  0 on success, negative on error.
- */
-static inline int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-#undef GET_PCIADDR_FIELD
-
-/**
- * Utility function to write a pci device name, this device name can later be
- * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
- * BDF helpers.
- *
- * @param addr
- *	The PCI Bus-Device-Function address
- * @param output
- *	The output buffer string
- * @param size
- *	The output buffer size
- */
-static inline void
-rte_pci_device_name(const struct rte_pci_addr *addr,
-		char *output, size_t size)
-{
-	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
-	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
-			    addr->domain, addr->bus,
-			    addr->devid, addr->function) >= 0);
-}
-
-/* Compare two PCI device addresses. */
-/**
- * Utility function to compare two PCI device addresses.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to compare
- * @param addr2
- *	The PCI Bus-Device-Function address to compare
- * @return
- *	0 on equal PCI address.
- *	Positive on addr is greater than addr2.
- *	Negative on addr is less than addr2, or error.
- */
-static inline int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			 const struct rte_pci_addr *addr2)
-{
-	uint64_t dev_addr, dev_addr2;
-
-	if ((addr == NULL) || (addr2 == NULL))
-		return -1;
-
-	dev_addr = ((uint64_t)addr->domain << 24) |
-		(addr->bus << 16) | (addr->devid << 8) | addr->function;
-	dev_addr2 = ((uint64_t)addr2->domain << 24) |
-		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
-
-	if (dev_addr > dev_addr2)
-		return 1;
-	else if (dev_addr < dev_addr2)
-		return -1;
-	else
-		return 0;
-}
-
-/**
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- *
- * @return
- *  0 on success, negative on error
- */
-int rte_pci_scan(void);
-
-/**
- * Probe the PCI bus
- *
- * @return
- *   - 0 on success.
- *   - !0 on error.
- */
-int
-rte_pci_probe(void);
-
-/*
- * Match the PCI Driver and Device using the ID Table
- *
- * @param pci_drv
- *      PCI driver from which ID table would be extracted
- * @param pci_dev
- *      PCI device to match against the driver
- * @return
- *      1 for successful match
- *      0 for unsuccessful match
- */
-int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev);
-
-
-/**
- * Get iommu class of PCI devices on the bus.
- * And return their preferred iova mapping mode.
- *
- * @return
- *   - enum rte_iova_mode.
- */
-enum rte_iova_mode
-rte_pci_get_iommu_class(void);
-
-/**
- * Map the PCI device resources in user space virtual memory address
- *
- * Note that driver should not call this function when flag
- * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for
- * you when it's on.
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- *
- * @return
- *   0 on success, negative on error and positive if no driver
- *   is found for the device.
- */
-int rte_pci_map_device(struct rte_pci_device *dev);
-
-/**
- * Unmap this device
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- */
-void rte_pci_unmap_device(struct rte_pci_device *dev);
-
-/**
- * @internal
- * Map a particular resource from a file.
- *
- * @param requested_addr
- *      The starting address for the new mapping range.
- * @param fd
- *      The file descriptor.
- * @param offset
- *      The offset for the mapping range.
- * @param size
- *      The size for the mapping range.
- * @param additional_flags
- *      The additional flags for the mapping range.
- * @return
- *   - On success, the function returns a pointer to the mapped area.
- *   - On error, the value MAP_FAILED is returned.
- */
-void *pci_map_resource(void *requested_addr, int fd, off_t offset,
-		size_t size, int additional_flags);
-
-/**
- * @internal
- * Unmap a particular resource.
- *
- * @param requested_addr
- *      The address for the unmapping range.
- * @param size
- *      The size for the unmapping range.
- */
-void pci_unmap_resource(void *requested_addr, size_t size);
-
-/**
- * Probe the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the probe() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to probe.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_probe_one(const struct rte_pci_addr *addr);
-
-/**
- * Close the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the remove() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to close.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_detach(const struct rte_pci_addr *addr);
-
-/**
- * Dump the content of the PCI bus.
- *
- * @param f
- *   A pointer to a file for output
- */
-void rte_pci_dump(FILE *f);
-
-/**
- * Register a PCI driver.
- *
- * @param driver
- *   A pointer to a rte_pci_driver structure describing the driver
- *   to be registered.
- */
-void rte_pci_register(struct rte_pci_driver *driver);
-
-/** Helper for PCI device registration from driver (eth, crypto) instance */
-#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
-RTE_INIT(pciinitfn_ ##nm); \
-static void pciinitfn_ ##nm(void) \
-{\
-	(pci_drv).driver.name = RTE_STR(nm);\
-	rte_pci_register(&pci_drv); \
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-/**
- * Unregister a PCI driver.
- *
- * @param driver
- *   A pointer to a rte_pci_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_pci_unregister(struct rte_pci_driver *driver);
-
-/**
- * Read PCI config space.
- *
- * @param device
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- * @param buf
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into PCI config space
- */
-int rte_pci_read_config(const struct rte_pci_device *device,
-		void *buf, size_t len, off_t offset);
-
-/**
- * Write PCI config space.
- *
- * @param device
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- * @param buf
- *   A data buffer containing the bytes should be written
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into PCI config space
- */
-int rte_pci_write_config(const struct rte_pci_device *device,
-		const void *buf, size_t len, off_t offset);
-
-/**
- * A structure used to access io resources for a pci device.
- * rte_pci_ioport is arch, os, driver specific, and should not be used outside
- * of pci ioport api.
- */
-struct rte_pci_ioport {
-	struct rte_pci_device *dev;
-	uint64_t base;
-	uint64_t len; /* only filled for memory mapped ports */
-};
-
-/**
- * Initialize a rte_pci_ioport object for a pci device io resource.
- *
- * This object is then used to gain access to those io resources (see below).
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use.
- * @param bar
- *   Index of the io pci resource we want to access.
- * @param p
- *   The rte_pci_ioport object to be initialized.
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p);
-
-/**
- * Release any resources used in a rte_pci_ioport object.
- *
- * @param p
- *   The rte_pci_ioport object to be uninitialized.
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_ioport_unmap(struct rte_pci_ioport *p);
-
-/**
- * Read from a io pci resource.
- *
- * @param p
- *   The rte_pci_ioport object from which we want to read.
- * @param data
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into the pci io resource.
- */
-void rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset);
-
-/**
- * Write to a io pci resource.
- *
- * @param p
- *   The rte_pci_ioport object to which we want to write.
- * @param data
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into the pci io resource.
- */
-void rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RTE_PCI_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 21e0b4a..90adb8d 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -61,10 +61,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
@@ -78,8 +74,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_errno.c
@@ -106,16 +100,12 @@ CFLAGS_eal_common_cpuflags.o := $(CPUFLAGS_LIST)
 
 CFLAGS_eal.o := -D_GNU_SOURCE
 CFLAGS_eal_interrupts.o := -D_GNU_SOURCE
-CFLAGS_eal_vfio_mp_sync.o := -D_GNU_SOURCE
 CFLAGS_eal_timer.o := -D_GNU_SOURCE
 CFLAGS_eal_lcore.o := -D_GNU_SOURCE
 CFLAGS_eal_thread.o := -D_GNU_SOURCE
 CFLAGS_eal_log.o := -D_GNU_SOURCE
 CFLAGS_eal_common_log.o := -D_GNU_SOURCE
 CFLAGS_eal_hugepage_info.o := -D_GNU_SOURCE
-CFLAGS_eal_pci.o := -D_GNU_SOURCE
-CFLAGS_eal_pci_uio.o := -D_GNU_SOURCE
-CFLAGS_eal_pci_vfio.o := -D_GNU_SOURCE
 CFLAGS_eal_common_whitelist.o := -D_GNU_SOURCE
 CFLAGS_eal_common_options.o := -D_GNU_SOURCE
 CFLAGS_eal_common_thread.o := -D_GNU_SOURCE
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index ec37c52..5005e6d 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -71,7 +71,6 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_bus.h>
-#include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_version.h>
diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
index 3e9ac41..0bebf00 100644
--- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
@@ -60,7 +60,6 @@
 #include <rte_branch_prediction.h>
 #include <rte_debug.h>
 #include <rte_log.h>
-#include <rte_pci.h>
 #include <rte_malloc.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
deleted file mode 100644
index b4dbf95..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ /dev/null
@@ -1,818 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <dirent.h>
-
-#include <rte_log.h>
-#include <rte_bus.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-#include <rte_devargs.h>
-#include <rte_memcpy.h>
-
-#include "eal_filesystem.h"
-#include "eal_private.h"
-#include "eal_pci_init.h"
-#include "eal_vfio.h"
-
-/**
- * @file
- * PCI probing under linux
- *
- * This code is used to simulate a PCI probe by parsing information in sysfs.
- * When a registered device matches a driver, it is then initialized with
- * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
- */
-
-extern struct rte_pci_bus rte_pci_bus;
-
-static int
-pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
-{
-	int count;
-	char path[PATH_MAX];
-	char *name;
-
-	if (!filename || !dri_name)
-		return -1;
-
-	count = readlink(filename, path, PATH_MAX);
-	if (count >= PATH_MAX)
-		return -1;
-
-	/* For device does not have a driver */
-	if (count < 0)
-		return 1;
-
-	path[count] = '\0';
-
-	name = strrchr(path, '/');
-	if (name) {
-		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
-		return 0;
-	}
-
-	return -1;
-}
-
-/* Map pci device */
-int
-rte_pci_map_device(struct rte_pci_device *dev)
-{
-	int ret = -1;
-
-	/* try mapping the NIC resources using VFIO if it exists */
-	switch (dev->kdrv) {
-	case RTE_KDRV_VFIO:
-#ifdef VFIO_PRESENT
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_map_resource(dev);
-#endif
-		break;
-	case RTE_KDRV_IGB_UIO:
-	case RTE_KDRV_UIO_GENERIC:
-		if (rte_eal_using_phys_addrs()) {
-			/* map resources for devices that use uio */
-			ret = pci_uio_map_resource(dev);
-		}
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		ret = 1;
-		break;
-	}
-
-	return ret;
-}
-
-/* Unmap pci device */
-void
-rte_pci_unmap_device(struct rte_pci_device *dev)
-{
-	/* try unmapping the NIC resources using VFIO if it exists */
-	switch (dev->kdrv) {
-	case RTE_KDRV_VFIO:
-#ifdef VFIO_PRESENT
-		if (pci_vfio_is_enabled())
-			pci_vfio_unmap_resource(dev);
-#endif
-		break;
-	case RTE_KDRV_IGB_UIO:
-	case RTE_KDRV_UIO_GENERIC:
-		/* unmap resources for devices that use uio */
-		pci_uio_unmap_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		break;
-	}
-}
-
-void *
-pci_find_max_end_va(void)
-{
-	const struct rte_memseg *seg = rte_eal_get_physmem_layout();
-	const struct rte_memseg *last = seg;
-	unsigned i = 0;
-
-	for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
-		if (seg->addr == NULL)
-			break;
-
-		if (seg->addr > last->addr)
-			last = seg;
-
-	}
-	return RTE_PTR_ADD(last->addr, last->len);
-}
-
-/* parse one line of the "resource" sysfs file (note that the 'line'
- * string is modified)
- */
-int
-pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
-	uint64_t *end_addr, uint64_t *flags)
-{
-	union pci_resource_info {
-		struct {
-			char *phys_addr;
-			char *end_addr;
-			char *flags;
-		};
-		char *ptrs[PCI_RESOURCE_FMT_NVAL];
-	} res_info;
-
-	if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
-		RTE_LOG(ERR, EAL,
-			"%s(): bad resource format\n", __func__);
-		return -1;
-	}
-	errno = 0;
-	*phys_addr = strtoull(res_info.phys_addr, NULL, 16);
-	*end_addr = strtoull(res_info.end_addr, NULL, 16);
-	*flags = strtoull(res_info.flags, NULL, 16);
-	if (errno != 0) {
-		RTE_LOG(ERR, EAL,
-			"%s(): bad resource format\n", __func__);
-		return -1;
-	}
-
-	return 0;
-}
-
-/* parse the "resource" sysfs file */
-static int
-pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
-{
-	FILE *f;
-	char buf[BUFSIZ];
-	int i;
-	uint64_t phys_addr, end_addr, flags;
-
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
-		return -1;
-	}
-
-	for (i = 0; i<PCI_MAX_RESOURCE; i++) {
-
-		if (fgets(buf, sizeof(buf), f) == NULL) {
-			RTE_LOG(ERR, EAL,
-				"%s(): cannot read resource\n", __func__);
-			goto error;
-		}
-		if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
-				&end_addr, &flags) < 0)
-			goto error;
-
-		if (flags & IORESOURCE_MEM) {
-			dev->mem_resource[i].phys_addr = phys_addr;
-			dev->mem_resource[i].len = end_addr - phys_addr + 1;
-			/* not mapped for now */
-			dev->mem_resource[i].addr = NULL;
-		}
-	}
-	fclose(f);
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
-}
-
-/* Scan one pci sysfs entry, and fill the devices list from it. */
-static int
-pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
-{
-	char filename[PATH_MAX];
-	unsigned long tmp;
-	struct rte_pci_device *dev;
-	char driver[PATH_MAX];
-	int ret;
-
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL)
-		return -1;
-
-	memset(dev, 0, sizeof(*dev));
-	dev->addr = *addr;
-
-	/* get vendor id */
-	snprintf(filename, sizeof(filename), "%s/vendor", dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.vendor_id = (uint16_t)tmp;
-
-	/* get device id */
-	snprintf(filename, sizeof(filename), "%s/device", dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.device_id = (uint16_t)tmp;
-
-	/* get subsystem_vendor id */
-	snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.subsystem_vendor_id = (uint16_t)tmp;
-
-	/* get subsystem_device id */
-	snprintf(filename, sizeof(filename), "%s/subsystem_device",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.subsystem_device_id = (uint16_t)tmp;
-
-	/* get class_id */
-	snprintf(filename, sizeof(filename), "%s/class",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	/* the least 24 bits are valid: class, subclass, program interface */
-	dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
-
-	/* get max_vfs */
-	dev->max_vfs = 0;
-	snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
-	if (!access(filename, F_OK) &&
-	    eal_parse_sysfs_value(filename, &tmp) == 0)
-		dev->max_vfs = (uint16_t)tmp;
-	else {
-		/* for non igb_uio driver, need kernel version >= 3.8 */
-		snprintf(filename, sizeof(filename),
-			 "%s/sriov_numvfs", dirname);
-		if (!access(filename, F_OK) &&
-		    eal_parse_sysfs_value(filename, &tmp) == 0)
-			dev->max_vfs = (uint16_t)tmp;
-	}
-
-	/* get numa node, default to 0 if not present */
-	snprintf(filename, sizeof(filename), "%s/numa_node",
-		 dirname);
-
-	if (access(filename, F_OK) != -1) {
-		if (eal_parse_sysfs_value(filename, &tmp) == 0)
-			dev->device.numa_node = tmp;
-		else
-			dev->device.numa_node = -1;
-	} else {
-		dev->device.numa_node = 0;
-	}
-
-	pci_name_set(dev);
-
-	/* parse resources */
-	snprintf(filename, sizeof(filename), "%s/resource", dirname);
-	if (pci_parse_sysfs_resource(filename, dev) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
-		free(dev);
-		return -1;
-	}
-
-	/* parse driver */
-	snprintf(filename, sizeof(filename), "%s/driver", dirname);
-	ret = pci_get_kernel_driver_by_path(filename, driver);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
-		free(dev);
-		return -1;
-	}
-
-	if (!ret) {
-		if (!strcmp(driver, "vfio-pci"))
-			dev->kdrv = RTE_KDRV_VFIO;
-		else if (!strcmp(driver, "igb_uio"))
-			dev->kdrv = RTE_KDRV_IGB_UIO;
-		else if (!strcmp(driver, "uio_pci_generic"))
-			dev->kdrv = RTE_KDRV_UIO_GENERIC;
-		else
-			dev->kdrv = RTE_KDRV_UNKNOWN;
-	} else
-		dev->kdrv = RTE_KDRV_NONE;
-
-	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-		rte_pci_add_device(dev);
-	} else {
-		struct rte_pci_device *dev2;
-		int ret;
-
-		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
-			if (ret > 0)
-				continue;
-
-			if (ret < 0) {
-				rte_pci_insert_device(dev2, dev);
-			} else { /* already registered */
-				dev2->kdrv = dev->kdrv;
-				dev2->max_vfs = dev->max_vfs;
-				pci_name_set(dev2);
-				memmove(dev2->mem_resource, dev->mem_resource,
-					sizeof(dev->mem_resource));
-				free(dev);
-			}
-			return 0;
-		}
-
-		rte_pci_add_device(dev);
-	}
-
-	return 0;
-}
-
-int
-pci_update_device(const struct rte_pci_addr *addr)
-{
-	char filename[PATH_MAX];
-
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
-		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
-		 addr->function);
-
-	return pci_scan_one(filename, addr);
-}
-
-/*
- * split up a pci address into its constituent parts.
- */
-static int
-parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
-{
-	/* first split on ':' */
-	union splitaddr {
-		struct {
-			char *domain;
-			char *bus;
-			char *devid;
-			char *function;
-		};
-		char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
-	} splitaddr;
-
-	char *buf_copy = strndup(buf, bufsize);
-	if (buf_copy == NULL)
-		return -1;
-
-	if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
-			!= PCI_FMT_NVAL - 1)
-		goto error;
-	/* final split is on '.' between devid and function */
-	splitaddr.function = strchr(splitaddr.devid,'.');
-	if (splitaddr.function == NULL)
-		goto error;
-	*splitaddr.function++ = '\0';
-
-	/* now convert to int values */
-	errno = 0;
-	addr->domain = strtoul(splitaddr.domain, NULL, 16);
-	addr->bus = strtoul(splitaddr.bus, NULL, 16);
-	addr->devid = strtoul(splitaddr.devid, NULL, 16);
-	addr->function = strtoul(splitaddr.function, NULL, 10);
-	if (errno != 0)
-		goto error;
-
-	free(buf_copy); /* free the copy made with strdup */
-	return 0;
-error:
-	free(buf_copy);
-	return -1;
-}
-
-/*
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- */
-int
-rte_pci_scan(void)
-{
-	struct dirent *e;
-	DIR *dir;
-	char dirname[PATH_MAX];
-	struct rte_pci_addr addr;
-
-	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
-		return 0;
-
-	dir = opendir(pci_get_sysfs_path());
-	if (dir == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
-			__func__, strerror(errno));
-		return -1;
-	}
-
-	while ((e = readdir(dir)) != NULL) {
-		if (e->d_name[0] == '.')
-			continue;
-
-		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
-			continue;
-
-		snprintf(dirname, sizeof(dirname), "%s/%s",
-				pci_get_sysfs_path(), e->d_name);
-
-		if (pci_scan_one(dirname, &addr) < 0)
-			goto error;
-	}
-	closedir(dir);
-	return 0;
-
-error:
-	closedir(dir);
-	return -1;
-}
-
-/*
- * Is pci device bound to any kdrv
- */
-static inline int
-pci_one_device_is_bound(void)
-{
-	struct rte_pci_device *dev = NULL;
-	int ret = 0;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (dev->kdrv == RTE_KDRV_UNKNOWN ||
-		    dev->kdrv == RTE_KDRV_NONE) {
-			continue;
-		} else {
-			ret = 1;
-			break;
-		}
-	}
-	return ret;
-}
-
-/*
- * Any one of the device bound to uio
- */
-static inline int
-pci_one_device_bound_uio(void)
-{
-	struct rte_pci_device *dev = NULL;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (dev->kdrv == RTE_KDRV_IGB_UIO ||
-		   dev->kdrv == RTE_KDRV_UIO_GENERIC) {
-			return 1;
-		}
-	}
-	return 0;
-}
-
-/*
- * Any one of the device has iova as va
- */
-static inline int
-pci_one_device_has_iova_va(void)
-{
-	struct rte_pci_device *dev = NULL;
-	struct rte_pci_driver *drv = NULL;
-
-	FOREACH_DRIVER_ON_PCIBUS(drv) {
-		if (drv && drv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) {
-			FOREACH_DEVICE_ON_PCIBUS(dev) {
-				if (dev->kdrv == RTE_KDRV_VFIO &&
-				    rte_pci_match(drv, dev))
-					return 1;
-			}
-		}
-	}
-	return 0;
-}
-
-/*
- * Get iommu class of PCI devices on the bus.
- */
-enum rte_iova_mode
-rte_pci_get_iommu_class(void)
-{
-	bool is_bound;
-	bool is_vfio_noiommu_enabled = true;
-	bool has_iova_va;
-	bool is_bound_uio;
-
-	is_bound = pci_one_device_is_bound();
-	if (!is_bound)
-		return RTE_IOVA_DC;
-
-	has_iova_va = pci_one_device_has_iova_va();
-	is_bound_uio = pci_one_device_bound_uio();
-#ifdef VFIO_PRESENT
-	is_vfio_noiommu_enabled = vfio_noiommu_is_enabled() == true ?
-					true : false;
-#endif
-
-	if (has_iova_va && !is_bound_uio && !is_vfio_noiommu_enabled)
-		return RTE_IOVA_VA;
-
-	if (has_iova_va) {
-		RTE_LOG(WARNING, EAL, "Some devices want iova as va but pa will be used because.. ");
-		if (is_vfio_noiommu_enabled)
-			RTE_LOG(WARNING, EAL, "vfio-noiommu mode configured\n");
-		if (is_bound_uio)
-			RTE_LOG(WARNING, EAL, "few device bound to UIO\n");
-	}
-
-	return RTE_IOVA_PA;
-}
-
-/* Read PCI config space. */
-int rte_pci_read_config(const struct rte_pci_device *device,
-		void *buf, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &device->intr_handle;
-
-	switch (intr_handle->type) {
-	case RTE_INTR_HANDLE_UIO:
-	case RTE_INTR_HANDLE_UIO_INTX:
-		return pci_uio_read_config(intr_handle, buf, len, offset);
-
-#ifdef VFIO_PRESENT
-	case RTE_INTR_HANDLE_VFIO_MSIX:
-	case RTE_INTR_HANDLE_VFIO_MSI:
-	case RTE_INTR_HANDLE_VFIO_LEGACY:
-		return pci_vfio_read_config(intr_handle, buf, len, offset);
-#endif
-	default:
-		RTE_LOG(ERR, EAL,
-			"Unknown handle type of fd %d\n",
-					intr_handle->fd);
-		return -1;
-	}
-}
-
-/* Write PCI config space. */
-int rte_pci_write_config(const struct rte_pci_device *device,
-		const void *buf, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &device->intr_handle;
-
-	switch (intr_handle->type) {
-	case RTE_INTR_HANDLE_UIO:
-	case RTE_INTR_HANDLE_UIO_INTX:
-		return pci_uio_write_config(intr_handle, buf, len, offset);
-
-#ifdef VFIO_PRESENT
-	case RTE_INTR_HANDLE_VFIO_MSIX:
-	case RTE_INTR_HANDLE_VFIO_MSI:
-	case RTE_INTR_HANDLE_VFIO_LEGACY:
-		return pci_vfio_write_config(intr_handle, buf, len, offset);
-#endif
-	default:
-		RTE_LOG(ERR, EAL,
-			"Unknown handle type of fd %d\n",
-					intr_handle->fd);
-		return -1;
-	}
-}
-
-#if defined(RTE_ARCH_X86)
-static int
-pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
-		struct rte_pci_ioport *p)
-{
-	uint16_t start, end;
-	FILE *fp;
-	char *line = NULL;
-	char pci_id[16];
-	int found = 0;
-	size_t linesz;
-
-	snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
-		 dev->addr.domain, dev->addr.bus,
-		 dev->addr.devid, dev->addr.function);
-
-	fp = fopen("/proc/ioports", "r");
-	if (fp == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);
-		return -1;
-	}
-
-	while (getdelim(&line, &linesz, '\n', fp) > 0) {
-		char *ptr = line;
-		char *left;
-		int n;
-
-		n = strcspn(ptr, ":");
-		ptr[n] = 0;
-		left = &ptr[n + 1];
-
-		while (*left && isspace(*left))
-			left++;
-
-		if (!strncmp(left, pci_id, strlen(pci_id))) {
-			found = 1;
-
-			while (*ptr && isspace(*ptr))
-				ptr++;
-
-			sscanf(ptr, "%04hx-%04hx", &start, &end);
-
-			break;
-		}
-	}
-
-	free(line);
-	fclose(fp);
-
-	if (!found)
-		return -1;
-
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	p->base = start;
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
-
-	return 0;
-}
-#endif
-
-int
-rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p)
-{
-	int ret = -1;
-
-	switch (dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_ioport_map(dev, bar, p);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		ret = pci_uio_ioport_map(dev, bar, p);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-#if defined(RTE_ARCH_X86)
-		ret = pci_ioport_map(dev, bar, p);
-#else
-		ret = pci_uio_ioport_map(dev, bar, p);
-#endif
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		ret = pci_ioport_map(dev, bar, p);
-#endif
-		break;
-	default:
-		break;
-	}
-
-	if (!ret)
-		p->dev = dev;
-
-	return ret;
-}
-
-void
-rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		pci_vfio_ioport_read(p, data, len, offset);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		pci_uio_ioport_read(p, data, len, offset);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-void
-rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		pci_vfio_ioport_write(p, data, len, offset);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		pci_uio_ioport_write(p, data, len, offset);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-int
-rte_pci_ioport_unmap(struct rte_pci_ioport *p)
-{
-	int ret = -1;
-
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_ioport_unmap(p);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		ret = pci_uio_ioport_unmap(p);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-#if defined(RTE_ARCH_X86)
-		ret = 0;
-#else
-		ret = pci_uio_ioport_unmap(p);
-#endif
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		ret = 0;
-#endif
-		break;
-	default:
-		break;
-	}
-
-	return ret;
-}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
deleted file mode 100644
index ae2980d..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_init.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef EAL_PCI_INIT_H_
-#define EAL_PCI_INIT_H_
-
-#include "eal_vfio.h"
-
-/** IO resource type: */
-#define IORESOURCE_IO         0x00000100
-#define IORESOURCE_MEM        0x00000200
-
-/*
- * Helper function to map PCI resources right after hugepages in virtual memory
- */
-extern void *pci_map_addr;
-void *pci_find_max_end_va(void);
-
-/* parse one line of the "resource" sysfs file (note that the 'line'
- * string is modified)
- */
-int pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
-	uint64_t *end_addr, uint64_t *flags);
-
-int pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res);
-void pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res);
-int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx);
-
-int pci_uio_read_config(const struct rte_intr_handle *intr_handle,
-			void *buf, size_t len, off_t offs);
-int pci_uio_write_config(const struct rte_intr_handle *intr_handle,
-			 const void *buf, size_t len, off_t offs);
-
-int pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		       struct rte_pci_ioport *p);
-void pci_uio_ioport_read(struct rte_pci_ioport *p,
-			 void *data, size_t len, off_t offset);
-void pci_uio_ioport_write(struct rte_pci_ioport *p,
-			  const void *data, size_t len, off_t offset);
-int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
-
-#ifdef VFIO_PRESENT
-
-/* access config space */
-int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
-			 void *buf, size_t len, off_t offs);
-int pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
-			  const void *buf, size_t len, off_t offs);
-
-int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
-		        struct rte_pci_ioport *p);
-void pci_vfio_ioport_read(struct rte_pci_ioport *p,
-			  void *data, size_t len, off_t offset);
-void pci_vfio_ioport_write(struct rte_pci_ioport *p,
-			   const void *data, size_t len, off_t offset);
-int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
-
-/* map/unmap VFIO resource prototype */
-int pci_vfio_map_resource(struct rte_pci_device *dev);
-int pci_vfio_unmap_resource(struct rte_pci_device *dev);
-
-#endif
-
-#endif /* EAL_PCI_INIT_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
deleted file mode 100644
index b639ab9..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/sysmacros.h>
-#include <linux/pci_regs.h>
-
-#if defined(RTE_ARCH_X86)
-#include <sys/io.h>
-#endif
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-
-void *pci_map_addr = NULL;
-
-#define OFF_MAX              ((uint64_t)(off_t)-1)
-
-int
-pci_uio_read_config(const struct rte_intr_handle *intr_handle,
-		    void *buf, size_t len, off_t offset)
-{
-	return pread(intr_handle->uio_cfg_fd, buf, len, offset);
-}
-
-int
-pci_uio_write_config(const struct rte_intr_handle *intr_handle,
-		     const void *buf, size_t len, off_t offset)
-{
-	return pwrite(intr_handle->uio_cfg_fd, buf, len, offset);
-}
-
-static int
-pci_uio_set_bus_master(int dev_fd)
-{
-	uint16_t reg;
-	int ret;
-
-	ret = pread(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL,
-			"Cannot read command from PCI config space!\n");
-		return -1;
-	}
-
-	/* return if bus mastering is already on */
-	if (reg & PCI_COMMAND_MASTER)
-		return 0;
-
-	reg |= PCI_COMMAND_MASTER;
-
-	ret = pwrite(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL,
-			"Cannot write command to PCI config space!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-static int
-pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
-{
-	FILE *f;
-	char filename[PATH_MAX];
-	int ret;
-	unsigned major, minor;
-	dev_t dev;
-
-	/* get the name of the sysfs file that contains the major and minor
-	 * of the uio device and read its content */
-	snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path);
-
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n",
-			__func__);
-		return -1;
-	}
-
-	ret = fscanf(f, "%u:%u", &major, &minor);
-	if (ret != 2) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n",
-			__func__);
-		fclose(f);
-		return -1;
-	}
-	fclose(f);
-
-	/* create the char device "mknod /dev/uioX c major minor" */
-	snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
-	dev = makedev(major, minor);
-	ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
-	if (ret != 0) {
-		RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
-			__func__, strerror(errno));
-		return -1;
-	}
-
-	return ret;
-}
-
-/*
- * Return the uioX char device used for a pci device. On success, return
- * the UIO number and fill dstbuf string with the path of the device in
- * sysfs. On error, return a negative value. In this case dstbuf is
- * invalid.
- */
-static int
-pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
-			   unsigned int buflen, int create)
-{
-	struct rte_pci_addr *loc = &dev->addr;
-	int uio_num = -1;
-	struct dirent *e;
-	DIR *dir;
-	char dirname[PATH_MAX];
-
-	/* depending on kernel version, uio can be located in uio/uioX
-	 * or uio:uioX */
-
-	snprintf(dirname, sizeof(dirname),
-			"%s/" PCI_PRI_FMT "/uio", pci_get_sysfs_path(),
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	dir = opendir(dirname);
-	if (dir == NULL) {
-		/* retry with the parent directory */
-		snprintf(dirname, sizeof(dirname),
-				"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
-				loc->domain, loc->bus, loc->devid, loc->function);
-		dir = opendir(dirname);
-
-		if (dir == NULL) {
-			RTE_LOG(ERR, EAL, "Cannot opendir %s\n", dirname);
-			return -1;
-		}
-	}
-
-	/* take the first file starting with "uio" */
-	while ((e = readdir(dir)) != NULL) {
-		/* format could be uio%d ...*/
-		int shortprefix_len = sizeof("uio") - 1;
-		/* ... or uio:uio%d */
-		int longprefix_len = sizeof("uio:uio") - 1;
-		char *endptr;
-
-		if (strncmp(e->d_name, "uio", 3) != 0)
-			continue;
-
-		/* first try uio%d */
-		errno = 0;
-		uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
-		if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
-			snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
-			break;
-		}
-
-		/* then try uio:uio%d */
-		errno = 0;
-		uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
-		if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
-			snprintf(dstbuf, buflen, "%s/uio:uio%u", dirname, uio_num);
-			break;
-		}
-	}
-	closedir(dir);
-
-	/* No uio resource found */
-	if (e == NULL)
-		return -1;
-
-	/* create uio device if we've been asked to */
-	if (internal_config.create_uio_dev && create &&
-			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
-		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
-
-	return uio_num;
-}
-
-void
-pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res)
-{
-	rte_free(uio_res);
-
-	if (dev->intr_handle.uio_cfg_fd >= 0) {
-		close(dev->intr_handle.uio_cfg_fd);
-		dev->intr_handle.uio_cfg_fd = -1;
-	}
-	if (dev->intr_handle.fd >= 0) {
-		close(dev->intr_handle.fd);
-		dev->intr_handle.fd = -1;
-		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	}
-}
-
-int
-pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res)
-{
-	char dirname[PATH_MAX];
-	char cfgname[PATH_MAX];
-	char devname[PATH_MAX]; /* contains the /dev/uioX */
-	int uio_num;
-	struct rte_pci_addr *loc;
-
-	loc = &dev->addr;
-
-	/* find uio resource */
-	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 1);
-	if (uio_num < 0) {
-		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
-				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
-		return 1;
-	}
-	snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
-
-	/* save fd if in primary process */
-	dev->intr_handle.fd = open(devname, O_RDWR);
-	if (dev->intr_handle.fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			devname, strerror(errno));
-		goto error;
-	}
-
-	snprintf(cfgname, sizeof(cfgname),
-			"/sys/class/uio/uio%u/device/config", uio_num);
-	dev->intr_handle.uio_cfg_fd = open(cfgname, O_RDWR);
-	if (dev->intr_handle.uio_cfg_fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			cfgname, strerror(errno));
-		goto error;
-	}
-
-	if (dev->kdrv == RTE_KDRV_IGB_UIO)
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-	else {
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
-
-		/* set bus master that is not done by uio_pci_generic */
-		if (pci_uio_set_bus_master(dev->intr_handle.uio_cfg_fd)) {
-			RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
-			goto error;
-		}
-	}
-
-	/* allocate the mapping details for secondary processes*/
-	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
-	if (*uio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto error;
-	}
-
-	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
-	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
-
-	return 0;
-
-error:
-	pci_uio_free_resource(dev, *uio_res);
-	return -1;
-}
-
-int
-pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx)
-{
-	int fd;
-	char devname[PATH_MAX];
-	void *mapaddr;
-	struct rte_pci_addr *loc;
-	struct pci_map *maps;
-
-	loc = &dev->addr;
-	maps = uio_res->maps;
-
-	/* update devname for mmap  */
-	snprintf(devname, sizeof(devname),
-			"%s/" PCI_PRI_FMT "/resource%d",
-			pci_get_sysfs_path(),
-			loc->domain, loc->bus, loc->devid,
-			loc->function, res_idx);
-
-	/* allocate memory to keep path */
-	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
-	if (maps[map_idx].path == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
-				strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * open resource file, to mmap it
-	 */
-	fd = open(devname, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				devname, strerror(errno));
-		goto error;
-	}
-
-	/* try mapping somewhere close to the end of hugepages */
-	if (pci_map_addr == NULL)
-		pci_map_addr = pci_find_max_end_va();
-
-	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
-			(size_t)dev->mem_resource[res_idx].len, 0);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		goto error;
-
-	pci_map_addr = RTE_PTR_ADD(mapaddr,
-			(size_t)dev->mem_resource[res_idx].len);
-
-	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
-	maps[map_idx].size = dev->mem_resource[res_idx].len;
-	maps[map_idx].addr = mapaddr;
-	maps[map_idx].offset = 0;
-	strcpy(maps[map_idx].path, devname);
-	dev->mem_resource[res_idx].addr = mapaddr;
-
-	return 0;
-
-error:
-	rte_free(maps[map_idx].path);
-	return -1;
-}
-
-#if defined(RTE_ARCH_X86)
-int
-pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		   struct rte_pci_ioport *p)
-{
-	char dirname[PATH_MAX];
-	char filename[PATH_MAX];
-	int uio_num;
-	unsigned long start;
-
-	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 0);
-	if (uio_num < 0)
-		return -1;
-
-	/* get portio start */
-	snprintf(filename, sizeof(filename),
-		 "%s/portio/port%d/start", dirname, bar);
-	if (eal_parse_sysfs_value(filename, &start) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
-			__func__);
-		return -1;
-	}
-	/* ensure we don't get anything funny here, read/write will cast to
-	 * uin16_t */
-	if (start > UINT16_MAX)
-		return -1;
-
-	/* FIXME only for primary process ? */
-	if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {
-
-		snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
-		dev->intr_handle.fd = open(filename, O_RDWR);
-		if (dev->intr_handle.fd < 0) {
-			RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				filename, strerror(errno));
-			return -1;
-		}
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-	}
-
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);
-
-	p->base = start;
-	p->len = 0;
-	return 0;
-}
-#else
-int
-pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		   struct rte_pci_ioport *p)
-{
-	FILE *f;
-	char buf[BUFSIZ];
-	char filename[PATH_MAX];
-	uint64_t phys_addr, end_addr, flags;
-	int fd, i;
-	void *addr;
-
-	/* open and read addresses of the corresponding resource in sysfs */
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
-		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
-		dev->addr.devid, dev->addr.function);
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",
-			strerror(errno));
-		return -1;
-	}
-	for (i = 0; i < bar + 1; i++) {
-		if (fgets(buf, sizeof(buf), f) == NULL) {
-			RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");
-			goto error;
-		}
-	}
-	if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
-			&end_addr, &flags) < 0)
-		goto error;
-	if ((flags & IORESOURCE_IO) == 0) {
-		RTE_LOG(ERR, EAL, "BAR %d is not an IO resource\n", bar);
-		goto error;
-	}
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
-		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
-		dev->addr.devid, dev->addr.function, bar);
-
-	/* mmap the pci resource */
-	fd = open(filename, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
-			strerror(errno));
-		goto error;
-	}
-	addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
-		MAP_SHARED, fd, 0);
-	close(fd);
-	if (addr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s\n",
-			strerror(errno));
-		goto error;
-	}
-
-	/* strangely, the base address is mmap addr + phys_addr */
-	p->base = (uintptr_t)addr + phys_addr;
-	p->len = end_addr + 1;
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"\n", p->base);
-	fclose(f);
-
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
-}
-#endif
-
-void
-pci_uio_ioport_read(struct rte_pci_ioport *p,
-		    void *data, size_t len, off_t offset)
-{
-	uint8_t *d;
-	int size;
-	uintptr_t reg = p->base + offset;
-
-	for (d = data; len > 0; d += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-#if defined(RTE_ARCH_X86)
-			*(uint32_t *)d = inl(reg);
-#else
-			*(uint32_t *)d = *(volatile uint32_t *)reg;
-#endif
-		} else if (len >= 2) {
-			size = 2;
-#if defined(RTE_ARCH_X86)
-			*(uint16_t *)d = inw(reg);
-#else
-			*(uint16_t *)d = *(volatile uint16_t *)reg;
-#endif
-		} else {
-			size = 1;
-#if defined(RTE_ARCH_X86)
-			*d = inb(reg);
-#else
-			*d = *(volatile uint8_t *)reg;
-#endif
-		}
-	}
-}
-
-void
-pci_uio_ioport_write(struct rte_pci_ioport *p,
-		     const void *data, size_t len, off_t offset)
-{
-	const uint8_t *s;
-	int size;
-	uintptr_t reg = p->base + offset;
-
-	for (s = data; len > 0; s += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-#if defined(RTE_ARCH_X86)
-			outl_p(*(const uint32_t *)s, reg);
-#else
-			*(volatile uint32_t *)reg = *(const uint32_t *)s;
-#endif
-		} else if (len >= 2) {
-			size = 2;
-#if defined(RTE_ARCH_X86)
-			outw_p(*(const uint16_t *)s, reg);
-#else
-			*(volatile uint16_t *)reg = *(const uint16_t *)s;
-#endif
-		} else {
-			size = 1;
-#if defined(RTE_ARCH_X86)
-			outb_p(*s, reg);
-#else
-			*(volatile uint8_t *)reg = *s;
-#endif
-		}
-	}
-}
-
-int
-pci_uio_ioport_unmap(struct rte_pci_ioport *p)
-{
-#if defined(RTE_ARCH_X86)
-	RTE_SET_USED(p);
-	/* FIXME close intr fd ? */
-	return 0;
-#else
-	return munmap((void *)(uintptr_t)p->base, p->len);
-#endif
-}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
deleted file mode 100644
index 10a75da..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ /dev/null
@@ -1,756 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <fcntl.h>
-#include <linux/pci_regs.h>
-#include <sys/eventfd.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <stdbool.h>
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-#include "eal_vfio.h"
-#include "eal_private.h"
-
-/**
- * @file
- * PCI probing under linux (VFIO version)
- *
- * This code tries to determine if the PCI device is bound to VFIO driver,
- * and initialize it (map BARs, set up interrupts) if that's the case.
- *
- * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
- */
-
-#ifdef VFIO_PRESENT
-
-#define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
-#define PAGE_MASK   (~(PAGE_SIZE - 1))
-
-static struct rte_tailq_elem rte_vfio_tailq = {
-	.name = "VFIO_RESOURCE_LIST",
-};
-EAL_REGISTER_TAILQ(rte_vfio_tailq)
-
-int
-pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
-		    void *buf, size_t len, off_t offs)
-{
-	return pread64(intr_handle->vfio_dev_fd, buf, len,
-	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
-}
-
-int
-pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
-		    const void *buf, size_t len, off_t offs)
-{
-	return pwrite64(intr_handle->vfio_dev_fd, buf, len,
-	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
-}
-
-/* get PCI BAR number where MSI-X interrupts are */
-static int
-pci_vfio_get_msix_bar(int fd, struct pci_msix_table *msix_table)
-{
-	int ret;
-	uint32_t reg;
-	uint16_t flags;
-	uint8_t cap_id, cap_offset;
-
-	/* read PCI capability pointer from config space */
-	ret = pread64(fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_CAPABILITY_LIST);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
-				"config space!\n");
-		return -1;
-	}
-
-	/* we need first byte */
-	cap_offset = reg & 0xFF;
-
-	while (cap_offset) {
-
-		/* read PCI capability ID */
-		ret = pread64(fd, &reg, sizeof(reg),
-				VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-				cap_offset);
-		if (ret != sizeof(reg)) {
-			RTE_LOG(ERR, EAL, "Cannot read capability ID from PCI "
-					"config space!\n");
-			return -1;
-		}
-
-		/* we need first byte */
-		cap_id = reg & 0xFF;
-
-		/* if we haven't reached MSI-X, check next capability */
-		if (cap_id != PCI_CAP_ID_MSIX) {
-			ret = pread64(fd, &reg, sizeof(reg),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset);
-			if (ret != sizeof(reg)) {
-				RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
-						"config space!\n");
-				return -1;
-			}
-
-			/* we need second byte */
-			cap_offset = (reg & 0xFF00) >> 8;
-
-			continue;
-		}
-		/* else, read table offset */
-		else {
-			/* table offset resides in the next 4 bytes */
-			ret = pread64(fd, &reg, sizeof(reg),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset + 4);
-			if (ret != sizeof(reg)) {
-				RTE_LOG(ERR, EAL, "Cannot read table offset from PCI config "
-						"space!\n");
-				return -1;
-			}
-
-			ret = pread64(fd, &flags, sizeof(flags),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset + 2);
-			if (ret != sizeof(flags)) {
-				RTE_LOG(ERR, EAL, "Cannot read table flags from PCI config "
-						"space!\n");
-				return -1;
-			}
-
-			msix_table->bar_index = reg & RTE_PCI_MSIX_TABLE_BIR;
-			msix_table->offset = reg & RTE_PCI_MSIX_TABLE_OFFSET;
-			msix_table->size =
-				16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE));
-
-			return 0;
-		}
-	}
-	return 0;
-}
-
-/* set PCI bus mastering */
-static int
-pci_vfio_set_bus_master(int dev_fd, bool op)
-{
-	uint16_t reg;
-	int ret;
-
-	ret = pread64(dev_fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n");
-		return -1;
-	}
-
-	if (op)
-		/* set the master bit */
-		reg |= PCI_COMMAND_MASTER;
-	else
-		reg &= ~(PCI_COMMAND_MASTER);
-
-	ret = pwrite64(dev_fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_COMMAND);
-
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-/* set up interrupt support (but not enable interrupts) */
-static int
-pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
-{
-	int i, ret, intr_idx;
-
-	/* default to invalid index */
-	intr_idx = VFIO_PCI_NUM_IRQS;
-
-	/* get interrupt type from internal config (MSI-X by default, can be
-	 * overridden from the command line
-	 */
-	switch (internal_config.vfio_intr_mode) {
-	case RTE_INTR_MODE_MSIX:
-		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
-		break;
-	case RTE_INTR_MODE_MSI:
-		intr_idx = VFIO_PCI_MSI_IRQ_INDEX;
-		break;
-	case RTE_INTR_MODE_LEGACY:
-		intr_idx = VFIO_PCI_INTX_IRQ_INDEX;
-		break;
-	/* don't do anything if we want to automatically determine interrupt type */
-	case RTE_INTR_MODE_NONE:
-		break;
-	default:
-		RTE_LOG(ERR, EAL, "  unknown default interrupt type!\n");
-		return -1;
-	}
-
-	/* start from MSI-X interrupt type */
-	for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) {
-		struct vfio_irq_info irq = { .argsz = sizeof(irq) };
-		int fd = -1;
-
-		/* skip interrupt modes we don't want */
-		if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE &&
-				i != intr_idx)
-			continue;
-
-		irq.index = i;
-
-		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  cannot get IRQ info, "
-					"error %i (%s)\n", errno, strerror(errno));
-			return -1;
-		}
-
-		/* if this vector cannot be used with eventfd, fail if we explicitly
-		 * specified interrupt type, otherwise continue */
-		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
-			if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE) {
-				RTE_LOG(ERR, EAL,
-						"  interrupt vector does not support eventfd!\n");
-				return -1;
-			} else
-				continue;
-		}
-
-		/* set up an eventfd for interrupts */
-		fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
-		if (fd < 0) {
-			RTE_LOG(ERR, EAL, "  cannot set up eventfd, "
-					"error %i (%s)\n", errno, strerror(errno));
-			return -1;
-		}
-
-		dev->intr_handle.fd = fd;
-		dev->intr_handle.vfio_dev_fd = vfio_dev_fd;
-
-		switch (i) {
-		case VFIO_PCI_MSIX_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSIX;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
-			break;
-		case VFIO_PCI_MSI_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSI;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
-			break;
-		case VFIO_PCI_INTX_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_LEGACY;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
-			break;
-		default:
-			RTE_LOG(ERR, EAL, "  unknown interrupt type!\n");
-			return -1;
-		}
-
-		return 0;
-	}
-
-	/* if we're here, we haven't found a suitable interrupt vector */
-	return -1;
-}
-
-static int
-pci_vfio_is_ioport_bar(int vfio_dev_fd, int bar_index)
-{
-	uint32_t ioport_bar;
-	int ret;
-
-	ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar),
-			  VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX)
-			  + PCI_BASE_ADDRESS_0 + bar_index*4);
-	if (ret != sizeof(ioport_bar)) {
-		RTE_LOG(ERR, EAL, "Cannot read command (%x) from config space!\n",
-			PCI_BASE_ADDRESS_0 + bar_index*4);
-		return -1;
-	}
-
-	return (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) != 0;
-}
-
-static int
-pci_vfio_setup_device(struct rte_pci_device *dev, int vfio_dev_fd)
-{
-	if (pci_vfio_setup_interrupts(dev, vfio_dev_fd) != 0) {
-		RTE_LOG(ERR, EAL, "Error setting up interrupts!\n");
-		return -1;
-	}
-
-	/* set bus mastering for the device */
-	if (pci_vfio_set_bus_master(vfio_dev_fd, true)) {
-		RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
-		return -1;
-	}
-
-	/* Reset the device */
-	ioctl(vfio_dev_fd, VFIO_DEVICE_RESET);
-
-	return 0;
-}
-
-static int
-pci_vfio_mmap_bar(int vfio_dev_fd, struct mapped_pci_resource *vfio_res,
-		int bar_index, int additional_flags)
-{
-	struct memreg {
-		unsigned long offset, size;
-	} memreg[2] = {};
-	void *bar_addr;
-	struct pci_msix_table *msix_table = &vfio_res->msix_table;
-	struct pci_map *bar = &vfio_res->maps[bar_index];
-
-	if (bar->size == 0)
-		/* Skip this BAR */
-		return 0;
-
-	if (msix_table->bar_index == bar_index) {
-		/*
-		 * VFIO will not let us map the MSI-X table,
-		 * but we can map around it.
-		 */
-		uint32_t table_start = msix_table->offset;
-		uint32_t table_end = table_start + msix_table->size;
-		table_end = (table_end + ~PAGE_MASK) & PAGE_MASK;
-		table_start &= PAGE_MASK;
-
-		if (table_start == 0 && table_end >= bar->size) {
-			/* Cannot map this BAR */
-			RTE_LOG(DEBUG, EAL, "Skipping BAR%d\n", bar_index);
-			bar->size = 0;
-			bar->addr = 0;
-			return 0;
-		}
-
-		memreg[0].offset = bar->offset;
-		memreg[0].size = table_start;
-		memreg[1].offset = bar->offset + table_end;
-		memreg[1].size = bar->size - table_end;
-
-		RTE_LOG(DEBUG, EAL,
-			"Trying to map BAR%d that contains the MSI-X "
-			"table. Trying offsets: "
-			"0x%04lx:0x%04lx, 0x%04lx:0x%04lx\n", bar_index,
-			memreg[0].offset, memreg[0].size,
-			memreg[1].offset, memreg[1].size);
-	} else {
-		memreg[0].offset = bar->offset;
-		memreg[0].size = bar->size;
-	}
-
-	/* reserve the address using an inaccessible mapping */
-	bar_addr = mmap(bar->addr, bar->size, 0, MAP_PRIVATE |
-			MAP_ANONYMOUS | additional_flags, -1, 0);
-	if (bar_addr != MAP_FAILED) {
-		void *map_addr = NULL;
-		if (memreg[0].size) {
-			/* actual map of first part */
-			map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
-							memreg[0].offset,
-							memreg[0].size,
-							MAP_FIXED);
-		}
-
-		/* if there's a second part, try to map it */
-		if (map_addr != MAP_FAILED
-			&& memreg[1].offset && memreg[1].size) {
-			void *second_addr = RTE_PTR_ADD(bar_addr,
-							memreg[1].offset -
-							(uintptr_t)bar->offset);
-			map_addr = pci_map_resource(second_addr,
-							vfio_dev_fd,
-							memreg[1].offset,
-							memreg[1].size,
-							MAP_FIXED);
-		}
-
-		if (map_addr == MAP_FAILED || !map_addr) {
-			munmap(bar_addr, bar->size);
-			bar_addr = MAP_FAILED;
-			RTE_LOG(ERR, EAL, "Failed to map pci BAR%d\n",
-					bar_index);
-			return -1;
-		}
-	} else {
-		RTE_LOG(ERR, EAL,
-				"Failed to create inaccessible mapping for BAR%d\n",
-				bar_index);
-		return -1;
-	}
-
-	bar->addr = bar_addr;
-	return 0;
-}
-
-static int
-pci_vfio_map_resource_primary(struct rte_pci_device *dev)
-{
-	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
-	char pci_addr[PATH_MAX] = {0};
-	int vfio_dev_fd;
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list =
-		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-
-	struct pci_map *maps;
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
-					&vfio_dev_fd, &device_info);
-	if (ret)
-		return ret;
-
-	/* allocate vfio_res and get region info */
-	vfio_res = rte_zmalloc("VFIO_RES", sizeof(*vfio_res), 0);
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto err_vfio_dev_fd;
-	}
-	memcpy(&vfio_res->pci_addr, &dev->addr, sizeof(vfio_res->pci_addr));
-
-	/* get number of registers (up to BAR5) */
-	vfio_res->nb_maps = RTE_MIN((int) device_info.num_regions,
-			VFIO_PCI_BAR5_REGION_INDEX + 1);
-
-	/* map BARs */
-	maps = vfio_res->maps;
-
-	vfio_res->msix_table.bar_index = -1;
-	/* get MSI-X BAR, if any (we have to know where it is because we can't
-	 * easily mmap it when using VFIO)
-	 */
-	ret = pci_vfio_get_msix_bar(vfio_dev_fd, &vfio_res->msix_table);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "  %s cannot get MSI-X BAR number!\n",
-				pci_addr);
-		goto err_vfio_dev_fd;
-	}
-
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-		struct vfio_region_info reg = { .argsz = sizeof(reg) };
-		void *bar_addr;
-
-		reg.index = i;
-
-		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg);
-		if (ret) {
-			RTE_LOG(ERR, EAL, "  %s cannot get device region info "
-					"error %i (%s)\n", pci_addr, errno, strerror(errno));
-			goto err_vfio_res;
-		}
-
-		/* chk for io port region */
-		ret = pci_vfio_is_ioport_bar(vfio_dev_fd, i);
-		if (ret < 0)
-			goto err_vfio_res;
-		else if (ret) {
-			RTE_LOG(INFO, EAL, "Ignore mapping IO port bar(%d)\n",
-					i);
-			continue;
-		}
-
-		/* skip non-mmapable BARs */
-		if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0)
-			continue;
-
-		/* try mapping somewhere close to the end of hugepages */
-		if (pci_map_addr == NULL)
-			pci_map_addr = pci_find_max_end_va();
-
-		bar_addr = pci_map_addr;
-		pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
-
-		maps[i].addr = bar_addr;
-		maps[i].offset = reg.offset;
-		maps[i].size = reg.size;
-		maps[i].path = NULL; /* vfio doesn't have per-resource paths */
-
-		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, 0);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
-					pci_addr, i, strerror(errno));
-			goto err_vfio_res;
-		}
-
-		dev->mem_resource[i].addr = maps[i].addr;
-	}
-
-	if (pci_vfio_setup_device(dev, vfio_dev_fd) < 0) {
-		RTE_LOG(ERR, EAL, "  %s setup device failed\n", pci_addr);
-		goto err_vfio_res;
-	}
-
-	TAILQ_INSERT_TAIL(vfio_res_list, vfio_res, next);
-
-	return 0;
-err_vfio_res:
-	rte_free(vfio_res);
-err_vfio_dev_fd:
-	close(vfio_dev_fd);
-	return -1;
-}
-
-static int
-pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
-{
-	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
-	char pci_addr[PATH_MAX] = {0};
-	int vfio_dev_fd;
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list =
-		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-
-	struct pci_map *maps;
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
-					&vfio_dev_fd, &device_info);
-	if (ret)
-		return ret;
-
-	/* if we're in a secondary process, just find our tailq entry */
-	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-		if (rte_eal_compare_pci_addr(&vfio_res->pci_addr,
-						 &dev->addr))
-			continue;
-		break;
-	}
-	/* if we haven't found our tailq entry, something's wrong */
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
-				pci_addr);
-		goto err_vfio_dev_fd;
-	}
-
-	/* map BARs */
-	maps = vfio_res->maps;
-
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, MAP_FIXED);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
-					pci_addr, i, strerror(errno));
-			goto err_vfio_dev_fd;
-		}
-
-		dev->mem_resource[i].addr = maps[i].addr;
-	}
-
-	return 0;
-err_vfio_dev_fd:
-	close(vfio_dev_fd);
-	return -1;
-}
-
-/*
- * map the PCI resources of a PCI device in virtual memory (VFIO version).
- * primary and secondary processes follow almost exactly the same path
- */
-int
-pci_vfio_map_resource(struct rte_pci_device *dev)
-{
-	if (internal_config.process_type == RTE_PROC_PRIMARY)
-		return pci_vfio_map_resource_primary(dev);
-	else
-		return pci_vfio_map_resource_secondary(dev);
-}
-
-int
-pci_vfio_unmap_resource(struct rte_pci_device *dev)
-{
-	char pci_addr[PATH_MAX] = {0};
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list;
-
-	struct pci_map *maps;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-
-	if (close(dev->intr_handle.fd) < 0) {
-		RTE_LOG(INFO, EAL, "Error when closing eventfd file descriptor for %s\n",
-			pci_addr);
-		return -1;
-	}
-
-	if (pci_vfio_set_bus_master(dev->intr_handle.vfio_dev_fd, false)) {
-		RTE_LOG(ERR, EAL, "  %s cannot unset bus mastering for PCI device!\n",
-				pci_addr);
-		return -1;
-	}
-
-	ret = vfio_release_device(pci_get_sysfs_path(), pci_addr,
-				  dev->intr_handle.vfio_dev_fd);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot release device\n", __func__);
-		return ret;
-	}
-
-	vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-	/* Get vfio_res */
-	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-		if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
-			continue;
-		break;
-	}
-	/* if we haven't found our tailq entry, something's wrong */
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
-				pci_addr);
-		return -1;
-	}
-
-	/* unmap BARs */
-	maps = vfio_res->maps;
-
-	RTE_LOG(INFO, EAL, "Releasing pci mapped resource for %s\n",
-		pci_addr);
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-
-		/*
-		 * We do not need to be aware of MSI-X table BAR mappings as
-		 * when mapping. Just using current maps array is enough
-		 */
-		if (maps[i].addr) {
-			RTE_LOG(INFO, EAL, "Calling pci_unmap_resource for %s at %p\n",
-				pci_addr, maps[i].addr);
-			pci_unmap_resource(maps[i].addr, maps[i].size);
-		}
-	}
-
-	TAILQ_REMOVE(vfio_res_list, vfio_res, next);
-
-	return 0;
-}
-
-int
-pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
-		    struct rte_pci_ioport *p)
-{
-	if (bar < VFIO_PCI_BAR0_REGION_INDEX ||
-	    bar > VFIO_PCI_BAR5_REGION_INDEX) {
-		RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar);
-		return -1;
-	}
-
-	p->dev = dev;
-	p->base = VFIO_GET_REGION_ADDR(bar);
-	return 0;
-}
-
-void
-pci_vfio_ioport_read(struct rte_pci_ioport *p,
-		     void *data, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
-
-	if (pread64(intr_handle->vfio_dev_fd, data,
-		    len, p->base + offset) <= 0)
-		RTE_LOG(ERR, EAL,
-			"Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n",
-			VFIO_GET_REGION_IDX(p->base), (int)offset);
-}
-
-void
-pci_vfio_ioport_write(struct rte_pci_ioport *p,
-		      const void *data, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
-
-	if (pwrite64(intr_handle->vfio_dev_fd, data,
-		     len, p->base + offset) <= 0)
-		RTE_LOG(ERR, EAL,
-			"Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n",
-			VFIO_GET_REGION_IDX(p->base), (int)offset);
-}
-
-int
-pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
-{
-	RTE_SET_USED(p);
-	return -1;
-}
-
-int
-pci_vfio_enable(void)
-{
-	return vfio_enable("vfio_pci");
-}
-
-int
-pci_vfio_is_enabled(void)
-{
-	return vfio_is_enabled("vfio_pci");
-}
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
deleted file mode 100644
index 537beeb..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <pthread.h>
-
-/* sys/un.h with __USE_MISC uses strlen, which is unsafe */
-#ifdef __USE_MISC
-#define REMOVED_USE_MISC
-#undef __USE_MISC
-#endif
-#include <sys/un.h>
-/* make sure we redefine __USE_MISC only if it was previously undefined */
-#ifdef REMOVED_USE_MISC
-#define __USE_MISC
-#undef REMOVED_USE_MISC
-#endif
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-#include "eal_thread.h"
-
-/**
- * @file
- * VFIO socket for communication between primary and secondary processes.
- *
- * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
- */
-
-#ifdef VFIO_PRESENT
-
-#define SOCKET_PATH_FMT "%s/.%s_mp_socket"
-#define CMSGLEN (CMSG_LEN(sizeof(int)))
-#define FD_TO_CMSGHDR(fd, chdr) \
-		do {\
-			(chdr).cmsg_len = CMSGLEN;\
-			(chdr).cmsg_level = SOL_SOCKET;\
-			(chdr).cmsg_type = SCM_RIGHTS;\
-			memcpy((chdr).__cmsg_data, &(fd), sizeof(fd));\
-		} while (0)
-#define CMSGHDR_TO_FD(chdr, fd) \
-			memcpy(&(fd), (chdr).__cmsg_data, sizeof(fd))
-
-static pthread_t socket_thread;
-static int mp_socket_fd;
-
-
-/* get socket path (/var/run if root, $HOME otherwise) */
-static void
-get_socket_path(char *buffer, int bufsz)
-{
-	const char *dir = "/var/run";
-	const char *home_dir = getenv("HOME");
-
-	if (getuid() != 0 && home_dir != NULL)
-		dir = home_dir;
-
-	/* use current prefix as file path */
-	snprintf(buffer, bufsz, SOCKET_PATH_FMT, dir,
-			internal_config.hugefile_prefix);
-}
-
-
-
-/*
- * data flow for socket comm protocol:
- * 1. client sends SOCKET_REQ_CONTAINER or SOCKET_REQ_GROUP
- * 1a. in case of SOCKET_REQ_GROUP, client also then sends group number
- * 2. server receives message
- * 2a. in case of invalid group, SOCKET_ERR is sent back to client
- * 2b. in case of unbound group, SOCKET_NO_FD is sent back to client
- * 2c. in case of valid group, SOCKET_OK is sent and immediately followed by fd
- *
- * in case of any error, socket is closed.
- */
-
-/* send a request, return -1 on error */
-int
-vfio_mp_sync_send_request(int socket, int req)
-{
-	struct msghdr hdr;
-	struct iovec iov;
-	int buf;
-	int ret;
-
-	memset(&hdr, 0, sizeof(hdr));
-
-	buf = req;
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-
-	ret = sendmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-	return 0;
-}
-
-/* receive a request and return it */
-int
-vfio_mp_sync_receive_request(int socket)
-{
-	int buf;
-	struct msghdr hdr;
-	struct iovec iov;
-	int ret, req;
-
-	memset(&hdr, 0, sizeof(hdr));
-
-	buf = SOCKET_ERR;
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-
-	ret = recvmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-
-	req = buf;
-
-	return req;
-}
-
-/* send OK in message, fd in control message */
-int
-vfio_mp_sync_send_fd(int socket, int fd)
-{
-	int buf;
-	struct msghdr hdr;
-	struct cmsghdr *chdr;
-	char chdr_buf[CMSGLEN];
-	struct iovec iov;
-	int ret;
-
-	chdr = (struct cmsghdr *) chdr_buf;
-	memset(chdr, 0, sizeof(chdr_buf));
-	memset(&hdr, 0, sizeof(hdr));
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-	hdr.msg_control = chdr;
-	hdr.msg_controllen = CMSGLEN;
-
-	buf = SOCKET_OK;
-	FD_TO_CMSGHDR(fd, *chdr);
-
-	ret = sendmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-	return 0;
-}
-
-/* receive OK in message, fd in control message */
-int
-vfio_mp_sync_receive_fd(int socket)
-{
-	int buf;
-	struct msghdr hdr;
-	struct cmsghdr *chdr;
-	char chdr_buf[CMSGLEN];
-	struct iovec iov;
-	int ret, req, fd;
-
-	buf = SOCKET_ERR;
-
-	chdr = (struct cmsghdr *) chdr_buf;
-	memset(chdr, 0, sizeof(chdr_buf));
-	memset(&hdr, 0, sizeof(hdr));
-
-	hdr.msg_iov = &iov;
-	hdr.msg_iovlen = 1;
-	iov.iov_base = (char *) &buf;
-	iov.iov_len = sizeof(buf);
-	hdr.msg_control = chdr;
-	hdr.msg_controllen = CMSGLEN;
-
-	ret = recvmsg(socket, &hdr, 0);
-	if (ret < 0)
-		return -1;
-
-	req = buf;
-
-	if (req != SOCKET_OK)
-		return -1;
-
-	CMSGHDR_TO_FD(*chdr, fd);
-
-	return fd;
-}
-
-/* connect socket_fd in secondary process to the primary process's socket */
-int
-vfio_mp_sync_connect_to_primary(void)
-{
-	struct sockaddr_un addr;
-	socklen_t sockaddr_len;
-	int socket_fd;
-
-	/* set up a socket */
-	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-	if (socket_fd < 0) {
-		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
-		return -1;
-	}
-
-	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
-	addr.sun_family = AF_UNIX;
-
-	sockaddr_len = sizeof(struct sockaddr_un);
-
-	if (connect(socket_fd, (struct sockaddr *) &addr, sockaddr_len) == 0)
-		return socket_fd;
-
-	/* if connect failed */
-	close(socket_fd);
-	return -1;
-}
-
-
-
-/*
- * socket listening thread for primary process
- */
-static __attribute__((noreturn)) void *
-vfio_mp_sync_thread(void __rte_unused * arg)
-{
-	int ret, fd, vfio_data;
-
-	/* wait for requests on the socket */
-	for (;;) {
-		int conn_sock;
-		struct sockaddr_un addr;
-		socklen_t sockaddr_len = sizeof(addr);
-
-		/* this is a blocking call */
-		conn_sock = accept(mp_socket_fd, (struct sockaddr *) &addr,
-				&sockaddr_len);
-
-		/* just restart on error */
-		if (conn_sock == -1)
-			continue;
-
-		/* set socket to linger after close */
-		struct linger l;
-		l.l_onoff = 1;
-		l.l_linger = 60;
-
-		if (setsockopt(conn_sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0)
-			RTE_LOG(WARNING, EAL, "Cannot set SO_LINGER option "
-					"on listen socket (%s)\n", strerror(errno));
-
-		ret = vfio_mp_sync_receive_request(conn_sock);
-
-		switch (ret) {
-		case SOCKET_REQ_CONTAINER:
-			fd = vfio_get_container_fd();
-			if (fd < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			else
-				vfio_mp_sync_send_fd(conn_sock, fd);
-			if (fd >= 0)
-				close(fd);
-			break;
-		case SOCKET_REQ_GROUP:
-			/* wait for group number */
-			vfio_data = vfio_mp_sync_receive_request(conn_sock);
-			if (vfio_data < 0) {
-				close(conn_sock);
-				continue;
-			}
-
-			fd = vfio_get_group_fd(vfio_data);
-
-			if (fd < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			/* if VFIO group exists but isn't bound to VFIO driver */
-			else if (fd == 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
-			/* if group exists and is bound to VFIO driver */
-			else {
-				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
-				vfio_mp_sync_send_fd(conn_sock, fd);
-			}
-			break;
-		case SOCKET_CLR_GROUP:
-			/* wait for group fd */
-			vfio_data = vfio_mp_sync_receive_request(conn_sock);
-			if (vfio_data < 0) {
-				close(conn_sock);
-				continue;
-			}
-
-			ret = clear_group(vfio_data);
-
-			if (ret < 0)
-				vfio_mp_sync_send_request(conn_sock, SOCKET_NO_FD);
-			else
-				vfio_mp_sync_send_request(conn_sock, SOCKET_OK);
-			break;
-		default:
-			vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
-			break;
-		}
-		close(conn_sock);
-	}
-}
-
-static int
-vfio_mp_sync_socket_setup(void)
-{
-	int ret, socket_fd;
-	struct sockaddr_un addr;
-	socklen_t sockaddr_len;
-
-	/* set up a socket */
-	socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-	if (socket_fd < 0) {
-		RTE_LOG(ERR, EAL, "Failed to create socket!\n");
-		return -1;
-	}
-
-	get_socket_path(addr.sun_path, sizeof(addr.sun_path));
-	addr.sun_family = AF_UNIX;
-
-	sockaddr_len = sizeof(struct sockaddr_un);
-
-	unlink(addr.sun_path);
-
-	ret = bind(socket_fd, (struct sockaddr *) &addr, sockaddr_len);
-	if (ret) {
-		RTE_LOG(ERR, EAL, "Failed to bind socket: %s!\n", strerror(errno));
-		close(socket_fd);
-		return -1;
-	}
-
-	ret = listen(socket_fd, 50);
-	if (ret) {
-		RTE_LOG(ERR, EAL, "Failed to listen: %s!\n", strerror(errno));
-		close(socket_fd);
-		return -1;
-	}
-
-	/* save the socket in local configuration */
-	mp_socket_fd = socket_fd;
-
-	return 0;
-}
-
-/*
- * set up a local socket and tell it to listen for incoming connections
- */
-int
-vfio_mp_sync_setup(void)
-{
-	int ret;
-	char thread_name[RTE_MAX_THREAD_NAME_LEN];
-
-	if (vfio_mp_sync_socket_setup() < 0) {
-		RTE_LOG(ERR, EAL, "Failed to set up local socket!\n");
-		return -1;
-	}
-
-	ret = pthread_create(&socket_thread, NULL,
-			vfio_mp_sync_thread, NULL);
-	if (ret) {
-		RTE_LOG(ERR, EAL,
-			"Failed to create thread for communication with secondary processes!\n");
-		close(mp_socket_fd);
-		return -1;
-	}
-
-	/* Set thread_name for aid in debugging. */
-	snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "vfio-sync");
-	ret = rte_thread_setname(socket_thread, thread_name);
-	if (ret)
-		RTE_LOG(DEBUG, EAL,
-			"Failed to set thread name for secondary processes!\n");
-
-	return 0;
-}
-
-#endif
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index fe186cb..a8ea4ea 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -170,21 +170,6 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_pci_detach;
-	rte_pci_dump;
-	rte_pci_ioport_map;
-	rte_pci_ioport_read;
-	rte_pci_ioport_unmap;
-	rte_pci_ioport_write;
-	rte_pci_map_device;
-	rte_pci_probe;
-	rte_pci_probe_one;
-	rte_pci_read_config;
-	rte_pci_register;
-	rte_pci_scan;
-	rte_pci_unmap_device;
-	rte_pci_unregister;
-	rte_pci_write_config;
 	rte_vdev_init;
 	rte_vdev_register;
 	rte_vdev_uninit;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 354d170..e7be855 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1151,8 +1151,6 @@ TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
 	} \
 } while (0)
 
-#define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
-
 /**
  * l2 tunnel configuration.
  */
diff --git a/lib/librte_pci/Makefile b/lib/librte_pci/Makefile
new file mode 100644
index 0000000..fc2fadb
--- /dev/null
+++ b/lib/librte_pci/Makefile
@@ -0,0 +1,48 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_pci.a
+
+CFLAGS := -I$(SRCDIR)/include -I$(SRCDIR) $(CFLAGS)
+CFLAGS += $(WERROR_FLAGS) -O3
+
+EXPORT_MAP := rte_pci_version.map
+
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_PCI) += rte_pci.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI)-include += include/rte_pci.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
new file mode 100644
index 0000000..2647568
--- /dev/null
+++ b/lib/librte_pci/include/rte_pci.h
@@ -0,0 +1,287 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_PCI_H_
+#define _RTE_PCI_H_
+
+/**
+ * @file
+ *
+ * RTE PCI Library
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+
+/** Formatting string for PCI device identifier: Ex: 0000:00:01.0 */
+#define PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+#define PCI_PRI_STR_SIZE sizeof("XXXXXXXX:XX:XX.X")
+
+/** Short formatting string, without domain, for PCI device: Ex: 00:01.0 */
+#define PCI_SHORT_PRI_FMT "%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+
+/** Nb. of values in PCI device identifier format string. */
+#define PCI_FMT_NVAL 4
+
+/** Nb. of values in PCI resource format. */
+#define PCI_RESOURCE_FMT_NVAL 3
+
+/** Maximum number of PCI resources. */
+#define PCI_MAX_RESOURCE 6
+
+/**
+ * A structure describing an ID for a PCI driver. Each driver provides a
+ * table of these IDs for each device that it supports.
+ */
+struct rte_pci_id {
+	uint32_t class_id;            /**< Class ID or RTE_CLASS_ANY_ID. */
+	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
+	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
+	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
+	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
+};
+
+/**
+ * A structure describing the location of a PCI device.
+ */
+struct rte_pci_addr {
+	uint32_t domain;                /**< Device domain */
+	uint8_t bus;                    /**< Device bus */
+	uint8_t devid;                  /**< Device ID */
+	uint8_t function;               /**< Device function. */
+};
+
+/** Any PCI device identifier (vendor, device, ...) */
+#define PCI_ANY_ID (0xffff)
+#define RTE_CLASS_ANY_ID (0xffffff)
+
+/**
+ * A structure describing a PCI mapping.
+ */
+struct pci_map {
+	void *addr;
+	char *path;
+	uint64_t offset;
+	uint64_t size;
+	uint64_t phaddr;
+};
+
+struct pci_msix_table {
+	int bar_index;
+	uint32_t offset;
+	uint32_t size;
+};
+
+/**
+ * A structure describing a mapped PCI resource.
+ * For multi-process we need to reproduce all PCI mappings in secondary
+ * processes, so save them in a tailq.
+ */
+struct mapped_pci_resource {
+	TAILQ_ENTRY(mapped_pci_resource) next;
+
+	struct rte_pci_addr pci_addr;
+	char path[PATH_MAX];
+	int nb_maps;
+	struct pci_map maps[PCI_MAX_RESOURCE];
+	struct pci_msix_table msix_table;
+};
+
+
+/** mapped pci device list */
+TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
+
+/**< Internal use only - Macro used by pci addr parsing functions **/
+#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
+do {                                                               \
+	unsigned long val;                                      \
+	char *end;                                              \
+	errno = 0;                                              \
+	val = strtoul((in), &end, 16);                          \
+	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
+		return -EINVAL;                                 \
+	(fd) = (typeof (fd))val;                                \
+	(in) = end + 1;                                         \
+} while(0)
+
+/**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided without
+ * a domain prefix (i.e. domain returned is always 0)
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned.
+ *	Domain will always be returned as 0
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	dev_addr->domain = 0;
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+/**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided including
+ * a domain prefix.
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XXXX:XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned
+ * @return
+ *  0 on success, negative on error.
+ */
+static inline int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+#undef GET_PCIADDR_FIELD
+
+/**
+ * Utility function to write a pci device name, this device name can later be
+ * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
+ * BDF helpers.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ */
+static inline void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+		char *output, size_t size)
+{
+	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+			    addr->domain, addr->bus,
+			    addr->devid, addr->function) >= 0);
+}
+
+/* Compare two PCI device addresses. */
+/**
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
+static inline int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			 const struct rte_pci_addr *addr2)
+{
+	uint64_t dev_addr, dev_addr2;
+
+	if ((addr == NULL) || (addr2 == NULL))
+		return -1;
+
+	dev_addr = ((uint64_t)addr->domain << 24) |
+		(addr->bus << 16) | (addr->devid << 8) | addr->function;
+	dev_addr2 = ((uint64_t)addr2->domain << 24) |
+		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+	if (dev_addr > dev_addr2)
+		return 1;
+	else if (dev_addr < dev_addr2)
+		return -1;
+	else
+		return 0;
+}
+
+/**
+ * Map a particular resource from a file.
+ *
+ * @param requested_addr
+ *      The starting address for the new mapping range.
+ * @param fd
+ *      The file descriptor.
+ * @param offset
+ *      The offset for the mapping range.
+ * @param size
+ *      The size for the mapping range.
+ * @param additional_flags
+ *      The additional flags for the mapping range.
+ * @return
+ *   - On success, the function returns a pointer to the mapped area.
+ *   - On error, the value MAP_FAILED is returned.
+ */
+void *pci_map_resource(void *requested_addr, int fd, off_t offset,
+		size_t size, int additional_flags);
+
+/**
+ * Unmap a particular resource.
+ *
+ * @param requested_addr
+ *      The address for the unmapping range.
+ * @param size
+ *      The size for the unmapping range.
+ */
+void pci_unmap_resource(void *requested_addr, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PCI_H_ */
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
new file mode 100644
index 0000000..9dfdd3f
--- /dev/null
+++ b/lib/librte_pci/rte_pci.c
@@ -0,0 +1,92 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+
+#include "rte_pci.h"
+
+/* map a particular resource from a file */
+void *
+pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+		 int additional_flags)
+{
+	void *mapaddr;
+
+	/* Map the PCI memory resource of device */
+	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+			MAP_SHARED | additional_flags, fd, offset);
+	if (mapaddr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
+			__func__, fd, requested_addr,
+			(unsigned long)size, (unsigned long)offset,
+			strerror(errno), mapaddr);
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
+
+	return mapaddr;
+}
+
+/* unmap a particular resource */
+void
+pci_unmap_resource(void *requested_addr, size_t size)
+{
+	if (requested_addr == NULL)
+		return;
+
+	/* Unmap the PCI memory resource of device */
+	if (munmap(requested_addr, size)) {
+		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+			__func__, requested_addr, (unsigned long)size,
+			strerror(errno));
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
+				requested_addr);
+}
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
new file mode 100644
index 0000000..64dec54
--- /dev/null
+++ b/lib/librte_pci/rte_pci_version.map
@@ -0,0 +1,8 @@
+DPDK_17.11 {
+	global:
+
+	pci_map_resource;
+	pci_unmap_resource;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 0b8f612..88b1a71 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -97,6 +97,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI)            += -lrte_pci
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
@@ -106,6 +107,8 @@ ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
 endif
 
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI_BUS)        += -lrte_bus_pci
+
 ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
 # plugins (link only if static libraries)
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 04/20] lib: include PCI bus header
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (2 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 03/20] pci: introduce PCI lib and bus Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 05/20] drivers: " Gaetan Rivet
                           ` (16 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update the libraries, as structuraly unsound as it may be.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ether/rte_ethdev_pci.h          | 1 +
 lib/librte_eventdev/rte_eventdev_pmd_pci.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h
index 56b1072..722075e 100644
--- a/lib/librte_ether/rte_ethdev_pci.h
+++ b/lib/librte_ether/rte_ethdev_pci.h
@@ -36,6 +36,7 @@
 
 #include <rte_malloc.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 
 /**
diff --git a/lib/librte_eventdev/rte_eventdev_pmd_pci.h b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
index b6bd731..ade32b5 100644
--- a/lib/librte_eventdev/rte_eventdev_pmd_pci.h
+++ b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
@@ -50,6 +50,7 @@ extern "C" {
 #include <rte_eal.h>
 #include <rte_lcore.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "rte_eventdev_pmd.h"
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 05/20] drivers: include PCI bus header
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (3 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 04/20] lib: include PCI bus header Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 06/20] test: " Gaetan Rivet
                           ` (15 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update drivers.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/bus/pci/bsd/pci.c                  | 1 +
 drivers/bus/pci/linux/pci.c                | 1 +
 drivers/bus/pci/linux/pci_uio.c            | 1 +
 drivers/bus/pci/linux/pci_vfio.c           | 1 +
 drivers/bus/pci/linux/vfio_mp_sync.c       | 1 +
 drivers/bus/pci/pci_common.c               | 1 +
 drivers/bus/pci/pci_common_uio.c           | 1 +
 drivers/bus/pci/private.h                  | 1 +
 drivers/crypto/qat/qat_qp.c                | 1 +
 drivers/event/octeontx/ssovf_probe.c       | 1 +
 drivers/mempool/octeontx/octeontx_fpavf.c  | 2 +-
 drivers/net/ark/ark_ethdev.c               | 1 +
 drivers/net/avp/avp_ethdev.c               | 2 ++
 drivers/net/bnxt/bnxt.h                    | 1 +
 drivers/net/bonding/rte_eth_bond_args.c    | 1 +
 drivers/net/cxgbe/base/adapter.h           | 1 +
 drivers/net/cxgbe/cxgbe_ethdev.c           | 1 +
 drivers/net/e1000/em_ethdev.c              | 1 +
 drivers/net/e1000/igb_ethdev.c             | 1 +
 drivers/net/e1000/igb_pf.c                 | 1 +
 drivers/net/ena/ena_ethdev.h               | 1 +
 drivers/net/enic/base/vnic_dev.h           | 4 +++-
 drivers/net/enic/enic_ethdev.c             | 1 +
 drivers/net/enic/enic_main.c               | 1 +
 drivers/net/i40e/i40e_ethdev.c             | 1 +
 drivers/net/i40e/i40e_ethdev_vf.c          | 1 +
 drivers/net/ixgbe/ixgbe_ethdev.c           | 1 +
 drivers/net/ixgbe/ixgbe_ethdev.h           | 1 +
 drivers/net/mlx4/mlx4_ethdev.c             | 2 +-
 drivers/net/mlx5/mlx5.c                    | 1 +
 drivers/net/mlx5/mlx5_ethdev.c             | 1 +
 drivers/net/nfp/nfp_nfpu.c                 | 2 +-
 drivers/net/nfp/nfp_nfpu.h                 | 2 +-
 drivers/net/octeontx/base/octeontx_pkivf.c | 2 +-
 drivers/net/octeontx/base/octeontx_pkovf.c | 2 +-
 drivers/net/sfc/sfc.h                      | 1 +
 drivers/net/sfc/sfc_ethdev.c               | 1 +
 drivers/net/thunderx/nicvf_ethdev.c        | 1 +
 drivers/net/virtio/virtio_ethdev.c         | 1 +
 drivers/net/virtio/virtio_pci.h            | 1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c       | 1 +
 41 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
index 599519a..753d914 100644
--- a/drivers/bus/pci/bsd/pci.c
+++ b/drivers/bus/pci/bsd/pci.c
@@ -57,6 +57,7 @@
 #include <rte_interrupts.h>
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_common.h>
 #include <rte_launch.h>
 #include <rte_memory.h>
diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c
index c1fcc56..422579f 100644
--- a/drivers/bus/pci/linux/pci.c
+++ b/drivers/bus/pci/linux/pci.c
@@ -37,6 +37,7 @@
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 #include <rte_devargs.h>
diff --git a/drivers/bus/pci/linux/pci_uio.c b/drivers/bus/pci/linux/pci_uio.c
index d3f0556..940fa21 100644
--- a/drivers/bus/pci/linux/pci_uio.c
+++ b/drivers/bus/pci/linux/pci_uio.c
@@ -47,6 +47,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_common.h>
 #include <rte_malloc.h>
diff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c
index e69e4d3..855e2b9 100644
--- a/drivers/bus/pci/linux/pci_vfio.c
+++ b/drivers/bus/pci/linux/pci_vfio.c
@@ -42,6 +42,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 
diff --git a/drivers/bus/pci/linux/vfio_mp_sync.c b/drivers/bus/pci/linux/vfio_mp_sync.c
index dd24e86..d07687f 100644
--- a/drivers/bus/pci/linux/vfio_mp_sync.c
+++ b/drivers/bus/pci/linux/vfio_mp_sync.c
@@ -50,6 +50,7 @@
 
 #include <rte_log.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index 7b68e99..cd95d1a 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -45,6 +45,7 @@
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_per_lcore.h>
 #include <rte_memory.h>
 #include <rte_memzone.h>
diff --git a/drivers/bus/pci/pci_common_uio.c b/drivers/bus/pci/pci_common_uio.c
index 4365660..544c606 100644
--- a/drivers/bus/pci/pci_common_uio.c
+++ b/drivers/bus/pci/pci_common_uio.c
@@ -40,6 +40,7 @@
 
 #include <rte_eal.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tailq.h>
 #include <rte_log.h>
 #include <rte_malloc.h>
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 7ff1fc4..fdc2c81 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -37,6 +37,7 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 struct rte_pci_driver;
 struct rte_pci_device;
diff --git a/drivers/crypto/qat/qat_qp.c b/drivers/crypto/qat/qat_qp.c
index 34f75ca..8489662 100644
--- a/drivers/crypto/qat/qat_qp.c
+++ b/drivers/crypto/qat/qat_qp.c
@@ -37,6 +37,7 @@
 #include <rte_memzone.h>
 #include <rte_cryptodev_pmd.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_prefetch.h>
 
diff --git a/drivers/event/octeontx/ssovf_probe.c b/drivers/event/octeontx/ssovf_probe.c
index e1c0c6d..1cac4bc 100644
--- a/drivers/event/octeontx/ssovf_probe.c
+++ b/drivers/event/octeontx/ssovf_probe.c
@@ -35,6 +35,7 @@
 #include <rte_eal.h>
 #include <rte_io.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "ssovf_evdev.h"
 
diff --git a/drivers/mempool/octeontx/octeontx_fpavf.c b/drivers/mempool/octeontx/octeontx_fpavf.c
index eea934f..bbede5d 100644
--- a/drivers/mempool/octeontx/octeontx_fpavf.c
+++ b/drivers/mempool/octeontx/octeontx_fpavf.c
@@ -41,7 +41,7 @@
 
 #include <rte_atomic.h>
 #include <rte_eal.h>
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_errno.h>
 #include <rte_memory.h>
 #include <rte_malloc.h>
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index dae1f3d..384be47 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -35,6 +35,7 @@
 #include <sys/stat.h>
 #include <dlfcn.h>
 
+#include <rte_bus_pci.h>
 #include <rte_ethdev_pci.h>
 #include <rte_kvargs.h>
 
diff --git a/drivers/net/avp/avp_ethdev.c b/drivers/net/avp/avp_ethdev.c
index b97a90c..89e91e2 100644
--- a/drivers/net/avp/avp_ethdev.c
+++ b/drivers/net/avp/avp_ethdev.c
@@ -36,6 +36,7 @@
 #include <errno.h>
 #include <unistd.h>
 
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_memcpy.h>
@@ -45,6 +46,7 @@
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 294a174..039b248 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -39,6 +39,7 @@
 #include <sys/queue.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_memory.h>
 #include <rte_lcore.h>
diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index c4dcefa..dea0265 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -33,6 +33,7 @@
 
 #include <rte_devargs.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 
 #include <cmdline_parse.h>
diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index 5e5f221..f2057af 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -36,6 +36,7 @@
 #ifndef __T4_ADAPTER_H__
 #define __T4_ADAPTER_H__
 
+#include <rte_bus_pci.h>
 #include <rte_mbuf.h>
 #include <rte_io.h>
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 02b4f62..b1405e5 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index e724205..aa831f8 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index f3b1d70..380ec31 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/e1000/igb_pf.c b/drivers/net/e1000/igb_pf.c
index 6809d30..cd6ae2f 100644
--- a/drivers/net/e1000/igb_pf.c
+++ b/drivers/net/e1000/igb_pf.c
@@ -39,6 +39,7 @@
 #include <stdarg.h>
 #include <inttypes.h>
 
+#include <rte_bus_pci.h>
 #include <rte_interrupts.h>
 #include <rte_log.h>
 #include <rte_debug.h>
diff --git a/drivers/net/ena/ena_ethdev.h b/drivers/net/ena/ena_ethdev.h
index dc3080f..be8bc9f 100644
--- a/drivers/net/ena/ena_ethdev.h
+++ b/drivers/net/ena/ena_ethdev.h
@@ -35,6 +35,7 @@
 #define _ENA_ETHDEV_H_
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "ena_com.h"
 
diff --git a/drivers/net/enic/base/vnic_dev.h b/drivers/net/enic/base/vnic_dev.h
index 9a9e691..c9ca25b 100644
--- a/drivers/net/enic/base/vnic_dev.h
+++ b/drivers/net/enic/base/vnic_dev.h
@@ -35,8 +35,10 @@
 #ifndef _VNIC_DEV_H_
 #define _VNIC_DEV_H_
 
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+
 #include "enic_compat.h"
-#include "rte_pci.h"
 #include "vnic_resource.h"
 #include "vnic_devcmd.h"
 
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 5386b2a..7a7e2d9 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -37,6 +37,7 @@
 
 #include <rte_dev.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_string_fns.h>
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 5211670..be62447 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -40,6 +40,7 @@
 #include <libgen.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_memzone.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 814f458..ffead82 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_eal.h>
 #include <rte_string_fns.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 63d1f77..39a0cbd 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -47,6 +47,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index a08e475..a750a88 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index e28c856..5156483 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -41,6 +41,7 @@
 #include <rte_time.h>
 #include <rte_hash.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tm_driver.h>
 
 /* need update link, bit flag */
diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
index 8962be1..b97b146 100644
--- a/drivers/net/mlx4/mlx4_ethdev.c
+++ b/drivers/net/mlx4/mlx4_ethdev.c
@@ -64,7 +64,7 @@
 #include <rte_errno.h>
 #include <rte_ethdev.h>
 #include <rte_ether.h>
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "mlx4.h"
 #include "mlx4_rxtx.h"
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 29221dc..d60ef74 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -54,6 +54,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_common.h>
 #include <rte_kvargs.h>
 
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index e06dce3..c31ea4b 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -56,6 +56,7 @@
 
 #include <rte_atomic.h>
 #include <rte_ethdev.h>
+#include <rte_bus_pci.h>
 #include <rte_mbuf.h>
 #include <rte_common.h>
 #include <rte_interrupts.h>
diff --git a/drivers/net/nfp/nfp_nfpu.c b/drivers/net/nfp/nfp_nfpu.c
index 556ded3..5775d8d 100644
--- a/drivers/net/nfp/nfp_nfpu.c
+++ b/drivers/net/nfp/nfp_nfpu.c
@@ -8,7 +8,7 @@
 #include <fcntl.h>
 #include <sys/types.h>
 
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_malloc.h>
 
 #include "nfp_nfpu.h"
diff --git a/drivers/net/nfp/nfp_nfpu.h b/drivers/net/nfp/nfp_nfpu.h
index 31511b3..e56fa09 100644
--- a/drivers/net/nfp/nfp_nfpu.h
+++ b/drivers/net/nfp/nfp_nfpu.h
@@ -42,7 +42,7 @@
  */
 
 
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include "nfp_nspu.h"
 
 typedef struct {
diff --git a/drivers/net/octeontx/base/octeontx_pkivf.c b/drivers/net/octeontx/base/octeontx_pkivf.c
index afae6a3..20cbe0c 100644
--- a/drivers/net/octeontx/base/octeontx_pkivf.c
+++ b/drivers/net/octeontx/base/octeontx_pkivf.c
@@ -32,7 +32,7 @@
 #include <string.h>
 
 #include <rte_eal.h>
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "octeontx_pkivf.h"
 
diff --git a/drivers/net/octeontx/base/octeontx_pkovf.c b/drivers/net/octeontx/base/octeontx_pkovf.c
index a8f6e5d..2bf607b 100644
--- a/drivers/net/octeontx/base/octeontx_pkovf.c
+++ b/drivers/net/octeontx/base/octeontx_pkovf.c
@@ -37,7 +37,7 @@
 #include <rte_cycles.h>
 #include <rte_malloc.h>
 #include <rte_memory.h>
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_spinlock.h>
 
 #include "../octeontx_logs.h"
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index c170384..7f11bf2 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -35,6 +35,7 @@
 #include <stdbool.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_kvargs.h>
 #include <rte_spinlock.h>
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index bd09191..430e24f 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -33,6 +33,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_errno.h>
 
 #include "efx.h"
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index 551b371..24ac3f9 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -61,6 +61,7 @@
 #include <rte_malloc.h>
 #include <rte_random.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tailq.h>
 
 #include "base/nicvf_plat.h"
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 0ec54a9..3c4c083 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -46,6 +46,7 @@
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_common.h>
 #include <rte_errno.h>
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 5f3b6c8..36d452c 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -37,6 +37,7 @@
 #include <stdint.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 
 struct virtqueue;
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 58bc4f2..9772386 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 06/20] test: include PCI bus header
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (4 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 05/20] drivers: " Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 07/20] app/testpmd: " Gaetan Rivet
                           ` (14 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update test applications.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 test/test/test_kni.c    | 1 +
 test/test/virtual_pmd.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/test/test/test_kni.c b/test/test/test_kni.c
index 2450c9f..b956727 100644
--- a/test/test/test_kni.c
+++ b/test/test/test_kni.c
@@ -42,6 +42,7 @@
 #include <rte_string_fns.h>
 #include <rte_mempool.h>
 #include <rte_ethdev.h>
+#include <rte_bus_pci.h>
 #include <rte_cycles.h>
 #include <rte_kni.h>
 
diff --git a/test/test/virtual_pmd.c b/test/test/virtual_pmd.c
index 09daf6c..b57a949 100644
--- a/test/test/virtual_pmd.c
+++ b/test/test/virtual_pmd.c
@@ -34,6 +34,7 @@
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_memory.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 07/20] app/testpmd: include PCI bus header
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (5 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 06/20] test: " Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 08/20] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
                           ` (13 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Devices and drivers are now defined within the bus-specific PCI header.
Update applications.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 app/test-pmd/testpmd.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 0b8e624..b05c8a0 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -35,6 +35,7 @@
 #define _TESTPMD_H_
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_gro.h>
 #include <rte_gso.h>
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 08/20] cryptodev: move PCI specific helpers to drivers/crypto
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (6 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 07/20] app/testpmd: " Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 09/20] net/bonding: use local prefix for local function Gaetan Rivet
                           ` (12 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Those helpers rely on the PCI bus driver implementation.
Other similar libraries relied on the bus-specifics being handled in
inlined functions, to be compiled on demand by drivers, once the proper
PCI dependency has been settled. This seems unsafe.

Move the PCI-specific helpers out of the lib directory to the
drivers/crypto directory, properly following the dependency hierarchy.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/crypto/Makefile                          |   4 +-
 drivers/crypto/pci/Makefile                      |  52 +++++++++
 drivers/crypto/pci/rte_cryptodev_pci.c           | 128 +++++++++++++++++++++++
 drivers/crypto/pci/rte_cryptodev_pci.h           |  94 +++++++++++++++++
 drivers/crypto/pci/rte_cryptodev_pci_version.map |   7 ++
 lib/librte_cryptodev/Makefile                    |   1 -
 lib/librte_cryptodev/rte_cryptodev_pci.h         |  92 ----------------
 lib/librte_cryptodev/rte_cryptodev_pmd.c         |  94 -----------------
 lib/librte_cryptodev/rte_cryptodev_version.map   |   2 -
 9 files changed, 284 insertions(+), 190 deletions(-)
 create mode 100644 drivers/crypto/pci/Makefile
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.c
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci.h
 create mode 100644 drivers/crypto/pci/rte_cryptodev_pci_version.map
 delete mode 100644 lib/librte_cryptodev/rte_cryptodev_pci.h

diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 7a719b9..cfd6cb6 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 core-libs := librte_eal librte_mbuf librte_mempool librte_ring librte_cryptodev
 
+DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
+DEPDIRS-pci = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm
 DEPDIRS-aesni_gcm = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb
@@ -42,7 +44,7 @@ DEPDIRS-armv8 = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_OPENSSL) += openssl
 DEPDIRS-openssl = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat
-DEPDIRS-qat = $(core-libs)
+DEPDIRS-qat = $(core-libs) librte_cryptodev_pci
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER) += scheduler
 DEPDIRS-scheduler = $(core-libs) librte_kvargs librte_reorder
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += snow3g
diff --git a/drivers/crypto/pci/Makefile b/drivers/crypto/pci/Makefile
new file mode 100644
index 0000000..da819f2
--- /dev/null
+++ b/drivers/crypto/pci/Makefile
@@ -0,0 +1,52 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A. All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND S.A. nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_cryptodev_pci.a
+
+# library version
+LIBABIVER := 1
+
+# build flags
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# library source files
+SRCS-y += rte_cryptodev_pci.c
+
+# export include files
+SYMLINK-y-include += rte_cryptodev_pci.h
+
+# versioning export map
+EXPORT_MAP := rte_cryptodev_pci_version.map
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/crypto/pci/rte_cryptodev_pci.c b/drivers/crypto/pci/rte_cryptodev_pci.c
new file mode 100644
index 0000000..a2a1366
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci.c
@@ -0,0 +1,128 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of the copyright holder nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_malloc.h>
+
+#include "rte_cryptodev_pci.h"
+
+int
+rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
+			size_t private_data_size,
+			cryptodev_pci_init_t dev_init)
+{
+	struct rte_cryptodev *cryptodev;
+
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+
+	int retval;
+
+	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name, rte_socket_id());
+	if (cryptodev == NULL)
+		return -ENOMEM;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc_socket(
+						"cryptodev private structure",
+						private_data_size,
+						RTE_CACHE_LINE_SIZE,
+						rte_socket_id());
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private "
+					"device data");
+	}
+
+	cryptodev->device = &pci_dev->device;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	/* Invoke PMD device initialization function */
+	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
+	retval = dev_init(cryptodev);
+	if (retval == 0)
+		return 0;
+
+	CDEV_LOG_ERR("driver %s: crypto_dev_init(vendor_id=0x%x device_id=0x%x)"
+			" failed", pci_dev->device.driver->name,
+			(unsigned int) pci_dev->id.vendor_id,
+			(unsigned int) pci_dev->id.device_id);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	return -ENXIO;
+}
+
+int
+rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
+		cryptodev_pci_uninit_t dev_uninit)
+{
+	struct rte_cryptodev *cryptodev;
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+	int ret;
+
+	if (pci_dev == NULL)
+		return -EINVAL;
+
+	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
+			sizeof(cryptodev_name));
+
+	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
+	if (cryptodev == NULL)
+		return -ENODEV;
+
+	/* Invoke PMD device uninit function */
+	if (dev_uninit) {
+		ret = dev_uninit(cryptodev);
+		if (ret)
+			return ret;
+	}
+
+	/* free crypto device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->device = NULL;
+	cryptodev->data = NULL;
+
+	return 0;
+}
diff --git a/drivers/crypto/pci/rte_cryptodev_pci.h b/drivers/crypto/pci/rte_cryptodev_pci.h
new file mode 100644
index 0000000..97b6f1e
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci.h
@@ -0,0 +1,94 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of the copyright holder nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_CRYPTODEV_PCI_H_
+#define _RTE_CRYPTODEV_PCI_H_
+
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
+
+/**
+ * Initialisation function of a crypto driver invoked for each matching
+ * crypto PCI device detected during the PCI probing phase.
+ *
+ * @param	dev	The dev pointer is the address of the *rte_cryptodev*
+ *			structure associated with the matching device and which
+ *			has been [automatically] allocated in the
+ *			*rte_crypto_devices* array.
+ *
+ * @return
+ *   - 0: Success, the device is properly initialised by the driver.
+ *        In particular, the driver MUST have set up the *dev_ops* pointer
+ *        of the *dev* structure.
+ *   - <0: Error code of the device initialisation failure.
+ */
+typedef int (*cryptodev_pci_init_t)(struct rte_cryptodev *dev);
+
+/**
+ * Finalisation function of a driver invoked for each matching
+ * PCI device detected during the PCI closing phase.
+ *
+ * @param	dev	The dev pointer is the address of the *rte_cryptodev*
+ *			structure associated with the matching device and which
+ *			has been [automatically] allocated in the
+ *			*rte_crypto_devices* array.
+ *
+ *  * @return
+ *   - 0: Success, the device is properly finalised by the driver.
+ *        In particular, the driver MUST free the *dev_ops* pointer
+ *        of the *dev* structure.
+ *   - <0: Error code of the device initialisation failure.
+ */
+typedef int (*cryptodev_pci_uninit_t)(struct rte_cryptodev *dev);
+
+/**
+ * @internal
+ * Wrapper for use by pci drivers as a .probe function to attach to a crypto
+ * interface.
+ */
+int
+rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
+			size_t private_data_size,
+			cryptodev_pci_init_t dev_init);
+
+/**
+ * @internal
+ * Wrapper for use by pci drivers as a .remove function to detach a crypto
+ * interface.
+ */
+int
+rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
+		cryptodev_pci_uninit_t dev_uninit);
+
+#endif /* _RTE_CRYPTODEV_PCI_H_ */
diff --git a/drivers/crypto/pci/rte_cryptodev_pci_version.map b/drivers/crypto/pci/rte_cryptodev_pci_version.map
new file mode 100644
index 0000000..0510fef
--- /dev/null
+++ b/drivers/crypto/pci/rte_cryptodev_pci_version.map
@@ -0,0 +1,7 @@
+DPDK_17.11 {
+	global:
+
+	rte_cryptodev_pci_generic_probe;
+	rte_cryptodev_pci_generic_remove;
+
+};
diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index 6ac331b..bd94cf7 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -49,7 +49,6 @@ SYMLINK-y-include += rte_crypto_sym.h
 SYMLINK-y-include += rte_cryptodev.h
 SYMLINK-y-include += rte_cryptodev_pmd.h
 SYMLINK-y-include += rte_cryptodev_vdev.h
-SYMLINK-y-include += rte_cryptodev_pci.h
 
 # versioning export map
 EXPORT_MAP := rte_cryptodev_version.map
diff --git a/lib/librte_cryptodev/rte_cryptodev_pci.h b/lib/librte_cryptodev/rte_cryptodev_pci.h
deleted file mode 100644
index 67eda96..0000000
--- a/lib/librte_cryptodev/rte_cryptodev_pci.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2017 Intel Corporation. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of the copyright holder nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_CRYPTODEV_PCI_H_
-#define _RTE_CRYPTODEV_PCI_H_
-
-#include <rte_pci.h>
-#include "rte_cryptodev.h"
-
-/**
- * Initialisation function of a crypto driver invoked for each matching
- * crypto PCI device detected during the PCI probing phase.
- *
- * @param	dev	The dev pointer is the address of the *rte_cryptodev*
- *			structure associated with the matching device and which
- *			has been [automatically] allocated in the
- *			*rte_crypto_devices* array.
- *
- * @return
- *   - 0: Success, the device is properly initialised by the driver.
- *        In particular, the driver MUST have set up the *dev_ops* pointer
- *        of the *dev* structure.
- *   - <0: Error code of the device initialisation failure.
- */
-typedef int (*cryptodev_pci_init_t)(struct rte_cryptodev *dev);
-
-/**
- * Finalisation function of a driver invoked for each matching
- * PCI device detected during the PCI closing phase.
- *
- * @param	dev	The dev pointer is the address of the *rte_cryptodev*
- *			structure associated with the matching device and which
- *			has been [automatically] allocated in the
- *			*rte_crypto_devices* array.
- *
- *  * @return
- *   - 0: Success, the device is properly finalised by the driver.
- *        In particular, the driver MUST free the *dev_ops* pointer
- *        of the *dev* structure.
- *   - <0: Error code of the device initialisation failure.
- */
-typedef int (*cryptodev_pci_uninit_t)(struct rte_cryptodev *dev);
-
-/**
- * @internal
- * Wrapper for use by pci drivers as a .probe function to attach to a crypto
- * interface.
- */
-int
-rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
-			size_t private_data_size,
-			cryptodev_pci_init_t dev_init);
-
-/**
- * @internal
- * Wrapper for use by pci drivers as a .remove function to detach a crypto
- * interface.
- */
-int
-rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
-		cryptodev_pci_uninit_t dev_uninit);
-
-#endif /* _RTE_CRYPTODEV_PCI_H_ */
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.c b/lib/librte_cryptodev/rte_cryptodev_pmd.c
index a57faad..ec5c33b 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.c
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.c
@@ -33,7 +33,6 @@
 #include <rte_malloc.h>
 
 #include "rte_cryptodev_vdev.h"
-#include "rte_cryptodev_pci.h"
 #include "rte_cryptodev_pmd.h"
 
 /**
@@ -154,96 +153,3 @@ rte_cryptodev_vdev_parse_init_params(struct rte_crypto_vdev_init_params *params,
 	rte_kvargs_free(kvlist);
 	return ret;
 }
-
-int
-rte_cryptodev_pci_generic_probe(struct rte_pci_device *pci_dev,
-			size_t private_data_size,
-			cryptodev_pci_init_t dev_init)
-{
-	struct rte_cryptodev *cryptodev;
-
-	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
-
-	int retval;
-
-	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
-			sizeof(cryptodev_name));
-
-	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name, rte_socket_id());
-	if (cryptodev == NULL)
-		return -ENOMEM;
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-		cryptodev->data->dev_private =
-				rte_zmalloc_socket(
-						"cryptodev private structure",
-						private_data_size,
-						RTE_CACHE_LINE_SIZE,
-						rte_socket_id());
-
-		if (cryptodev->data->dev_private == NULL)
-			rte_panic("Cannot allocate memzone for private "
-					"device data");
-	}
-
-	cryptodev->device = &pci_dev->device;
-
-	/* init user callbacks */
-	TAILQ_INIT(&(cryptodev->link_intr_cbs));
-
-	/* Invoke PMD device initialization function */
-	RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
-	retval = dev_init(cryptodev);
-	if (retval == 0)
-		return 0;
-
-	CDEV_LOG_ERR("driver %s: crypto_dev_init(vendor_id=0x%x device_id=0x%x)"
-			" failed", pci_dev->device.driver->name,
-			(unsigned int) pci_dev->id.vendor_id,
-			(unsigned int) pci_dev->id.device_id);
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-		rte_free(cryptodev->data->dev_private);
-
-	/* free crypto device */
-	rte_cryptodev_pmd_release_device(cryptodev);
-
-	return -ENXIO;
-}
-
-int
-rte_cryptodev_pci_generic_remove(struct rte_pci_device *pci_dev,
-		cryptodev_pci_uninit_t dev_uninit)
-{
-	struct rte_cryptodev *cryptodev;
-	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
-	int ret;
-
-	if (pci_dev == NULL)
-		return -EINVAL;
-
-	rte_pci_device_name(&pci_dev->addr, cryptodev_name,
-			sizeof(cryptodev_name));
-
-	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
-	if (cryptodev == NULL)
-		return -ENODEV;
-
-	/* Invoke PMD device uninit function */
-	if (dev_uninit) {
-		ret = dev_uninit(cryptodev);
-		if (ret)
-			return ret;
-	}
-
-	/* free crypto device */
-	rte_cryptodev_pmd_release_device(cryptodev);
-
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-		rte_free(cryptodev->data->dev_private);
-
-	cryptodev->device = NULL;
-	cryptodev->data = NULL;
-
-	return 0;
-}
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index e9ba88a..496253d 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -68,8 +68,6 @@ DPDK_17.08 {
 	rte_cryptodev_get_aead_algo_enum;
 	rte_cryptodev_get_header_session_size;
 	rte_cryptodev_get_private_session_size;
-	rte_cryptodev_pci_generic_probe;
-	rte_cryptodev_pci_generic_remove;
 	rte_cryptodev_sym_capability_check_aead;
 	rte_cryptodev_sym_session_init;
 	rte_cryptodev_sym_session_clear;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 09/20] net/bonding: use local prefix for local function
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (7 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 08/20] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 10/20] pci: avoid inlining functions Gaetan Rivet
                           ` (11 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/net/bonding/rte_eth_bond_args.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index dea0265..e816da3 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -90,7 +90,7 @@ find_port_id_by_dev_name(const char *name)
 }
 
 static inline int
-pci_addr_cmp(const struct rte_device *dev, const void *_pci_addr)
+bond_pci_addr_cmp(const struct rte_device *dev, const void *_pci_addr)
 {
 	struct rte_pci_device *pdev;
 	const struct rte_pci_addr *paddr = _pci_addr;
@@ -119,7 +119,7 @@ parse_port_id(const char *port_str)
 
 	/* try parsing as pci address, physical devices */
 	if (pci_bus->parse(port_str, &dev_addr) == 0) {
-		dev = pci_bus->find_device(NULL, pci_addr_cmp, &dev_addr);
+		dev = pci_bus->find_device(NULL, bond_pci_addr_cmp, &dev_addr);
 		if (dev == NULL) {
 			RTE_LOG(ERR, PMD, "unable to find PCI device\n");
 			return -1;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 10/20] pci: avoid inlining functions
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (8 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 09/20] net/bonding: use local prefix for local function Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-17 18:20           ` Aaron Conole
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 11/20] pci: avoid over-complicated macro Gaetan Rivet
                           ` (10 subsequent siblings)
  20 siblings, 1 reply; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Parsing operations should not happen in performance critical sections.
Headers should not propose implementations unless duly required.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_pci/include/rte_pci.h   | 69 ++++----------------------------------
 lib/librte_pci/rte_pci.c           | 65 +++++++++++++++++++++++++++++++++++
 lib/librte_pci/rte_pci_version.map |  4 +++
 3 files changed, 75 insertions(+), 63 deletions(-)

diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
index 2647568..fe4d411 100644
--- a/lib/librte_pci/include/rte_pci.h
+++ b/lib/librte_pci/include/rte_pci.h
@@ -134,19 +134,6 @@ struct mapped_pci_resource {
 /** mapped pci device list */
 TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 
-/**< Internal use only - Macro used by pci addr parsing functions **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
-do {                                                               \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
-
 /**
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided without
@@ -160,15 +147,7 @@ do {                                                               \
  * @return
  *  0 on success, negative on error.
  */
-static inline int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
+int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to produce a PCI Bus-Device-Function value
@@ -182,16 +161,7 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
  * @return
  *  0 on success, negative on error.
  */
-static inline int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-#undef GET_PCIADDR_FIELD
+int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to write a pci device name, this device name can later be
@@ -205,17 +175,9 @@ eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
  * @param size
  *	The output buffer size
  */
-static inline void
-rte_pci_device_name(const struct rte_pci_addr *addr,
-		char *output, size_t size)
-{
-	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
-	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
-			    addr->domain, addr->bus,
-			    addr->devid, addr->function) >= 0);
-}
+void rte_pci_device_name(const struct rte_pci_addr *addr,
+			 char *output, size_t size);
 
-/* Compare two PCI device addresses. */
 /**
  * Utility function to compare two PCI device addresses.
  *
@@ -228,27 +190,8 @@ rte_pci_device_name(const struct rte_pci_addr *addr,
  *	Positive on addr is greater than addr2.
  *	Negative on addr is less than addr2, or error.
  */
-static inline int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			 const struct rte_pci_addr *addr2)
-{
-	uint64_t dev_addr, dev_addr2;
-
-	if ((addr == NULL) || (addr2 == NULL))
-		return -1;
-
-	dev_addr = ((uint64_t)addr->domain << 24) |
-		(addr->bus << 16) | (addr->devid << 8) | addr->function;
-	dev_addr2 = ((uint64_t)addr2->domain << 24) |
-		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
-
-	if (dev_addr > dev_addr2)
-		return 1;
-	else if (dev_addr < dev_addr2)
-		return -1;
-	else
-		return 0;
-}
+int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			     const struct rte_pci_addr *addr2);
 
 /**
  * Map a particular resource from a file.
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index 9dfdd3f..8584b55 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -53,6 +53,71 @@
 
 #include "rte_pci.h"
 
+/* Macro used by pci addr parsing functions. **/
+#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                     \
+do {                                                            \
+	unsigned long val;                                      \
+	char *end;                                              \
+	errno = 0;                                              \
+	val = strtoul((in), &end, 16);                          \
+	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
+		return -EINVAL;                                 \
+	(fd) = (typeof (fd))val;                                \
+	(in) = end + 1;                                         \
+} while(0)
+
+int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	dev_addr->domain = 0;
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+		    char *output, size_t size)
+{
+	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+			    addr->domain, addr->bus,
+			    addr->devid, addr->function) >= 0);
+}
+
+int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			 const struct rte_pci_addr *addr2)
+{
+	uint64_t dev_addr, dev_addr2;
+
+	if ((addr == NULL) || (addr2 == NULL))
+		return -1;
+
+	dev_addr = ((uint64_t)addr->domain << 24) |
+		(addr->bus << 16) | (addr->devid << 8) | addr->function;
+	dev_addr2 = ((uint64_t)addr2->domain << 24) |
+		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+	if (dev_addr > dev_addr2)
+		return 1;
+	else if (dev_addr < dev_addr2)
+		return -1;
+	else
+		return 0;
+}
+
 /* map a particular resource from a file */
 void *
 pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index 64dec54..a940259 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -1,8 +1,12 @@
 DPDK_17.11 {
 	global:
 
+	eal_parse_pci_BDF;
+	eal_parse_pci_DomBDF;
 	pci_map_resource;
 	pci_unmap_resource;
+	rte_eal_compare_pci_addr;
+	rte_pci_device_name;
 
 	local: *;
 };
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 11/20] pci: avoid over-complicated macro
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (9 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 10/20] pci: avoid inlining functions Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 12/20] pci: deprecate misnamed functions Gaetan Rivet
                           ` (9 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Using a macro helps writing the code to the detriment of the reader in
this case. This is backward. Write once, read many.

The few LOCs gained is not worth the opacity of the implementation.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_pci/rte_pci.c | 65 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 46 insertions(+), 19 deletions(-)

diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index 8584b55..cbb5359 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -53,36 +53,63 @@
 
 #include "rte_pci.h"
 
-/* Macro used by pci addr parsing functions. **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                     \
-do {                                                            \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
+static inline const char *
+get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
+{
+	unsigned long val;
+	uint8_t *u8 = _u8;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != dlm || val > UINT8_MAX) {
+		errno = errno ? errno : EINVAL;
+		return NULL;
+	}
+	*u8 = (uint8_t)val;
+	return end + 1;
+}
 
 int
 eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	const char *in = input;
+
 	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
 	return 0;
 }
 
 int
 eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
 {
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	const char *in = input;
+	unsigned long val;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != ':' || val > UINT16_MAX)
+		return -EINVAL;
+	dev_addr->domain = (uint16_t)val;
+	in = end + 1;
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
 	return 0;
 }
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 12/20] pci: deprecate misnamed functions
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (10 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 11/20] pci: avoid over-complicated macro Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 13/20] pci: introduce PCI address parsing function Gaetan Rivet
                           ` (8 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Rename misnamed functions and describe the change in a deprecation
notice.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst | 10 ++++++
 lib/librte_pci/include/rte_pci.h     | 63 ++++++++++++++++++++++++++++++++++++
 lib/librte_pci/rte_pci.c             | 26 +++++++++++++++
 lib/librte_pci/rte_pci_version.map   |  4 +++
 4 files changed, 103 insertions(+)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 4e4d97b..ef2264f 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -98,3 +98,13 @@ Deprecation Notices
   The non-"do-sig" versions of the hash tables will be removed
   (including the ``signature_offset`` parameter)
   and the "do-sig" versions renamed accordingly.
+
+* pci: Several exposed functions are misnamed.
+  The following functions are deprecated starting from v17.11 and are replaced:
+
+  - ``eal_parse_pci_BDF`` replaced by ``pci_parse_BDF``
+  - ``eal_parse_pci_DomBDF`` replaced by ``pci_parse_DomBDF``
+  - ``rte_eal_compare_pci_addr`` replaced by ``pci_addr_cmp``
+  - ``rte_pci_device_name`` replaced by ``pci_device_name``
+
+  The functions are only renamed. Their behavior is not affected.
diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
index fe4d411..38cbdb3 100644
--- a/lib/librte_pci/include/rte_pci.h
+++ b/lib/librte_pci/include/rte_pci.h
@@ -135,6 +135,7 @@ struct mapped_pci_resource {
 TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 
 /**
+ * @deprecated
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided without
  * a domain prefix (i.e. domain returned is always 0)
@@ -151,6 +152,22 @@ int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided without
+ * a domain prefix (i.e. domain returned is always 0)
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned.
+ *	Domain will always be returned as 0
+ * @return
+ *  0 on success, negative on error.
+ */
+int pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
+ * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided including
  * a domain prefix.
  *
@@ -164,6 +181,21 @@ int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided including
+ * a domain prefix.
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XXXX:XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned
+ * @return
+ *  0 on success, negative on error.
+ */
+int pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
  * Utility function to write a pci device name, this device name can later be
  * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
  * BDF helpers.
@@ -179,6 +211,22 @@ void rte_pci_device_name(const struct rte_pci_addr *addr,
 			 char *output, size_t size);
 
 /**
+ * Utility function to write a pci device name, this device name can later be
+ * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
+ * BDF helpers.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ */
+void pci_device_name(const struct rte_pci_addr *addr,
+		     char *output, size_t size);
+
+/**
+ * @deprecated
  * Utility function to compare two PCI device addresses.
  *
  * @param addr
@@ -194,6 +242,21 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 			     const struct rte_pci_addr *addr2);
 
 /**
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
+int pci_addr_cmp(const struct rte_pci_addr *addr,
+		 const struct rte_pci_addr *addr2);
+
+/**
  * Map a particular resource from a file.
  *
  * @param requested_addr
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index cbb5359..fc2fc7f 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -73,6 +73,12 @@ get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
 int
 eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	return pci_bdf_parse(input, dev_addr);
+}
+
+int
+pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
+{
 	const char *in = input;
 
 	dev_addr->domain = 0;
@@ -91,6 +97,12 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 int
 eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	return pci_dbdf_parse(input, dev_addr);
+}
+
+int
+pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
+{
 	const char *in = input;
 	unsigned long val;
 	char *end;
@@ -117,6 +129,13 @@ void
 rte_pci_device_name(const struct rte_pci_addr *addr,
 		    char *output, size_t size)
 {
+	pci_device_name(addr, output, size);
+}
+
+void
+pci_device_name(const struct rte_pci_addr *addr,
+		char *output, size_t size)
+{
 	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
 	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
 			    addr->domain, addr->bus,
@@ -127,6 +146,13 @@ int
 rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 			 const struct rte_pci_addr *addr2)
 {
+	return pci_addr_cmp(addr, addr2);
+}
+
+int
+pci_addr_cmp(const struct rte_pci_addr *addr,
+	     const struct rte_pci_addr *addr2)
+{
 	uint64_t dev_addr, dev_addr2;
 
 	if ((addr == NULL) || (addr2 == NULL))
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index a940259..8d180e3 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -3,6 +3,10 @@ DPDK_17.11 {
 
 	eal_parse_pci_BDF;
 	eal_parse_pci_DomBDF;
+	pci_addr_cmp;
+	pci_bdf_parse;
+	pci_dbdf_parse;
+	pci_device_name;
 	pci_map_resource;
 	pci_unmap_resource;
 	rte_eal_compare_pci_addr;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 13/20] pci: introduce PCI address parsing function
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (11 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 12/20] pci: deprecate misnamed functions Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 14/20] pci: make specialized parsing functions private Gaetan Rivet
                           ` (7 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

A new single function that is able to parse all currently supported
format:

   * Domain-Bus-Device-Function
   *        Bus-Device-Function

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_pci/include/rte_pci.h   | 15 +++++++++++++++
 lib/librte_pci/rte_pci.c           | 10 ++++++++++
 lib/librte_pci/rte_pci_version.map |  1 +
 3 files changed, 26 insertions(+)

diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
index 38cbdb3..9e79557 100644
--- a/lib/librte_pci/include/rte_pci.h
+++ b/lib/librte_pci/include/rte_pci.h
@@ -256,6 +256,21 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 int pci_addr_cmp(const struct rte_pci_addr *addr,
 		 const struct rte_pci_addr *addr2);
 
+
+/**
+ * Utility function to parse a string into a PCI location.
+ *
+ * @param str
+ *	The string to parse
+ * @param addr
+ *	The reference to the structure where the location
+ *	is stored.
+ * @return
+ *	0 on success
+ *	<0 otherwise
+ */
+int pci_addr_parse(const char *str, struct rte_pci_addr *addr);
+
 /**
  * Map a particular resource from a file.
  *
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index fc2fc7f..7ba472c 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -171,6 +171,16 @@ pci_addr_cmp(const struct rte_pci_addr *addr,
 		return 0;
 }
 
+int
+pci_addr_parse(const char *str, struct rte_pci_addr *addr)
+{
+	if (pci_bdf_parse(str, addr) == 0 ||
+	    pci_dbdf_parse(str, addr) == 0)
+		return 0;
+	return -1;
+}
+
+
 /* map a particular resource from a file */
 void *
 pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index 8d180e3..5f50f98 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -4,6 +4,7 @@ DPDK_17.11 {
 	eal_parse_pci_BDF;
 	eal_parse_pci_DomBDF;
 	pci_addr_cmp;
+	pci_addr_parse;
 	pci_bdf_parse;
 	pci_dbdf_parse;
 	pci_device_name;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 14/20] pci: make specialized parsing functions private
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (12 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 13/20] pci: introduce PCI address parsing function Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 15/20] bus/pci: use new PCI addr parsing function Gaetan Rivet
                           ` (6 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Do not expose the minute implementations of PCI parsing.
This leaves only the all-purpose pci_addr_parse, which is simpler to
use.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_pci/include/rte_pci.h   | 29 -----------------------------
 lib/librte_pci/rte_pci.c           | 28 ++++++++++++++--------------
 lib/librte_pci/rte_pci_version.map |  2 --
 3 files changed, 14 insertions(+), 45 deletions(-)

diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
index 9e79557..ea0897c 100644
--- a/lib/librte_pci/include/rte_pci.h
+++ b/lib/librte_pci/include/rte_pci.h
@@ -151,21 +151,6 @@ TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided without
- * a domain prefix (i.e. domain returned is always 0)
- *
- * @param input
- *	The input string to be parsed. Should have the format XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned.
- *	Domain will always be returned as 0
- * @return
- *  0 on success, negative on error.
- */
-int pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr);
-
-/**
  * @deprecated
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided including
@@ -181,20 +166,6 @@ int pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr);
 int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided including
- * a domain prefix.
- *
- * @param input
- *	The input string to be parsed. Should have the format XXXX:XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned
- * @return
- *  0 on success, negative on error.
- */
-int pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr);
-
-/**
  * @deprecated
  * Utility function to write a pci device name, this device name can later be
  * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index 7ba472c..1307a18 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -70,13 +70,7 @@ get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
 	return end + 1;
 }
 
-int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	return pci_bdf_parse(input, dev_addr);
-}
-
-int
+static int
 pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 {
 	const char *in = input;
@@ -94,13 +88,7 @@ pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 	return 0;
 }
 
-int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	return pci_dbdf_parse(input, dev_addr);
-}
-
-int
+static int
 pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 {
 	const char *in = input;
@@ -125,6 +113,18 @@ pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 	return 0;
 }
 
+int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	return pci_bdf_parse(input, dev_addr);
+}
+
+int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	return pci_dbdf_parse(input, dev_addr);
+}
+
 void
 rte_pci_device_name(const struct rte_pci_addr *addr,
 		    char *output, size_t size)
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index 5f50f98..b5c9ec2 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -5,8 +5,6 @@ DPDK_17.11 {
 	eal_parse_pci_DomBDF;
 	pci_addr_cmp;
 	pci_addr_parse;
-	pci_bdf_parse;
-	pci_dbdf_parse;
 	pci_device_name;
 	pci_map_resource;
 	pci_unmap_resource;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 15/20] bus/pci: use new PCI addr parsing function
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (13 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 14/20] pci: make specialized parsing functions private Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 16/20] bus/pci: do not expose private functions Gaetan Rivet
                           ` (5 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/bus/pci/pci_common.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index cd95d1a..d7a1c05 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -437,8 +437,7 @@ pci_parse(const char *name, void *addr)
 	struct rte_pci_addr pci_addr;
 	bool parse;
 
-	parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
-		 eal_parse_pci_DomBDF(name, &pci_addr) == 0);
+	parse = (pci_addr_parse(name, &pci_addr) == 0);
 	if (parse && addr != NULL)
 		*out = pci_addr;
 	return parse == false;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 16/20] bus/pci: do not expose private functions
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (14 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 15/20] bus/pci: use new PCI addr parsing function Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 17/20] bus/pci: do not expose PCI match function Gaetan Rivet
                           ` (4 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

make the functions

   + rte_pci_detach
   + rte_pci_probe
   + rte_pci_probe_one
   + rte_pci_scan

private as there is no point in using them outside of the rte_bus
framework.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/bus/pci/include/rte_bus_pci.h   | 49 ---------------------------------
 drivers/bus/pci/private.h               | 49 +++++++++++++++++++++++++++++++++
 drivers/bus/pci/rte_bus_pci_version.map |  4 ---
 3 files changed, 49 insertions(+), 53 deletions(-)

diff --git a/drivers/bus/pci/include/rte_bus_pci.h b/drivers/bus/pci/include/rte_bus_pci.h
index e6a7998..d188353 100644
--- a/drivers/bus/pci/include/rte_bus_pci.h
+++ b/drivers/bus/pci/include/rte_bus_pci.h
@@ -170,25 +170,6 @@ struct rte_pci_bus {
 /** Device driver supports IOVA as VA */
 #define RTE_PCI_DRV_IOVA_AS_VA 0X0040
 
-/**
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- *
- * @return
- *  0 on success, negative on error
- */
-int rte_pci_scan(void);
-
-/**
- * Probe the PCI bus
- *
- * @return
- *   - 0 on success.
- *   - !0 on error.
- */
-int
-rte_pci_probe(void);
-
 /*
  * Match the PCI Driver and Device using the ID Table
  *
@@ -242,36 +223,6 @@ int rte_pci_map_device(struct rte_pci_device *dev);
 void rte_pci_unmap_device(struct rte_pci_device *dev);
 
 /**
- * Probe the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the probe() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to probe.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_probe_one(const struct rte_pci_addr *addr);
-
-/**
- * Close the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the remove() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to close.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_detach(const struct rte_pci_addr *addr);
-
-/**
  * Dump the content of the PCI bus.
  *
  * @param f
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index fdc2c81..455c81d 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -43,6 +43,55 @@ struct rte_pci_driver;
 struct rte_pci_device;
 
 /**
+ * Probe the PCI bus
+ *
+ * @return
+ *   - 0 on success.
+ *   - !0 on error.
+ */
+int
+rte_pci_probe(void);
+
+/**
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ *
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_pci_scan(void);
+
+/**
+ * Probe the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the probe() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to probe.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_probe_one(const struct rte_pci_addr *addr);
+
+/**
+ * Close the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the remove() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_detach(const struct rte_pci_addr *addr);
+
+/**
  * Find the name of a PCI device.
  */
 void
diff --git a/drivers/bus/pci/rte_bus_pci_version.map b/drivers/bus/pci/rte_bus_pci_version.map
index c1973f6..ee67033 100644
--- a/drivers/bus/pci/rte_bus_pci_version.map
+++ b/drivers/bus/pci/rte_bus_pci_version.map
@@ -1,18 +1,14 @@
 DPDK_17.11 {
 	global:
 
-	rte_pci_detach;
 	rte_pci_dump;
 	rte_pci_ioport_map;
 	rte_pci_ioport_read;
 	rte_pci_ioport_unmap;
 	rte_pci_ioport_write;
 	rte_pci_map_device;
-	rte_pci_probe;
-	rte_pci_probe_one;
 	rte_pci_read_config;
 	rte_pci_register;
-	rte_pci_scan;
 	rte_pci_unmap_device;
 	rte_pci_unregister;
 	rte_pci_write_config;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 17/20] bus/pci: do not expose PCI match function
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (15 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 16/20] bus/pci: do not expose private functions Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 18/20] bus/pci: do not expose IOVA mode getter Gaetan Rivet
                           ` (3 subsequent siblings)
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

This function is private to the PCI bus.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/bus/pci/include/rte_bus_pci.h           | 16 ----------------
 drivers/bus/pci/private.h                       | 15 +++++++++++++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  1 -
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  1 -
 4 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/drivers/bus/pci/include/rte_bus_pci.h b/drivers/bus/pci/include/rte_bus_pci.h
index d188353..f0a3b37 100644
--- a/drivers/bus/pci/include/rte_bus_pci.h
+++ b/drivers/bus/pci/include/rte_bus_pci.h
@@ -170,22 +170,6 @@ struct rte_pci_bus {
 /** Device driver supports IOVA as VA */
 #define RTE_PCI_DRV_IOVA_AS_VA 0X0040
 
-/*
- * Match the PCI Driver and Device using the ID Table
- *
- * @param pci_drv
- *      PCI driver from which ID table would be extracted
- * @param pci_dev
- *      PCI device to match against the driver
- * @return
- *      1 for successful match
- *      0 for unsuccessful match
- */
-int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev);
-
-
 /**
  * Get iommu class of PCI devices on the bus.
  * And return their preferred iova mapping mode.
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 455c81d..b91217b 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -220,4 +220,19 @@ void pci_uio_free_resource(struct rte_pci_device *dev,
 int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
 		struct mapped_pci_resource *uio_res, int map_idx);
 
+/*
+ * Match the PCI Driver and Device using the ID Table
+ *
+ * @param pci_drv
+ *      PCI driver from which ID table would be extracted
+ * @param pci_dev
+ *      PCI device to match against the driver
+ * @return
+ *      1 for successful match
+ *      0 for unsuccessful match
+ */
+int
+rte_pci_match(const struct rte_pci_driver *pci_drv,
+	      const struct rte_pci_device *pci_dev);
+
 #endif /* _PCI_PRIVATE_H_ */
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 97b3918..1c18ca5 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -229,6 +229,5 @@ DPDK_17.11 {
 	rte_eal_mbuf_default_mempool_ops;
 	rte_lcore_has_role;
 	rte_pci_get_iommu_class;
-	rte_pci_match;
 
 } DPDK_17.08;
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index a8ea4ea..827bcd4 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -233,6 +233,5 @@ DPDK_17.11 {
 	rte_eal_mbuf_default_mempool_ops;
 	rte_lcore_has_role;
 	rte_pci_get_iommu_class;
-	rte_pci_match;
 
 } DPDK_17.08;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 18/20] bus/pci: do not expose IOVA mode getter
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (16 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 17/20] bus/pci: do not expose PCI match function Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:54           ` Gaëtan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 19/20] doc: add notes on EAL PCI API update Gaetan Rivet
                           ` (2 subsequent siblings)
  20 siblings, 1 reply; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/bus/pci/private.h                       | 10 ++++++++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  1 -
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |  1 -
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index b91217b..2283f09 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -235,4 +235,14 @@ int
 rte_pci_match(const struct rte_pci_driver *pci_drv,
 	      const struct rte_pci_device *pci_dev);
 
+/**
+ * Get iommu class of PCI devices on the bus.
+ * And return their preferred iova mapping mode.
+ *
+ * @return
+ *   - enum rte_iova_mode.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void);
+
 #endif /* _PCI_PRIVATE_H_ */
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 1c18ca5..1d879a1 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -228,6 +228,5 @@ DPDK_17.11 {
 	rte_eal_iova_mode;
 	rte_eal_mbuf_default_mempool_ops;
 	rte_lcore_has_role;
-	rte_pci_get_iommu_class;
 
 } DPDK_17.08;
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 827bcd4..1334433 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -232,6 +232,5 @@ DPDK_17.11 {
 	rte_eal_iova_mode;
 	rte_eal_mbuf_default_mempool_ops;
 	rte_lcore_has_role;
-	rte_pci_get_iommu_class;
 
 } DPDK_17.08;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 19/20] doc: add notes on EAL PCI API update
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (17 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 18/20] bus/pci: do not expose IOVA mode getter Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 20/20] bus: rename scan policy as probe policy Gaetan Rivet
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
  20 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Add a section related to EAL API changes to 17.11 release notes.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/rel_notes/release_17_11.rst | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 63b9869..ed3d6d8 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -232,6 +232,34 @@ API Changes
   By this way PMDs can return an error value in case of failure at stats
   getting process time.
 
+* **PCI bus API moved outside of the EAL**
+
+  The PCI bus previously implemented within the EAL has been moved.
+  A first part has been added as an RTE library providing PCI helpers to
+  parse device locations or other such utilities.
+  A second part consisting in the actual bus driver has been moved to its
+  proper subdirectory, without changing its functionalities.
+
+  As such, several PCI-related functions are not proposed by the EAL anymore:
+
+  * rte_pci_detach
+  * rte_pci_dump
+  * rte_pci_ioport_map
+  * rte_pci_ioport_read
+  * rte_pci_ioport_unmap
+  * rte_pci_ioport_write
+  * rte_pci_map_device
+  * rte_pci_probe
+  * rte_pci_probe_one
+  * rte_pci_read_config
+  * rte_pci_register
+  * rte_pci_scan
+  * rte_pci_unmap_device
+  * rte_pci_unregister
+  * rte_pci_write_config
+
+  These functions are made available either as part of ``librte_pci`` or
+  ``librte_bus_pci``.
 
 ABI Changes
 -----------
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v5 20/20] bus: rename scan policy as probe policy
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (18 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 19/20] doc: add notes on EAL PCI API update Gaetan Rivet
@ 2017-10-12 10:45         ` Gaetan Rivet
  2017-10-12 10:55           ` Gaëtan Rivet
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
  20 siblings, 1 reply; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-12 10:45 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

This bus configuration item is misnamed, as it actually refers to the
probing process.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/bus/pci/pci_common.c               |  2 +-
 lib/librte_eal/common/eal_common_devargs.c |  6 +++---
 lib/librte_eal/common/include/rte_bus.h    | 12 ++++++------
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index d7a1c05..cc23a39 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -373,7 +373,7 @@ rte_pci_probe(void)
 	int probe_all = 0;
 	int ret = 0;
 
-	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
+	if (rte_pci_bus.bus.conf.probe_mode != RTE_BUS_PROBE_WHITELIST)
 		probe_all = 1;
 
 	FOREACH_DEVICE_ON_PCIBUS(dev) {
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index 6ac88d6..f5ef913 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -170,11 +170,11 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
 	bus = devargs->bus;
 	if (devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI)
 		devargs->policy = RTE_DEV_BLACKLISTED;
-	if (bus->conf.scan_mode == RTE_BUS_SCAN_UNDEFINED) {
+	if (bus->conf.probe_mode == RTE_BUS_PROBE_UNDEFINED) {
 		if (devargs->policy == RTE_DEV_WHITELISTED)
-			bus->conf.scan_mode = RTE_BUS_SCAN_WHITELIST;
+			bus->conf.probe_mode = RTE_BUS_PROBE_WHITELIST;
 		else if (devargs->policy == RTE_DEV_BLACKLISTED)
-			bus->conf.scan_mode = RTE_BUS_SCAN_BLACKLIST;
+			bus->conf.probe_mode = RTE_BUS_PROBE_BLACKLIST;
 	}
 	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
 	return 0;
diff --git a/lib/librte_eal/common/include/rte_bus.h b/lib/librte_eal/common/include/rte_bus.h
index 6fb0834..331d954 100644
--- a/lib/librte_eal/common/include/rte_bus.h
+++ b/lib/librte_eal/common/include/rte_bus.h
@@ -168,19 +168,19 @@ typedef int (*rte_bus_unplug_t)(struct rte_device *dev);
 typedef int (*rte_bus_parse_t)(const char *name, void *addr);
 
 /**
- * Bus scan policies
+ * Bus probe policies
  */
-enum rte_bus_scan_mode {
-	RTE_BUS_SCAN_UNDEFINED,
-	RTE_BUS_SCAN_WHITELIST,
-	RTE_BUS_SCAN_BLACKLIST,
+enum rte_bus_probe_mode {
+	RTE_BUS_PROBE_UNDEFINED,
+	RTE_BUS_PROBE_WHITELIST,
+	RTE_BUS_PROBE_BLACKLIST,
 };
 
 /**
  * A structure used to configure bus operations.
  */
 struct rte_bus_conf {
-	enum rte_bus_scan_mode scan_mode; /**< Scan policy. */
+	enum rte_bus_probe_mode probe_mode; /**< Probe policy. */
 };
 
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v5 18/20] bus/pci: do not expose IOVA mode getter
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 18/20] bus/pci: do not expose IOVA mode getter Gaetan Rivet
@ 2017-10-12 10:54           ` Gaëtan Rivet
  0 siblings, 0 replies; 156+ messages in thread
From: Gaëtan Rivet @ 2017-10-12 10:54 UTC (permalink / raw)
  To: dev

On Thu, Oct 12, 2017 at 12:45:45PM +0200, Gaetan Rivet wrote:
> Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> ---
>  drivers/bus/pci/private.h                       | 10 ++++++++++
>  lib/librte_eal/bsdapp/eal/rte_eal_version.map   |  1 -
>  lib/librte_eal/linuxapp/eal/rte_eal_version.map |  1 -
>  3 files changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
> index b91217b..2283f09 100644
> --- a/drivers/bus/pci/private.h
> +++ b/drivers/bus/pci/private.h
> @@ -235,4 +235,14 @@ int
>  rte_pci_match(const struct rte_pci_driver *pci_drv,
>  	      const struct rte_pci_device *pci_dev);
>  
> +/**
> + * Get iommu class of PCI devices on the bus.
> + * And return their preferred iova mapping mode.
> + *
> + * @return
> + *   - enum rte_iova_mode.
> + */
> +enum rte_iova_mode
> +rte_pci_get_iommu_class(void);
> +

Made a mistake here while rebasing.
The function declaration should be removed from

  drivers/bus/pci/include/rte_bus_pci.h

as well.

>  #endif /* _PCI_PRIVATE_H_ */
> diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> index 1c18ca5..1d879a1 100644
> --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
> @@ -228,6 +228,5 @@ DPDK_17.11 {
>  	rte_eal_iova_mode;
>  	rte_eal_mbuf_default_mempool_ops;
>  	rte_lcore_has_role;
> -	rte_pci_get_iommu_class;
>  
>  } DPDK_17.08;
> diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> index 827bcd4..1334433 100644
> --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
> @@ -232,6 +232,5 @@ DPDK_17.11 {
>  	rte_eal_iova_mode;
>  	rte_eal_mbuf_default_mempool_ops;
>  	rte_lcore_has_role;
> -	rte_pci_get_iommu_class;
>  
>  } DPDK_17.08;
> -- 
> 2.1.4
> 

-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v5 20/20] bus: rename scan policy as probe policy
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 20/20] bus: rename scan policy as probe policy Gaetan Rivet
@ 2017-10-12 10:55           ` Gaëtan Rivet
  0 siblings, 0 replies; 156+ messages in thread
From: Gaëtan Rivet @ 2017-10-12 10:55 UTC (permalink / raw)
  To: dev

This patch is not part of this series, sorry.
I can send a v6 if necessary, but here simply ignore this patch.

On Thu, Oct 12, 2017 at 12:45:47PM +0200, Gaetan Rivet wrote:
> This bus configuration item is misnamed, as it actually refers to the
> probing process.
> 
> Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> ---
>  drivers/bus/pci/pci_common.c               |  2 +-
>  lib/librte_eal/common/eal_common_devargs.c |  6 +++---
>  lib/librte_eal/common/include/rte_bus.h    | 12 ++++++------
>  3 files changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
> index d7a1c05..cc23a39 100644
> --- a/drivers/bus/pci/pci_common.c
> +++ b/drivers/bus/pci/pci_common.c
> @@ -373,7 +373,7 @@ rte_pci_probe(void)
>  	int probe_all = 0;
>  	int ret = 0;
>  
> -	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
> +	if (rte_pci_bus.bus.conf.probe_mode != RTE_BUS_PROBE_WHITELIST)
>  		probe_all = 1;
>  
>  	FOREACH_DEVICE_ON_PCIBUS(dev) {
> diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
> index 6ac88d6..f5ef913 100644
> --- a/lib/librte_eal/common/eal_common_devargs.c
> +++ b/lib/librte_eal/common/eal_common_devargs.c
> @@ -170,11 +170,11 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
>  	bus = devargs->bus;
>  	if (devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI)
>  		devargs->policy = RTE_DEV_BLACKLISTED;
> -	if (bus->conf.scan_mode == RTE_BUS_SCAN_UNDEFINED) {
> +	if (bus->conf.probe_mode == RTE_BUS_PROBE_UNDEFINED) {
>  		if (devargs->policy == RTE_DEV_WHITELISTED)
> -			bus->conf.scan_mode = RTE_BUS_SCAN_WHITELIST;
> +			bus->conf.probe_mode = RTE_BUS_PROBE_WHITELIST;
>  		else if (devargs->policy == RTE_DEV_BLACKLISTED)
> -			bus->conf.scan_mode = RTE_BUS_SCAN_BLACKLIST;
> +			bus->conf.probe_mode = RTE_BUS_PROBE_BLACKLIST;
>  	}
>  	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
>  	return 0;
> diff --git a/lib/librte_eal/common/include/rte_bus.h b/lib/librte_eal/common/include/rte_bus.h
> index 6fb0834..331d954 100644
> --- a/lib/librte_eal/common/include/rte_bus.h
> +++ b/lib/librte_eal/common/include/rte_bus.h
> @@ -168,19 +168,19 @@ typedef int (*rte_bus_unplug_t)(struct rte_device *dev);
>  typedef int (*rte_bus_parse_t)(const char *name, void *addr);
>  
>  /**
> - * Bus scan policies
> + * Bus probe policies
>   */
> -enum rte_bus_scan_mode {
> -	RTE_BUS_SCAN_UNDEFINED,
> -	RTE_BUS_SCAN_WHITELIST,
> -	RTE_BUS_SCAN_BLACKLIST,
> +enum rte_bus_probe_mode {
> +	RTE_BUS_PROBE_UNDEFINED,
> +	RTE_BUS_PROBE_WHITELIST,
> +	RTE_BUS_PROBE_BLACKLIST,
>  };
>  
>  /**
>   * A structure used to configure bus operations.
>   */
>  struct rte_bus_conf {
> -	enum rte_bus_scan_mode scan_mode; /**< Scan policy. */
> +	enum rte_bus_probe_mode probe_mode; /**< Probe policy. */
>  };
>  
>  
> -- 
> 2.1.4
> 

-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v5 10/20] pci: avoid inlining functions
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 10/20] pci: avoid inlining functions Gaetan Rivet
@ 2017-10-17 18:20           ` Aaron Conole
  2017-10-18  8:54             ` Gaëtan Rivet
  0 siblings, 1 reply; 156+ messages in thread
From: Aaron Conole @ 2017-10-17 18:20 UTC (permalink / raw)
  To: Gaetan Rivet; +Cc: dev

Gaetan Rivet <gaetan.rivet@6wind.com> writes:

> Parsing operations should not happen in performance critical sections.
> Headers should not propose implementations unless duly required.
>
> Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> ---

Can these cleanups be done before the move in patch 3?

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v5 10/20] pci: avoid inlining functions
  2017-10-17 18:20           ` Aaron Conole
@ 2017-10-18  8:54             ` Gaëtan Rivet
  2017-10-18 14:30               ` Aaron Conole
  0 siblings, 1 reply; 156+ messages in thread
From: Gaëtan Rivet @ 2017-10-18  8:54 UTC (permalink / raw)
  To: Aaron Conole; +Cc: dev

On Tue, Oct 17, 2017 at 02:20:45PM -0400, Aaron Conole wrote:
> Gaetan Rivet <gaetan.rivet@6wind.com> writes:
> 
> > Parsing operations should not happen in performance critical sections.
> > Headers should not propose implementations unless duly required.
> >
> > Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> > ---
> 
> Can these cleanups be done before the move in patch 3?

Sure.

I wanted to minimize the changes before moving the code. If I had rework
to do on these patches, I wanted to avoid having to redo the move and
verify the changes were properly propagated.

But if it is necessary, these changes can happen before moving the whole
lot.

-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v5 10/20] pci: avoid inlining functions
  2017-10-18  8:54             ` Gaëtan Rivet
@ 2017-10-18 14:30               ` Aaron Conole
  0 siblings, 0 replies; 156+ messages in thread
From: Aaron Conole @ 2017-10-18 14:30 UTC (permalink / raw)
  To: Gaëtan Rivet; +Cc: dev

Gaëtan Rivet <gaetan.rivet@6wind.com> writes:

> On Tue, Oct 17, 2017 at 02:20:45PM -0400, Aaron Conole wrote:
>> Gaetan Rivet <gaetan.rivet@6wind.com> writes:
>> 
>> > Parsing operations should not happen in performance critical sections.
>> > Headers should not propose implementations unless duly required.
>> >
>> > Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
>> > ---
>> 
>> Can these cleanups be done before the move in patch 3?
>
> Sure.
>
> I wanted to minimize the changes before moving the code. If I had rework
> to do on these patches, I wanted to avoid having to redo the move and
> verify the changes were properly propagated.

I use 'git rebase -i' to do changes; it can take care of moving through
a stack of changes.

> But if it is necessary, these changes can happen before moving the whole
> lot.

I think it's better to do all the changes before hand.  If there is a
change that could be part of a bug fix, it can be easily backported to
stable branches.

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL
  2017-10-11 14:32     ` Gaëtan Rivet
@ 2017-10-23  8:44       ` De Lara Guarch, Pablo
  2017-10-23  8:49         ` Gaëtan Rivet
  0 siblings, 1 reply; 156+ messages in thread
From: De Lara Guarch, Pablo @ 2017-10-23  8:44 UTC (permalink / raw)
  To: Gaëtan Rivet, Doherty, Declan; +Cc: dev

Hi Gaetan,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Gaëtan Rivet
> Sent: Wednesday, October 11, 2017 3:32 PM
> To: Doherty, Declan <declan.doherty@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL
> 
> On Wed, Oct 11, 2017 at 03:19:31PM +0100, Doherty, Declan wrote:
> > On 18/09/2017 10:31 AM, Gaetan Rivet wrote:
> > >Hi all,
> > >
> > >Here is a new version of the PCI bus move out of the EAL.
> > >
> > >The EAL PCI implementation is divided in two parts:
> > >
> > >   - librte_pci: library offering helpers to handle PCI objects
> > >   - librte_bus_pci: bus driver for PCI devices
> > >
> > >This allows other libraries / tools to use PCI elements (location,
> > >mappings, parsing operations, etc) without forcing a dependency on a
> bus driver.
> > >
> > >The latter should not have to export helpers that others might need.
> > >It is focused on defining the rte_pci_device, rte_pci_driver objects
> > >and their handling.
> > >
> > >The cryptodev library has hard dependencies on rte_pci_devices (used
> > >by generic probe function). Other similar libs (ether and eventdev)
> > >avoided the issue by inlining such functions and expecting users to
> > >include the relevant headers once the PCI bus has already been built.
> > >
> > >@Declan:
> > >I proposed a solution that would avoid inlining those functions,
> > >which does not feel right. Let me know what you think of it or if you
> > >think of a better solution. I think it would be best to have
> > >cryptodev completely independent from PCI / vdev as far as the lib in
> > >concerned (the vdev bus will move as well).
> > >
> >
> >
> > Hey Gaetan, apologies for the delay in getting back to you on this, I
> > had been looking at this but got sidelined onto other issues before
> > usersapce and I'm only getting back to it now. I think that while your
> > solution works it just highlights the dependency which probably
> > shouldn't be there between the cryptodev library and PCI devices. I've
> > had a look, and the functions in the cryptodev which you moved don't
> > really provide that much useful functionality. I done some testing and
> > completely removed them and just update the QAT PMD which is the only
> > crypto PMD which was using them and it seems much cleaner to me. I'll
> > push a patch for this change later today and it will allow you to drop
> > the patch "cryptodev: move PCI specific helpers to drivers/crypto" from
> this set.
> >
> > Regards
> > Declan
> >
> >
> >
> 
> Hi Declan,
> 
> All right, seems good from my PoV. I will rebase onto your patch once it is
> sent.
> 

Could you take a look at Declan's patchset and tell him what you think?
http://dpdk.org/ml/archives/dev/2017-October/079827.html

It might be a bit late, but if we think it is a better approach for cryptodev,
we could avoid creating a new PCI folder under drivers/crypto.

Thanks!
Pablo

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL
  2017-10-23  8:44       ` De Lara Guarch, Pablo
@ 2017-10-23  8:49         ` Gaëtan Rivet
  0 siblings, 0 replies; 156+ messages in thread
From: Gaëtan Rivet @ 2017-10-23  8:49 UTC (permalink / raw)
  To: De Lara Guarch, Pablo; +Cc: Doherty, Declan, dev

Hello Pablo,

On Mon, Oct 23, 2017 at 08:44:31AM +0000, De Lara Guarch, Pablo wrote:
> Hi Gaetan,
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Gaëtan Rivet
> > Sent: Wednesday, October 11, 2017 3:32 PM
> > To: Doherty, Declan <declan.doherty@intel.com>
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL
> > 
> > On Wed, Oct 11, 2017 at 03:19:31PM +0100, Doherty, Declan wrote:
> > > On 18/09/2017 10:31 AM, Gaetan Rivet wrote:
> > > >Hi all,
> > > >
> > > >Here is a new version of the PCI bus move out of the EAL.
> > > >
> > > >The EAL PCI implementation is divided in two parts:
> > > >
> > > >   - librte_pci: library offering helpers to handle PCI objects
> > > >   - librte_bus_pci: bus driver for PCI devices
> > > >
> > > >This allows other libraries / tools to use PCI elements (location,
> > > >mappings, parsing operations, etc) without forcing a dependency on a
> > bus driver.
> > > >
> > > >The latter should not have to export helpers that others might need.
> > > >It is focused on defining the rte_pci_device, rte_pci_driver objects
> > > >and their handling.
> > > >
> > > >The cryptodev library has hard dependencies on rte_pci_devices (used
> > > >by generic probe function). Other similar libs (ether and eventdev)
> > > >avoided the issue by inlining such functions and expecting users to
> > > >include the relevant headers once the PCI bus has already been built.
> > > >
> > > >@Declan:
> > > >I proposed a solution that would avoid inlining those functions,
> > > >which does not feel right. Let me know what you think of it or if you
> > > >think of a better solution. I think it would be best to have
> > > >cryptodev completely independent from PCI / vdev as far as the lib in
> > > >concerned (the vdev bus will move as well).
> > > >
> > >
> > >
> > > Hey Gaetan, apologies for the delay in getting back to you on this, I
> > > had been looking at this but got sidelined onto other issues before
> > > usersapce and I'm only getting back to it now. I think that while your
> > > solution works it just highlights the dependency which probably
> > > shouldn't be there between the cryptodev library and PCI devices. I've
> > > had a look, and the functions in the cryptodev which you moved don't
> > > really provide that much useful functionality. I done some testing and
> > > completely removed them and just update the QAT PMD which is the only
> > > crypto PMD which was using them and it seems much cleaner to me. I'll
> > > push a patch for this change later today and it will allow you to drop
> > > the patch "cryptodev: move PCI specific helpers to drivers/crypto" from
> > this set.
> > >
> > > Regards
> > > Declan
> > >
> > >
> > >
> > 
> > Hi Declan,
> > 
> > All right, seems good from my PoV. I will rebase onto your patch once it is
> > sent.
> > 
> 
> Could you take a look at Declan's patchset and tell him what you think?
> http://dpdk.org/ml/archives/dev/2017-October/079827.html
> 
> It might be a bit late, but if we think it is a better approach for cryptodev,
> we could avoid creating a new PCI folder under drivers/crypto.
> 
> Thanks!
> Pablo
> 

Thanks for the heads up :)

I was working with a stand-in patch on my PCI move series, I will use
yours instead and see if I have any problem.

I am bound to send a new version soon, if all is fine I will add the
dependency on your series.

-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL
  2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
                           ` (19 preceding siblings ...)
  2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 20/20] bus: rename scan policy as probe policy Gaetan Rivet
@ 2017-10-25 22:38         ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 01/25] ethdev: remove useless PCI dependency Gaetan Rivet
                             ` (25 more replies)
  20 siblings, 26 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet, Aaron Conole, Anatoly Burakov

Hi all,

Here is a new version of the PCI bus move out of the EAL.

The EAL PCI implementation is divided in two parts:

  - librte_pci: library offering helpers to handle PCI objects
  - librte_bus_pci: bus driver for PCI devices

This allows other libraries / tools to use PCI elements (location, mappings,
parsing operations, etc) without forcing a dependency on a bus driver.

The latter should not have to export helpers that others might need. It
is focused on defining the rte_pci_device, rte_pci_driver objects and
their handling.

The cryptodev library has hard dependencies on rte_pci_devices (used by
generic probe function). Other similar libs (ether and eventdev) avoided
the issue by inlining such functions and expecting users to include the
relevant headers once the PCI bus has already been built.

After review from Declan, he proposed to submit a patch removing this dependency.
Once this patch is submitted, the relevant commit will be dropped from this
patchset.

v2:

  + Made rte_eal_using_phys_addrs common to both linux and bsd interfaces.
  + Added documentation of EAL API changes in release note.
  + Fixed a few rebase-related mistakes.
  + Fixed parallel build race condition reported by Luca Boccassi.
  + Grouped together commits breaking compilation:

    -> pci: introduce PCI lib and bus
    -> lib: include rte_bus_pci
    -> drivers: include rte_bus_pci
    -> test: include rte_bus_pci
    -> app/testpmd: include rte_bus_pci
    -> cryptodev: move PCI specific helpers to drivers/crypto

  Until all of them have been applied, compilation is broken.
  I am currently wondering whether merging some of them might
  be sensible.

  + Not included in this series:

    Several filesystem-related functions are currently
    private to the EAL and directly linked. This is not good,
    but the solution seems to be to have a new lib offering an FS abstraction.
    This seems an overreach for this patchset and should probably come in a
    second step.

v3:

  + Fixed .map versioning
  + merged one commit breaking the build into the main commit moving
    code around.

    Other such commits are still present, as they only break specific subsystems
    (lib, drivers, apps, cryptodev). Merging them all within the one main commit
    does not seem right.

    As such, build is still broken from

       * pci: introduce PCI lib and bus

    until

       * cryptodev: move PCI specific helpers to drivers/crypto

v4:

  + Rebased unto master, with new PCI functionalities integrated.
  + Removed the exposition of private EAL functions.
    While one commit did deal with this for one function, the issue is more
    widespread and should be fixed in a more generic way.
  + Introduced new PCI address parsing function,
    deprecating the old ones.
  + Fix conflict with bonding PMD regarding pci_addr_cmp function name.

v5:

  + Rebase unto master: fix a few compilation issues with the header change.
  + Make more PCI bus functions private.

v6: (Not sent publicly)

  + Made a mistake when formatting the patches.
  + fixed a rebase error in the commit

     bus/pci: do not expose IOVA mode getter

               ~*~

 Compilation is still broken from

    * pci: introduce PCI lib and bus

 until

    * net/bonding: use local prefix for local function

v7:

  + Fixed compilation issues with shared build
    This required exposing several private EAL symbols
    from VFIO and internal_config.

Cc: Anatoly Burakov <anatoly.burakov@intel.com>

    For VFIO

  + Squashed all commits breaking compilation into
    the single big move. compilation is stable throughout the series now.

  + Removed cryptodev commit, now based upon Declan's work (see patchset dependencies).

  + Moved PCI enhancement prior to moving code into the lib and bus.
    Thanks to Aaron Conole for the suggestion.

  + Fixed build on FreeBSD

  + Claimed ownership on librte_pci, for the time being.

This patchset now depends on:

Break dependency on bus infrastructure
http://dpdk.org/ml/archives/dev/2017-October/079827.html

Gaetan Rivet (25):
  ethdev: remove useless PCI dependency
  eal: include debug header in bus source
  eal: include stdint in private header
  eal: include common header
  eal: expose rte_eal_using_phys_addrs
  eal: expose internal config elements
  eal: expose vfio symbols
  vfio: remove useless PCI headers and add vfio one
  vfio: check PCI dependency from within PCI code
  vfio: move PCI-related functions out of vfio header
  pci: avoid inlining functions
  pci: avoid over-complicated macro
  pci: deprecate misnamed functions
  pci: introduce PCI address parsing function
  pci: make specialized parsing functions private
  pci: use new PCI addr comparison function
  pci: use new PCI addr parsing function
  pci: do not expose private functions
  pci: do not expose PCI match function
  pci: do not expose IOVA mode getter
  pci: use EAL exposed configuration
  net/bonding: use local prefix for local function
  pci: introduce PCI lib and bus
  doc: add notes on EAL PCI API update
  maintainers: claim maintainership of PCI lib

 MAINTAINERS                                    |   4 +
 app/test-pmd/testpmd.h                         |   1 +
 config/common_base                             |  10 +
 doc/guides/rel_notes/deprecation.rst           |   7 +
 doc/guides/rel_notes/release_17_11.rst         |  28 +
 drivers/bus/Makefile                           |   2 +
 drivers/bus/fslmc/fslmc_vfio.h                 |   2 +
 drivers/bus/pci/Makefile                       |  62 ++
 drivers/bus/pci/bsd/Makefile                   |  32 +
 drivers/bus/pci/bsd/pci.c                      | 681 ++++++++++++++++++++
 drivers/bus/pci/include/rte_bus_pci.h          | 340 ++++++++++
 drivers/bus/pci/linux/Makefile                 |  36 ++
 drivers/bus/pci/linux/pci.c                    | 826 +++++++++++++++++++++++++
 drivers/bus/pci/linux/pci_init.h               |  99 +++
 drivers/bus/pci/linux/pci_uio.c                | 568 +++++++++++++++++
 drivers/bus/pci/linux/pci_vfio.c               | 756 ++++++++++++++++++++++
 drivers/bus/pci/pci_common.c                   | 535 ++++++++++++++++
 drivers/bus/pci/pci_common_uio.c               | 235 +++++++
 drivers/bus/pci/private.h                      | 248 ++++++++
 drivers/bus/pci/rte_bus_pci_version.map        |  17 +
 drivers/crypto/qat/Makefile                    |   1 +
 drivers/crypto/qat/qat_qp.c                    |   1 +
 drivers/crypto/qat/rte_qat_cryptodev.c         |   1 +
 drivers/event/octeontx/Makefile                |   1 +
 drivers/event/skeleton/Makefile                |   1 +
 drivers/mempool/octeontx/Makefile              |   1 +
 drivers/mempool/octeontx/octeontx_fpavf.c      |   2 +-
 drivers/mempool/octeontx/octeontx_ssovf.c      |   1 +
 drivers/net/ark/Makefile                       |   1 +
 drivers/net/ark/ark_ethdev.c                   |   1 +
 drivers/net/avp/Makefile                       |   1 +
 drivers/net/avp/avp_ethdev.c                   |   2 +
 drivers/net/bnx2x/Makefile                     |   1 +
 drivers/net/bnxt/Makefile                      |   1 +
 drivers/net/bnxt/bnxt.h                        |   1 +
 drivers/net/bonding/Makefile                   |   1 +
 drivers/net/bonding/rte_eth_bond_args.c        |   5 +-
 drivers/net/cxgbe/Makefile                     |   1 +
 drivers/net/cxgbe/base/adapter.h               |   1 +
 drivers/net/cxgbe/cxgbe_ethdev.c               |   1 +
 drivers/net/e1000/Makefile                     |   1 +
 drivers/net/e1000/em_ethdev.c                  |   1 +
 drivers/net/e1000/igb_ethdev.c                 |   1 +
 drivers/net/e1000/igb_pf.c                     |   1 +
 drivers/net/ena/Makefile                       |   1 +
 drivers/net/ena/ena_ethdev.h                   |   1 +
 drivers/net/enic/Makefile                      |   1 +
 drivers/net/enic/base/vnic_dev.h               |   4 +-
 drivers/net/enic/enic_ethdev.c                 |   1 +
 drivers/net/enic/enic_main.c                   |   1 +
 drivers/net/fm10k/Makefile                     |   1 +
 drivers/net/i40e/Makefile                      |   1 +
 drivers/net/i40e/i40e_ethdev.c                 |   1 +
 drivers/net/i40e/i40e_ethdev_vf.c              |   1 +
 drivers/net/ixgbe/Makefile                     |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c               |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.h               |   1 +
 drivers/net/liquidio/Makefile                  |   1 +
 drivers/net/mlx4/Makefile                      |   1 +
 drivers/net/mlx4/mlx4_ethdev.c                 |   1 +
 drivers/net/mlx5/Makefile                      |   1 +
 drivers/net/mlx5/mlx5.c                        |   1 +
 drivers/net/mlx5/mlx5_ethdev.c                 |   1 +
 drivers/net/nfp/Makefile                       |   1 +
 drivers/net/nfp/nfp_nfpu.c                     |   2 +-
 drivers/net/nfp/nfp_nfpu.h                     |   2 +-
 drivers/net/octeontx/Makefile                  |   1 +
 drivers/net/octeontx/base/octeontx_pkivf.c     |   2 +-
 drivers/net/octeontx/base/octeontx_pkovf.c     |   2 +-
 drivers/net/qede/Makefile                      |   1 +
 drivers/net/sfc/Makefile                       |   1 +
 drivers/net/sfc/sfc.h                          |   1 +
 drivers/net/sfc/sfc_ethdev.c                   |   1 +
 drivers/net/szedata2/Makefile                  |   1 +
 drivers/net/thunderx/Makefile                  |   1 +
 drivers/net/thunderx/nicvf_ethdev.c            |   1 +
 drivers/net/virtio/Makefile                    |   1 +
 drivers/net/virtio/virtio_ethdev.c             |   1 +
 drivers/net/virtio/virtio_pci.h                |   1 +
 drivers/net/vmxnet3/Makefile                   |   1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c           |   1 +
 lib/Makefile                                   |   2 +
 lib/librte_eal/bsdapp/eal/Makefile             |   3 -
 lib/librte_eal/bsdapp/eal/eal.c                |  58 +-
 lib/librte_eal/bsdapp/eal/eal_memory.c         |   6 +
 lib/librte_eal/bsdapp/eal/eal_pci.c            | 680 --------------------
 lib/librte_eal/common/Makefile                 |   4 +-
 lib/librte_eal/common/arch/x86/rte_cycles.c    |   2 +
 lib/librte_eal/common/eal_common_bus.c         |   1 +
 lib/librte_eal/common/eal_common_pci.c         | 573 -----------------
 lib/librte_eal/common/eal_common_pci_uio.c     | 233 -------
 lib/librte_eal/common/eal_private.h            | 144 +----
 lib/librte_eal/common/include/rte_eal.h        |  28 +
 lib/librte_eal/common/include/rte_memory.h     |  11 +
 lib/librte_eal/common/include/rte_pci.h        | 633 -------------------
 lib/librte_eal/common/include/rte_vfio.h       | 130 ++++
 lib/librte_eal/linuxapp/eal/Makefile           |   8 -
 lib/librte_eal/linuxapp/eal/eal.c              |  23 +-
 lib/librte_eal/linuxapp/eal/eal_interrupts.c   |   2 +-
 lib/librte_eal/linuxapp/eal/eal_memory.c       |   2 +-
 lib/librte_eal/linuxapp/eal/eal_pci.c          | 818 ------------------------
 lib/librte_eal/linuxapp/eal/eal_pci_init.h     |  97 ---
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c      | 567 -----------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c     | 750 ----------------------
 lib/librte_eal/linuxapp/eal/eal_vfio.c         |   1 +
 lib/librte_eal/linuxapp/eal/eal_vfio.h         |  19 -
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c |   4 +-
 lib/librte_eal/rte_eal_version.map             |  26 +-
 lib/librte_ether/rte_ethdev.c                  |   1 -
 lib/librte_ether/rte_ethdev.h                  |   2 -
 lib/librte_ether/rte_ethdev_pci.h              |   1 +
 lib/librte_eventdev/rte_eventdev_pmd_pci.h     |   1 +
 lib/librte_pci/Makefile                        |  49 ++
 lib/librte_pci/include/rte_pci.h               | 279 +++++++++
 lib/librte_pci/rte_pci.c                       | 220 +++++++
 lib/librte_pci/rte_pci_version.map             |  15 +
 mk/rte.app.mk                                  |   3 +
 test/test/test_kni.c                           |   1 +
 test/test/virtual_pmd.c                        |   1 +
 119 files changed, 5396 insertions(+), 4565 deletions(-)
 create mode 100644 drivers/bus/pci/Makefile
 create mode 100644 drivers/bus/pci/bsd/Makefile
 create mode 100644 drivers/bus/pci/bsd/pci.c
 create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
 create mode 100644 drivers/bus/pci/linux/Makefile
 create mode 100644 drivers/bus/pci/linux/pci.c
 create mode 100644 drivers/bus/pci/linux/pci_init.h
 create mode 100644 drivers/bus/pci/linux/pci_uio.c
 create mode 100644 drivers/bus/pci/linux/pci_vfio.c
 create mode 100644 drivers/bus/pci/pci_common.c
 create mode 100644 drivers/bus/pci/pci_common_uio.c
 create mode 100644 drivers/bus/pci/private.h
 create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
 delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
 delete mode 100644 lib/librte_eal/common/include/rte_pci.h
 create mode 100644 lib/librte_eal/common/include/rte_vfio.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
 create mode 100644 lib/librte_pci/Makefile
 create mode 100644 lib/librte_pci/include/rte_pci.h
 create mode 100644 lib/librte_pci/rte_pci.c
 create mode 100644 lib/librte_pci/rte_pci_version.map

-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 01/25] ethdev: remove useless PCI dependency
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 02/25] eal: include debug header in bus source Gaetan Rivet
                             ` (24 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ether/rte_ethdev.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 0b1e928..e91c963 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -47,7 +47,6 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_interrupts.h>
-#include <rte_pci.h>
 #include <rte_memory.h>
 #include <rte_memcpy.h>
 #include <rte_memzone.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 02/25] eal: include debug header in bus source
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 01/25] ethdev: remove useless PCI dependency Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 03/25] eal: include stdint in private header Gaetan Rivet
                             ` (23 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

This header is included through rte_pci.h, which will be removed once
the PCI bus is moved out of the EAL.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_bus.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
index 5c63ced..3e022d5 100644
--- a/lib/librte_eal/common/eal_common_bus.c
+++ b/lib/librte_eal/common/eal_common_bus.c
@@ -35,6 +35,7 @@
 #include <sys/queue.h>
 
 #include <rte_bus.h>
+#include <rte_debug.h>
 
 #include "eal_private.h"
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 03/25] eal: include stdint in private header
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 01/25] ethdev: remove useless PCI dependency Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 02/25] eal: include debug header in bus source Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 04/25] eal: include common header Gaetan Rivet
                             ` (22 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_private.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 6e0f85d..9340b6e 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -35,6 +35,7 @@
 #define _EAL_PRIVATE_H_
 
 #include <stdbool.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <rte_pci.h>
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 04/25] eal: include common header
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (2 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 03/25] eal: include stdint in private header Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 05/25] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
                             ` (21 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

The macro RTE_SET_USED is defined in rte_common.h

This header is included through eal_private.h, which includes in turn
rte_pci.h

Once the PCI subsystem is out of the EAL, this will break the
compilation (seen on FreeBSD).

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/arch/x86/rte_cycles.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_eal/common/arch/x86/rte_cycles.c b/lib/librte_eal/common/arch/x86/rte_cycles.c
index b286d90..417850e 100644
--- a/lib/librte_eal/common/arch/x86/rte_cycles.c
+++ b/lib/librte_eal/common/arch/x86/rte_cycles.c
@@ -35,6 +35,8 @@
 #include <unistd.h>
 #include <cpuid.h>
 
+#include <rte_common.h>
+
 #include "eal_private.h"
 
 static unsigned int
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 05/25] eal: expose rte_eal_using_phys_addrs
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (3 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 04/25] eal: include common header Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 06/25] eal: expose internal config elements Gaetan Rivet
                             ` (20 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

This function was previously private to the EAL layer.
Other subsystems requires it, such as the PCI bus.

In order not to force other components to include stdbool, which is
incompatible with several NIC drivers, the return type has
been changed from bool to int.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/bsdapp/eal/eal_memory.c     |  6 ++++++
 lib/librte_eal/common/eal_private.h        | 11 -----------
 lib/librte_eal/common/include/rte_memory.h | 11 +++++++++++
 lib/librte_eal/linuxapp/eal/eal_memory.c   |  2 +-
 lib/librte_eal/rte_eal_version.map         |  1 +
 5 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal_memory.c b/lib/librte_eal/bsdapp/eal/eal_memory.c
index 3614da8..65c96b0 100644
--- a/lib/librte_eal/bsdapp/eal/eal_memory.c
+++ b/lib/librte_eal/bsdapp/eal/eal_memory.c
@@ -192,3 +192,9 @@ rte_eal_hugepage_attach(void)
 		close(fd_hugepage);
 	return -1;
 }
+
+int
+rte_eal_using_phys_addrs(void)
+{
+	return 0;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 9340b6e..80fea24 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -345,17 +345,6 @@ int rte_eal_hugepage_init(void);
 int rte_eal_hugepage_attach(void);
 
 /**
- * Returns true if the system is able to obtain
- * physical addresses. Return false if using DMA
- * addresses through an IOMMU.
- *
- * Drivers based on uio will not load unless physical
- * addresses are obtainable. It is only possible to get
- * physical addresses when running as a privileged user.
- */
-bool rte_eal_using_phys_addrs(void);
-
-/**
  * Find a bus capable of identifying a device.
  *
  * @param str
diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h
index c545963..271d2bb 100644
--- a/lib/librte_eal/common/include/rte_memory.h
+++ b/lib/librte_eal/common/include/rte_memory.h
@@ -187,6 +187,17 @@ unsigned rte_memory_get_nchannel(void);
  */
 unsigned rte_memory_get_nrank(void);
 
+/**
+ * Drivers based on uio will not load unless physical
+ * addresses are obtainable. It is only possible to get
+ * physical addresses when running as a privileged user.
+ *
+ * @return
+ *   1 if the system is able to obtain physical addresses.
+ *   0 if using DMA addresses through an IOMMU.
+ */
+int rte_eal_using_phys_addrs(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
index 187d338..ddf88c5 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -1494,7 +1494,7 @@ rte_eal_hugepage_attach(void)
 	return -1;
 }
 
-bool
+int
 rte_eal_using_phys_addrs(void)
 {
 	return phys_addrs_available;
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 8eb53ab..bcc594d 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -244,6 +244,7 @@ DPDK_17.11 {
 	rte_bus_get_iommu_class;
 	rte_eal_iova_mode;
 	rte_eal_mbuf_default_mempool_ops;
+	rte_eal_using_phys_addrs;
 	rte_lcore_has_role;
 	rte_memcpy_ptr;
 	rte_pci_get_iommu_class;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 06/25] eal: expose internal config elements
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (4 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 05/25] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 07/25] eal: expose vfio symbols Gaetan Rivet
                             ` (19 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Some internal configuration elements set by the user on the command line
are necessary outside the EAL, when the PCI bus is detached.

Expose:
  + rte_eal_create_uio_dev
  + rte_eal_has_pci
  + rte_eal_vfio_intr_mode

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/bsdapp/eal/eal.c         | 16 ++++++++++++++++
 lib/librte_eal/common/include/rte_eal.h | 28 ++++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal.c       | 16 ++++++++++++++++
 lib/librte_eal/rte_eal_version.map      |  3 +++
 4 files changed, 63 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index e981721..d54a280 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -723,3 +723,19 @@ rte_eal_process_type(void)
 {
 	return rte_config.process_type;
 }
+
+int rte_eal_has_pci(void)
+{
+	return !internal_config.no_pci;
+}
+
+int rte_eal_create_uio_dev(void)
+{
+	return internal_config.create_uio_dev;
+}
+
+enum rte_intr_mode
+rte_eal_vfio_intr_mode(void)
+{
+	return RTE_INTR_MODE_NONE;
+}
diff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h
index 4ea2ff4..cc2636c 100644
--- a/lib/librte_eal/common/include/rte_eal.h
+++ b/lib/librte_eal/common/include/rte_eal.h
@@ -47,6 +47,8 @@
 #include <rte_config.h>
 #include <rte_bus.h>
 
+#include <rte_pci_dev_feature_defs.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -268,6 +270,32 @@ rte_set_application_usage_hook(rte_usage_hook_t usage_func);
 int rte_eal_has_hugepages(void);
 
 /**
+ * Whether EAL is using PCI bus.
+ * Disabled by --no-pci option.
+ *
+ * @return
+ *   Nonzero if the PCI bus is enabled.
+ */
+int rte_eal_has_pci(void);
+
+/**
+ * Whether the EAL was asked to create UIO device.
+ *
+ * @return
+ *   Nonzero if true.
+ */
+int rte_eal_create_uio_dev(void);
+
+/**
+ * The user-configured vfio interrupt mode.
+ *
+ * @return
+ *   Interrupt mode configured with the command line,
+ *   RTE_INTR_MODE_NONE by default.
+ */
+enum rte_intr_mode rte_eal_vfio_intr_mode(void);
+
+/**
  * A wrap API for syscall gettid.
  *
  * @return
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 02381d0..18a07b0 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -989,6 +989,22 @@ int rte_eal_has_hugepages(void)
 	return ! internal_config.no_hugetlbfs;
 }
 
+int rte_eal_has_pci(void)
+{
+	return !internal_config.no_pci;
+}
+
+int rte_eal_create_uio_dev(void)
+{
+	return internal_config.create_uio_dev;
+}
+
+enum rte_intr_mode
+rte_eal_vfio_intr_mode(void)
+{
+	return internal_config.vfio_intr_mode;
+}
+
 int
 rte_eal_check_module(const char *module_name)
 {
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index bcc594d..9f06d23 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -241,10 +241,13 @@ EXPERIMENTAL {
 DPDK_17.11 {
 	global:
 
+	rte_eal_create_uio_dev;
 	rte_bus_get_iommu_class;
+	rte_eal_has_pci;
 	rte_eal_iova_mode;
 	rte_eal_mbuf_default_mempool_ops;
 	rte_eal_using_phys_addrs;
+	rte_eal_vfio_intr_mode;
 	rte_lcore_has_role;
 	rte_memcpy_ptr;
 	rte_pci_get_iommu_class;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 07/25] eal: expose vfio symbols
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (5 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 06/25] eal: expose internal config elements Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 08/25] vfio: remove useless PCI headers and add vfio one Gaetan Rivet
                             ` (18 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

The following symbols are used by vfio implementations within the PCI bus.
They need to be publicly available for the PCI bus to be outside the
EAL.

  + vfio_enable;
  + vfio_is_enabled;
  + vfio_noiommu_is_enabled;
  + vfio_release_device;
  + vfio_setup_device;

PCI-related files (either source or private headers) do not rely on
private EAL vfio header and only need the public one henceforth.
This is preparing moving the PCI bus outside the EAL.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/bus/fslmc/fslmc_vfio.h                 |   2 +
 lib/librte_eal/bsdapp/eal/eal.c                |  41 ++++++++
 lib/librte_eal/common/Makefile                 |   2 +-
 lib/librte_eal/common/include/rte_vfio.h       | 130 +++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal.c              |   1 +
 lib/librte_eal/linuxapp/eal/eal_interrupts.c   |   1 +
 lib/librte_eal/linuxapp/eal/eal_pci.c          |   2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_init.h     |   4 +-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c     |   2 +-
 lib/librte_eal/linuxapp/eal/eal_vfio.c         |   1 +
 lib/librte_eal/linuxapp/eal/eal_vfio.h         |  17 ----
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c |   1 +
 lib/librte_eal/rte_eal_version.map             |   5 +
 13 files changed, 187 insertions(+), 22 deletions(-)
 create mode 100644 lib/librte_eal/common/include/rte_vfio.h

diff --git a/drivers/bus/fslmc/fslmc_vfio.h b/drivers/bus/fslmc/fslmc_vfio.h
index 5470a41..b442dc0 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -34,6 +34,8 @@
 #ifndef _FSLMC_VFIO_H_
 #define _FSLMC_VFIO_H_
 
+#include <rte_vfio.h>
+
 #include "eal_vfio.h"
 
 #define DPAA2_MC_DPNI_DEVID	7
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index d54a280..af15812 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -739,3 +739,44 @@ rte_eal_vfio_intr_mode(void)
 {
 	return RTE_INTR_MODE_NONE;
 }
+
+/* dummy forward declaration. */
+struct vfio_device_info;
+
+/* dummy prototypes. */
+int vfio_setup_device(const char *sysfs_base, const char *dev_addr,
+		int *vfio_dev_fd, struct vfio_device_info *device_info);
+int vfio_release_device(const char *sysfs_base, const char *dev_addr, int fd);
+int vfio_enable(const char *modname);
+int vfio_is_enabled(const char *modname);
+int vfio_noiommu_is_enabled(void);
+
+int vfio_setup_device(__rte_unused const char *sysfs_base,
+		      __rte_unused const char *dev_addr,
+		      __rte_unused int *vfio_dev_fd,
+		      __rte_unused struct vfio_device_info *device_info)
+{
+	return -1;
+}
+
+int vfio_release_device(__rte_unused const char *sysfs_base,
+			__rte_unused const char *dev_addr,
+			__rte_unused int fd)
+{
+	return -1;
+}
+
+int vfio_enable(__rte_unused const char *modname)
+{
+	return -1;
+}
+
+int vfio_is_enabled(__rte_unused const char *modname)
+{
+	return 0;
+}
+
+int vfio_noiommu_is_enabled(void)
+{
+	return 0;
+}
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 6f5b3f3..64ff811 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -43,7 +43,7 @@ INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
-INC += rte_bitmap.h
+INC += rte_bitmap.h rte_vfio.h
 
 GENERIC_INC := rte_atomic.h rte_byteorder.h rte_cycles.h rte_prefetch.h
 GENERIC_INC += rte_spinlock.h rte_memcpy.h rte_cpuflags.h rte_rwlock.h
diff --git a/lib/librte_eal/common/include/rte_vfio.h b/lib/librte_eal/common/include/rte_vfio.h
new file mode 100644
index 0000000..731c3a3
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_vfio.h
@@ -0,0 +1,130 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_VFIO_H_
+#define _RTE_VFIO_H_
+
+#include <linux/vfio.h>
+
+/**
+ * Setup vfio_cfg for the device identified by its address.
+ * It discovers the configured I/O MMU groups or sets a new one for the device.
+ * If a new groups is assigned, the DMA mapping is performed.
+ *
+ * This function is only relevant to linux and will return
+ * an error on BSD.
+ *
+ * @param sysfs_base
+ *   sysfs path prefix.
+ *
+ * @param dev_addr
+ *   device location.
+ *
+ * @param vfio_dev_fd
+ *   VFIO fd.
+ *
+ * @param device_info
+ *   Device information.
+ *
+ * @return
+ *   0 on success.
+ *   <0 on failure.
+ *   >1 if the device cannot be managed this way.
+ */
+int vfio_setup_device(const char *sysfs_base, const char *dev_addr,
+		int *vfio_dev_fd, struct vfio_device_info *device_info);
+
+/**
+ * Release a device mapped to a VFIO-managed I/O MMU group.
+ *
+ * This function is only relevant to linux and will return
+ * an error on BSD.
+ *
+ * @param sysfs_base
+ *   sysfs path prefix.
+ *
+ * @param dev_addr
+ *   device location.
+ *
+ * @param fd
+ *   VFIO fd.
+ *
+ * @return
+ *   0 on success.
+ *   <0 on failure.
+ */
+int vfio_release_device(const char *sysfs_base, const char *dev_addr, int fd);
+
+/**
+ * Enable a VFIO-related kmod.
+ *
+ * This function is only relevant to linux and will return
+ * an error on BSD.
+ *
+ * @param modname
+ *   kernel module name.
+ *
+ * @return
+ *   0 on success.
+ *   <0 on failure.
+ */
+int vfio_enable(const char *modname);
+
+/**
+ * Check whether a VFIO-related kmod is enabled.
+ *
+ * This function is only relevant to linux and will return
+ * an error on BSD.
+ *
+ * @param modname
+ *   kernel module name.
+ *
+ * @return
+ *   !0 if true.
+ *   0 otherwise.
+ */
+int vfio_is_enabled(const char *modname);
+
+/**
+ * Whether VFIO NOIOMMU mode is enabled.
+ *
+ * This function is only relevant to linux and will return
+ * an error on BSD.
+ *
+ * @return
+ *   !0 if true.
+ *   0 otherwise.
+ */
+int vfio_noiommu_is_enabled(void);
+
+#endif /* _RTE_VFIO_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 18a07b0..bee3bbe 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -77,6 +77,7 @@
 #include <rte_version.h>
 #include <rte_atomic.h>
 #include <malloc_heap.h>
+#include <rte_vfio.h>
 
 #include "eal_private.h"
 #include "eal_thread.h"
diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
index 3e9ac41..6df63d4 100644
--- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
@@ -65,6 +65,7 @@
 #include <rte_errno.h>
 #include <rte_spinlock.h>
 #include <rte_pause.h>
+#include <rte_vfio.h>
 
 #include "eal_private.h"
 #include "eal_vfio.h"
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index b4dbf95..8682ee6 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -41,11 +41,11 @@
 #include <rte_malloc.h>
 #include <rte_devargs.h>
 #include <rte_memcpy.h>
+#include <rte_vfio.h>
 
 #include "eal_filesystem.h"
 #include "eal_private.h"
 #include "eal_pci_init.h"
-#include "eal_vfio.h"
 
 /**
  * @file
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
index ae2980d..a20783d 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_init.h
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
@@ -34,7 +34,7 @@
 #ifndef EAL_PCI_INIT_H_
 #define EAL_PCI_INIT_H_
 
-#include "eal_vfio.h"
+#include <rte_vfio.h>
 
 /** IO resource type: */
 #define IORESOURCE_IO         0x00000100
@@ -72,7 +72,7 @@ void pci_uio_ioport_write(struct rte_pci_ioport *p,
 			  const void *data, size_t len, off_t offset);
 int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
 
-#ifdef VFIO_PRESENT
+#ifdef RTE_EAL_VFIO
 
 /* access config space */
 int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
index d407c87..d498df6 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
@@ -44,10 +44,10 @@
 #include <rte_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
+#include <rte_vfio.h>
 
 #include "eal_filesystem.h"
 #include "eal_pci_init.h"
-#include "eal_vfio.h"
 #include "eal_private.h"
 
 /**
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.c b/lib/librte_eal/linuxapp/eal/eal_vfio.c
index 3f56967..5bbcdf9 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.c
@@ -39,6 +39,7 @@
 #include <rte_log.h>
 #include <rte_memory.h>
 #include <rte_eal_memconfig.h>
+#include <rte_vfio.h>
 
 #include "eal_filesystem.h"
 #include "eal_vfio.h"
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.h b/lib/librte_eal/linuxapp/eal/eal_vfio.h
index 4bab363..3fd433c 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio.h
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.h
@@ -192,27 +192,10 @@ vfio_get_group_fd(int iommu_group_no);
 int
 clear_group(int vfio_group_fd);
 
-/**
- * Setup vfio_cfg for the device identified by its address. It discovers
- * the configured I/O MMU groups or sets a new one for the device. If a new
- * groups is assigned, the DMA mapping is performed.
- * Returns 0 on success, a negative value on failure and a positive value in
- * case the given device cannot be managed this way.
- */
-int vfio_setup_device(const char *sysfs_base, const char *dev_addr,
-		int *vfio_dev_fd, struct vfio_device_info *device_info);
-
-int vfio_release_device(const char *sysfs_base, const char *dev_addr, int fd);
-
-int vfio_enable(const char *modname);
-int vfio_is_enabled(const char *modname);
-
 int pci_vfio_is_enabled(void);
 
 int vfio_mp_sync_setup(void);
 
-int vfio_noiommu_is_enabled(void);
-
 #define SOCKET_REQ_CONTAINER 0x100
 #define SOCKET_REQ_GROUP 0x200
 #define SOCKET_CLR_GROUP 0x300
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
index 537beeb..598df12 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
@@ -52,6 +52,7 @@
 #include <rte_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
+#include <rte_vfio.h>
 
 #include "eal_filesystem.h"
 #include "eal_pci_init.h"
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 9f06d23..262211a 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -252,5 +252,10 @@ DPDK_17.11 {
 	rte_memcpy_ptr;
 	rte_pci_get_iommu_class;
 	rte_pci_match;
+	vfio_enable;
+	vfio_is_enabled;
+	vfio_noiommu_is_enabled;
+	vfio_release_device;
+	vfio_setup_device;
 
 } DPDK_17.08;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 08/25] vfio: remove useless PCI headers and add vfio one
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (6 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 07/25] eal: expose vfio symbols Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 09/25] vfio: check PCI dependency from within PCI code Gaetan Rivet
                             ` (17 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

PCI headers are not necessary and are making this module dependent on
the PCI subsystem.

The internal eal_vfio.h header was necessary however for shared build.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
index 598df12..a793e9a 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
@@ -49,14 +49,13 @@
 #endif
 
 #include <rte_log.h>
-#include <rte_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 #include <rte_vfio.h>
 
 #include "eal_filesystem.h"
-#include "eal_pci_init.h"
 #include "eal_thread.h"
+#include "eal_vfio.h"
 
 /**
  * @file
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 09/25] vfio: check PCI dependency from within PCI code
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (7 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 08/25] vfio: remove useless PCI headers and add vfio one Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 10/25] vfio: move PCI-related functions out of vfio header Gaetan Rivet
                             ` (16 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

PCI sometimes requires vfio to be enabled.
Move the check from EAL init to PCI bus scan.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/linuxapp/eal/eal.c     | 5 -----
 lib/librte_eal/linuxapp/eal/eal_pci.c | 5 +++++
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index bee3bbe..91c3712 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -715,11 +715,6 @@ static int rte_eal_vfio_setup(void)
 		return -1;
 	vfio_enabled = vfio_is_enabled("vfio");
 
-	if (!internal_config.no_pci) {
-		if (!pci_vfio_is_enabled())
-			RTE_LOG(DEBUG, EAL, "VFIO PCI modules not loaded\n");
-	}
-
 	if (vfio_enabled) {
 
 		/* if we are primary process, create a thread to communicate with
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 8682ee6..dc65852 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -460,6 +460,11 @@ rte_pci_scan(void)
 	if (internal_config.no_pci)
 		return 0;
 
+#ifdef VFIO_PRESENT
+	if (!pci_vfio_is_enabled())
+		RTE_LOG(DEBUG, EAL, "VFIO PCI modules not loaded\n");
+#endif
+
 	dir = opendir(pci_get_sysfs_path());
 	if (dir == NULL) {
 		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 10/25] vfio: move PCI-related functions out of vfio header
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (8 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 09/25] vfio: check PCI dependency from within PCI code Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 11/25] pci: avoid inlining functions Gaetan Rivet
                             ` (15 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

These two declarations are only relevant to PCI operations and
should be in a related header.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/linuxapp/eal/eal_pci_init.h | 2 ++
 lib/librte_eal/linuxapp/eal/eal_vfio.h     | 2 --
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
index a20783d..c94ba19 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_init.h
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
@@ -92,6 +92,8 @@ int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
 int pci_vfio_map_resource(struct rte_pci_device *dev);
 int pci_vfio_unmap_resource(struct rte_pci_device *dev);
 
+int pci_vfio_is_enabled(void);
+
 #endif
 
 #endif /* EAL_PCI_INIT_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.h b/lib/librte_eal/linuxapp/eal/eal_vfio.h
index 3fd433c..0c7b062 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio.h
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.h
@@ -192,8 +192,6 @@ vfio_get_group_fd(int iommu_group_no);
 int
 clear_group(int vfio_group_fd);
 
-int pci_vfio_is_enabled(void);
-
 int vfio_mp_sync_setup(void);
 
 #define SOCKET_REQ_CONTAINER 0x100
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 11/25] pci: avoid inlining functions
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (9 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 10/25] vfio: move PCI-related functions out of vfio header Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 12/25] pci: avoid over-complicated macro Gaetan Rivet
                             ` (14 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Parsing operations should not happen in performance critical sections.
Headers should not propose implementations unless duly required.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_pci.c  | 68 ++++++++++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_pci.h | 69 +++------------------------------
 lib/librte_eal/rte_eal_version.map      |  4 ++
 3 files changed, 78 insertions(+), 63 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 0f0e4b9..b4e35d0 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -87,6 +87,74 @@ static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
 	return NULL;
 }
 
+/* Macro used by pci addr parsing functions. **/
+#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                     \
+do {                                                            \
+	unsigned long val;                                      \
+	char *end;                                              \
+	errno = 0;                                              \
+	val = strtoul((in), &end, 16);                          \
+	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
+		return -EINVAL;                                 \
+	(fd) = (typeof (fd))val;                                \
+	(in) = end + 1;                                         \
+} while(0)
+
+
+int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	dev_addr->domain = 0;
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+#undef GET_PCIADDR_FIELD
+
+void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+		     char *output, size_t size)
+{
+	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+			    addr->domain, addr->bus,
+			    addr->devid, addr->function) >= 0);
+}
+
+int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			   const struct rte_pci_addr *addr2)
+{
+	uint64_t dev_addr, dev_addr2;
+
+	if ((addr == NULL) || (addr2 == NULL))
+		 return -1;
+
+	dev_addr = ((uint64_t)addr->domain << 24) |
+		 (addr->bus << 16) | (addr->devid << 8) | addr->function;
+	dev_addr2 = ((uint64_t)addr2->domain << 24) |
+		 (addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+	if (dev_addr > dev_addr2)
+		 return 1;
+	else if (dev_addr < dev_addr2)
+		 return -1;
+	else
+		 return 0;
+}
+
 void
 pci_name_set(struct rte_pci_device *dev)
 {
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 1c5f469..a366f3f 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -240,19 +240,6 @@ struct mapped_pci_resource {
 /** mapped pci device list */
 TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 
-/**< Internal use only - Macro used by pci addr parsing functions **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
-do {                                                               \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
-
 /**
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided without
@@ -266,15 +253,7 @@ do {                                                               \
  * @return
  *  0 on success, negative on error.
  */
-static inline int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
+int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to produce a PCI Bus-Device-Function value
@@ -288,16 +267,7 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
  * @return
  *  0 on success, negative on error.
  */
-static inline int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-#undef GET_PCIADDR_FIELD
+int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to write a pci device name, this device name can later be
@@ -311,17 +281,9 @@ eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
  * @param size
  *	The output buffer size
  */
-static inline void
-rte_pci_device_name(const struct rte_pci_addr *addr,
-		char *output, size_t size)
-{
-	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
-	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
-			    addr->domain, addr->bus,
-			    addr->devid, addr->function) >= 0);
-}
+void rte_pci_device_name(const struct rte_pci_addr *addr, char *output,
+			 size_t size);
 
-/* Compare two PCI device addresses. */
 /**
  * Utility function to compare two PCI device addresses.
  *
@@ -334,27 +296,8 @@ rte_pci_device_name(const struct rte_pci_addr *addr,
  *	Positive on addr is greater than addr2.
  *	Negative on addr is less than addr2, or error.
  */
-static inline int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			 const struct rte_pci_addr *addr2)
-{
-	uint64_t dev_addr, dev_addr2;
-
-	if ((addr == NULL) || (addr2 == NULL))
-		return -1;
-
-	dev_addr = ((uint64_t)addr->domain << 24) |
-		(addr->bus << 16) | (addr->devid << 8) | addr->function;
-	dev_addr2 = ((uint64_t)addr2->domain << 24) |
-		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
-
-	if (dev_addr > dev_addr2)
-		return 1;
-	else if (dev_addr < dev_addr2)
-		return -1;
-	else
-		return 0;
-}
+int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			     const struct rte_pci_addr *addr2);
 
 /**
  * Scan the content of the PCI bus, and the devices in the devices
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 262211a..f22869a 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -241,8 +241,11 @@ EXPERIMENTAL {
 DPDK_17.11 {
 	global:
 
+	eal_parse_pci_BDF;
+	eal_parse_pci_DomBDF;
 	rte_eal_create_uio_dev;
 	rte_bus_get_iommu_class;
+	rte_eal_compare_pci_addr;
 	rte_eal_has_pci;
 	rte_eal_iova_mode;
 	rte_eal_mbuf_default_mempool_ops;
@@ -250,6 +253,7 @@ DPDK_17.11 {
 	rte_eal_vfio_intr_mode;
 	rte_lcore_has_role;
 	rte_memcpy_ptr;
+	rte_pci_device_name;
 	rte_pci_get_iommu_class;
 	rte_pci_match;
 	vfio_enable;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 12/25] pci: avoid over-complicated macro
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (10 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 11/25] pci: avoid inlining functions Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 13/25] pci: deprecate misnamed functions Gaetan Rivet
                             ` (13 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Using a macro helps writing the code to the detriment of the reader
in this case. This is backward. Write once, read many.

The few LOCs gained is not worth the opacity of the implementation.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_pci.c | 67 +++++++++++++++++++++++-----------
 1 file changed, 46 insertions(+), 21 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index b4e35d0..20ae349 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -87,42 +87,67 @@ static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
 	return NULL;
 }
 
-/* Macro used by pci addr parsing functions. **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                     \
-do {                                                            \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
+static inline const char *
+get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
+{
+	unsigned long val;
+	uint8_t *u8 = _u8;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != dlm || val > UINT8_MAX) {
+		errno = errno ? errno : EINVAL;
+		return NULL;
+	}
+	*u8 = (uint8_t)val;
+	return end + 1;
+}
 
 
 int
 eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	const char *in = input;
+
 	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
 	return 0;
 }
 
 int
 eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
 {
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	const char *in = input;
+	unsigned long val;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != ':' || val > UINT16_MAX)
+		return -EINVAL;
+	dev_addr->domain = (uint16_t)val;
+	in = end + 1;
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
 	return 0;
 }
 
-#undef GET_PCIADDR_FIELD
-
 void
 rte_pci_device_name(const struct rte_pci_addr *addr,
 		     char *output, size_t size)
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 13/25] pci: deprecate misnamed functions
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (11 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 12/25] pci: avoid over-complicated macro Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 14/25] pci: introduce PCI address parsing function Gaetan Rivet
                             ` (12 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Rename misnamed functions and describe the change in a deprecation
notice.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst    |  9 +++++++
 lib/librte_eal/common/eal_common_pci.c  | 27 ++++++++++++++++---
 lib/librte_eal/common/include/rte_pci.h | 47 +++++++++++++++++++++++++++++++++
 lib/librte_eal/rte_eal_version.map      |  3 +++
 4 files changed, 82 insertions(+), 4 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 023cb60..f3d7203 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -84,3 +84,12 @@ Deprecation Notices
 
 * librte_meter: The API will change to accommodate configuration profiles.
   Most of the API functions will have an additional opaque parameter.
+
+* pci: Several exposed functions are misnamed.
+  The following functions are deprecated starting from v17.11 and are replaced:
+
+  - ``eal_parse_pci_BDF`` replaced by ``rte_pci_bdf_parse``
+  - ``eal_parse_pci_DomBDF`` replaced by ``rte_pci_dbdf_parse``
+  - ``rte_eal_compare_pci_addr`` replaced by ``rte_pci_addr_cmp``
+
+  The functions are only renamed. Their behavior is not affected.
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 20ae349..a3c32fb 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -106,7 +106,7 @@ get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
 
 
 int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+rte_pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 {
 	const char *in = input;
 
@@ -124,7 +124,13 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 }
 
 int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	return rte_pci_bdf_parse(input, dev_addr);
+}
+
+int
+rte_pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 {
 	const char *in = input;
 	unsigned long val;
@@ -148,6 +154,12 @@ eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
 	return 0;
 }
 
+int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	return rte_pci_dbdf_parse(input, dev_addr);
+}
+
 void
 rte_pci_device_name(const struct rte_pci_addr *addr,
 		     char *output, size_t size)
@@ -159,8 +171,8 @@ rte_pci_device_name(const struct rte_pci_addr *addr,
 }
 
 int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			   const struct rte_pci_addr *addr2)
+rte_pci_addr_cmp(const struct rte_pci_addr *addr,
+		 const struct rte_pci_addr *addr2)
 {
 	uint64_t dev_addr, dev_addr2;
 
@@ -180,6 +192,13 @@ rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 		 return 0;
 }
 
+int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			   const struct rte_pci_addr *addr2)
+{
+	return rte_pci_addr_cmp(addr, addr2);
+}
+
 void
 pci_name_set(struct rte_pci_device *dev)
 {
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index a366f3f..9ac19d5 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -253,6 +253,22 @@ TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
  * @return
  *  0 on success, negative on error.
  */
+int rte_pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided without
+ * a domain prefix (i.e. domain returned is always 0)
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned. Domain will always be
+ *	returned as 0
+ * @return
+ *  0 on success, negative on error.
+ */
 int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
@@ -267,6 +283,21 @@ int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
  * @return
  *  0 on success, negative on error.
  */
+int rte_pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided including
+ * a domain prefix.
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XXXX:XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned
+ * @return
+ *  0 on success, negative on error.
+ */
 int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
@@ -296,6 +327,22 @@ void rte_pci_device_name(const struct rte_pci_addr *addr, char *output,
  *	Positive on addr is greater than addr2.
  *	Negative on addr is less than addr2, or error.
  */
+int rte_pci_addr_cmp(const struct rte_pci_addr *addr,
+		     const struct rte_pci_addr *addr2);
+
+/**
+ * @deprecated
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
 int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 			     const struct rte_pci_addr *addr2);
 
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index f22869a..5cad972 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -253,6 +253,9 @@ DPDK_17.11 {
 	rte_eal_vfio_intr_mode;
 	rte_lcore_has_role;
 	rte_memcpy_ptr;
+	rte_pci_addr_cmp;
+	rte_pci_bdf_parse;
+	rte_pci_dbdf_parse;
 	rte_pci_device_name;
 	rte_pci_get_iommu_class;
 	rte_pci_match;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 14/25] pci: introduce PCI address parsing function
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (12 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 13/25] pci: deprecate misnamed functions Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 15/25] pci: make specialized parsing functions private Gaetan Rivet
                             ` (11 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

A new single function that is able to parse all currently supported
format:

   * Domain-Bus-Device-Function
   *        Bus-Device-Function

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_pci.c  |  9 +++++++++
 lib/librte_eal/common/include/rte_pci.h | 14 ++++++++++++++
 lib/librte_eal/rte_eal_version.map      |  1 +
 3 files changed, 24 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index a3c32fb..fdcf005 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -199,6 +199,15 @@ rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 	return rte_pci_addr_cmp(addr, addr2);
 }
 
+int
+rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr)
+{
+	if (rte_pci_bdf_parse(str, addr) == 0 ||
+	    rte_pci_dbdf_parse(str, addr) == 0)
+		return 0;
+	return -1;
+}
+
 void
 pci_name_set(struct rte_pci_device *dev)
 {
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 9ac19d5..11ba442 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -347,6 +347,20 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 			     const struct rte_pci_addr *addr2);
 
 /**
+ * Utility function to parse a string into a PCI location.
+ *
+ * @param str
+ *     The string to parse
+ * @param addr
+ *     The reference to the structure where the location
+ *     is stored.
+ * @return
+ *     0 on success
+ *     <0 otherwise
+ */
+int rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr);
+
+/**
  * Scan the content of the PCI bus, and the devices in the devices
  * list
  *
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 5cad972..3568694 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -254,6 +254,7 @@ DPDK_17.11 {
 	rte_lcore_has_role;
 	rte_memcpy_ptr;
 	rte_pci_addr_cmp;
+	rte_pci_addr_parse;
 	rte_pci_bdf_parse;
 	rte_pci_dbdf_parse;
 	rte_pci_device_name;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 15/25] pci: make specialized parsing functions private
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (13 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 14/25] pci: introduce PCI address parsing function Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 16/25] pci: use new PCI addr comparison function Gaetan Rivet
                             ` (10 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Do not expose the minute implementations of PCI parsing.
This leaves only the all-purpose rte_pci_addr_parse, which is simpler to
use.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst    |  6 ++----
 lib/librte_eal/common/eal_common_pci.c  |  4 ++--
 lib/librte_eal/common/include/rte_pci.h | 29 -----------------------------
 lib/librte_eal/rte_eal_version.map      |  2 --
 4 files changed, 4 insertions(+), 37 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index f3d7203..4e7f1f5 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -88,8 +88,6 @@ Deprecation Notices
 * pci: Several exposed functions are misnamed.
   The following functions are deprecated starting from v17.11 and are replaced:
 
-  - ``eal_parse_pci_BDF`` replaced by ``rte_pci_bdf_parse``
-  - ``eal_parse_pci_DomBDF`` replaced by ``rte_pci_dbdf_parse``
+  - ``eal_parse_pci_BDF`` replaced by ``rte_pci_addr_parse``
+  - ``eal_parse_pci_DomBDF`` replaced by ``rte_pci_addr_parse``
   - ``rte_eal_compare_pci_addr`` replaced by ``rte_pci_addr_cmp``
-
-  The functions are only renamed. Their behavior is not affected.
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index fdcf005..531dc12 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -105,7 +105,7 @@ get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
 }
 
 
-int
+static int
 rte_pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 {
 	const char *in = input;
@@ -129,7 +129,7 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 	return rte_pci_bdf_parse(input, dev_addr);
 }
 
-int
+static int
 rte_pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 {
 	const char *in = input;
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 11ba442..11ade4d 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -241,21 +241,6 @@ struct mapped_pci_resource {
 TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 
 /**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided without
- * a domain prefix (i.e. domain returned is always 0)
- *
- * @param input
- *	The input string to be parsed. Should have the format XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned. Domain will always be
- *	returned as 0
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr);
-
-/**
  * @deprecated
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided without
@@ -272,20 +257,6 @@ int rte_pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr);
 int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided including
- * a domain prefix.
- *
- * @param input
- *	The input string to be parsed. Should have the format XXXX:XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr);
-
-/**
  * @deprecated
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided including
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 3568694..180eee8 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -255,8 +255,6 @@ DPDK_17.11 {
 	rte_memcpy_ptr;
 	rte_pci_addr_cmp;
 	rte_pci_addr_parse;
-	rte_pci_bdf_parse;
-	rte_pci_dbdf_parse;
 	rte_pci_device_name;
 	rte_pci_get_iommu_class;
 	rte_pci_match;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 16/25] pci: use new PCI addr comparison function
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (14 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 15/25] pci: make specialized parsing functions private Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 17/25] pci: use new PCI addr parsing function Gaetan Rivet
                             ` (9 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/bsdapp/eal/eal_pci.c        | 2 +-
 lib/librte_eal/common/eal_common_pci.c     | 8 ++++----
 lib/librte_eal/common/eal_common_pci_uio.c | 4 ++--
 lib/librte_eal/linuxapp/eal/eal_pci.c      | 2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c | 4 ++--
 5 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 1595988..7d82195 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -323,7 +323,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
 		int ret;
 
 		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+			ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr);
 			if (ret > 0)
 				continue;
 			else if (ret < 0) {
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 531dc12..bf8a96c 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -81,7 +81,7 @@ static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
 		if (devargs->bus != pbus)
 			continue;
 		devargs->bus->parse(devargs->name, &addr);
-		if (!rte_eal_compare_pci_addr(&dev->addr, &addr))
+		if (!rte_pci_addr_cmp(&dev->addr, &addr))
 			return devargs;
 	}
 	return NULL;
@@ -194,7 +194,7 @@ rte_pci_addr_cmp(const struct rte_pci_addr *addr,
 
 int
 rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			   const struct rte_pci_addr *addr2)
+			 const struct rte_pci_addr *addr2)
 {
 	return rte_pci_addr_cmp(addr, addr2);
 }
@@ -463,7 +463,7 @@ rte_pci_probe_one(const struct rte_pci_addr *addr)
 		goto err_return;
 
 	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_eal_compare_pci_addr(&dev->addr, addr))
+		if (rte_pci_addr_cmp(&dev->addr, addr))
 			continue;
 
 		ret = pci_probe_all_drivers(dev);
@@ -493,7 +493,7 @@ rte_pci_detach(const struct rte_pci_addr *addr)
 		return -1;
 
 	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_eal_compare_pci_addr(&dev->addr, addr))
+		if (rte_pci_addr_cmp(&dev->addr, addr))
 			continue;
 
 		ret = rte_pci_detach_dev(dev);
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
index 367a681..9df3833 100644
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ b/lib/librte_eal/common/eal_common_pci_uio.c
@@ -61,7 +61,7 @@ pci_uio_map_secondary(struct rte_pci_device *dev)
 	TAILQ_FOREACH(uio_res, uio_res_list, next) {
 
 		/* skip this element if it doesn't match our PCI address */
-		if (rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+		if (rte_pci_addr_cmp(&uio_res->pci_addr, &dev->addr))
 			continue;
 
 		for (i = 0; i != uio_res->nb_maps; i++) {
@@ -187,7 +187,7 @@ pci_uio_find_resource(struct rte_pci_device *dev)
 	TAILQ_FOREACH(uio_res, uio_res_list, next) {
 
 		/* skip this element if it doesn't match our PCI address */
-		if (!rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+		if (!rte_pci_addr_cmp(&uio_res->pci_addr, &dev->addr))
 			return uio_res;
 	}
 	return NULL;
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index dc65852..3a853a6 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -363,7 +363,7 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
 		int ret;
 
 		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+			ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr);
 			if (ret > 0)
 				continue;
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
index d498df6..85e481d 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
@@ -576,8 +576,8 @@ pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
 
 	/* if we're in a secondary process, just find our tailq entry */
 	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-		if (rte_eal_compare_pci_addr(&vfio_res->pci_addr,
-						 &dev->addr))
+		if (rte_pci_addr_cmp(&vfio_res->pci_addr,
+				     &dev->addr))
 			continue;
 		break;
 	}
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 17/25] pci: use new PCI addr parsing function
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (15 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 16/25] pci: use new PCI addr comparison function Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 18/25] pci: do not expose private functions Gaetan Rivet
                             ` (8 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_pci.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index bf8a96c..0a51dd8 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -595,8 +595,7 @@ pci_parse(const char *name, void *addr)
 	struct rte_pci_addr pci_addr;
 	bool parse;
 
-	parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
-		 eal_parse_pci_DomBDF(name, &pci_addr) == 0);
+	parse = (rte_pci_addr_parse(name, &pci_addr) == 0);
 	if (parse && addr != NULL)
 		*out = pci_addr;
 	return parse == false;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 18/25] pci: do not expose private functions
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (16 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 17/25] pci: use new PCI addr parsing function Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 19/25] pci: do not expose PCI match function Gaetan Rivet
                             ` (7 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

make the functions

   + rte_pci_detach
   + rte_pci_probe
   + rte_pci_probe_one
   + rte_pci_scan

private as there is no point in using them outside of the rte_bus
framework.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_private.h     | 49 +++++++++++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_pci.h | 49 ---------------------------------
 lib/librte_eal/rte_eal_version.map      |  4 ---
 3 files changed, 49 insertions(+), 53 deletions(-)

diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 80fea24..8f949fb 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -114,6 +114,55 @@ struct rte_pci_driver;
 struct rte_pci_device;
 
 /**
+ * Probe the PCI bus
+ *
+ * @return
+ *   - 0 on success.
+ *   - !0 on error.
+ */
+int
+rte_pci_probe(void);
+
+/**
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ *
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_pci_scan(void);
+
+/**
+ * Probe the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the probe() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *     The PCI Bus-Device-Function address to probe.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_probe_one(const struct rte_pci_addr *addr);
+
+/**
+ * Close the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the remove() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *     The PCI Bus-Device-Function address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_detach(const struct rte_pci_addr *addr);
+
+/**
  * Find the name of a PCI device.
  */
 void pci_name_set(struct rte_pci_device *dev);
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 11ade4d..ca753b5 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -331,25 +331,6 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
  */
 int rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr);
 
-/**
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- *
- * @return
- *  0 on success, negative on error
- */
-int rte_pci_scan(void);
-
-/**
- * Probe the PCI bus
- *
- * @return
- *   - 0 on success.
- *   - !0 on error.
- */
-int
-rte_pci_probe(void);
-
 /*
  * Match the PCI Driver and Device using the ID Table
  *
@@ -435,36 +416,6 @@ void *pci_map_resource(void *requested_addr, int fd, off_t offset,
 void pci_unmap_resource(void *requested_addr, size_t size);
 
 /**
- * Probe the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the probe() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to probe.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_probe_one(const struct rte_pci_addr *addr);
-
-/**
- * Close the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the remove() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to close.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_detach(const struct rte_pci_addr *addr);
-
-/**
  * Dump the content of the PCI bus.
  *
  * @param f
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 180eee8..754c6c3 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -166,18 +166,14 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_pci_detach;
 	rte_pci_dump;
 	rte_pci_ioport_map;
 	rte_pci_ioport_read;
 	rte_pci_ioport_unmap;
 	rte_pci_ioport_write;
 	rte_pci_map_device;
-	rte_pci_probe;
-	rte_pci_probe_one;
 	rte_pci_read_config;
 	rte_pci_register;
-	rte_pci_scan;
 	rte_pci_unmap_device;
 	rte_pci_unregister;
 	rte_pci_write_config;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 19/25] pci: do not expose PCI match function
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (17 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 18/25] pci: do not expose private functions Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 20/25] pci: do not expose IOVA mode getter Gaetan Rivet
                             ` (6 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

This function is private to the PCI bus.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_private.h     | 15 +++++++++++++++
 lib/librte_eal/common/include/rte_pci.h | 16 ----------------
 lib/librte_eal/rte_eal_version.map      |  1 -
 3 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 8f949fb..ea1a5be 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -290,6 +290,21 @@ void pci_uio_free_resource(struct rte_pci_device *dev,
 int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
 		struct mapped_pci_resource *uio_res, int map_idx);
 
+/*
+ * Match the PCI Driver and Device using the ID Table
+ *
+ * @param pci_drv
+ *      PCI driver from which ID table would be extracted
+ * @param pci_dev
+ *      PCI device to match against the driver
+ * @return
+ *      1 for successful match
+ *      0 for unsuccessful match
+ */
+int
+rte_pci_match(const struct rte_pci_driver *pci_drv,
+	      const struct rte_pci_device *pci_dev);
+
 /**
  * Init tail queues for non-EAL library structures. This is to allow
  * the rings, mempools, etc. lists to be shared among multiple processes
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index ca753b5..de213cc 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -331,22 +331,6 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
  */
 int rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr);
 
-/*
- * Match the PCI Driver and Device using the ID Table
- *
- * @param pci_drv
- *      PCI driver from which ID table would be extracted
- * @param pci_dev
- *      PCI device to match against the driver
- * @return
- *      1 for successful match
- *      0 for unsuccessful match
- */
-int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev);
-
-
 /**
  * Get iommu class of PCI devices on the bus.
  * And return their preferred iova mapping mode.
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 754c6c3..f2b4147 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -253,7 +253,6 @@ DPDK_17.11 {
 	rte_pci_addr_parse;
 	rte_pci_device_name;
 	rte_pci_get_iommu_class;
-	rte_pci_match;
 	vfio_enable;
 	vfio_is_enabled;
 	vfio_noiommu_is_enabled;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 20/25] pci: do not expose IOVA mode getter
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (18 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 19/25] pci: do not expose PCI match function Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 21/25] pci: use EAL exposed configuration Gaetan Rivet
                             ` (5 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_private.h     | 10 ++++++++++
 lib/librte_eal/common/include/rte_pci.h | 10 ----------
 lib/librte_eal/rte_eal_version.map      |  1 -
 3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index ea1a5be..4eb1bd2 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -306,6 +306,16 @@ rte_pci_match(const struct rte_pci_driver *pci_drv,
 	      const struct rte_pci_device *pci_dev);
 
 /**
+ * Get iommu class of PCI devices on the bus.
+ * And return their preferred iova mapping mode.
+ *
+ * @return
+ *   - enum rte_iova_mode.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void);
+
+/**
  * Init tail queues for non-EAL library structures. This is to allow
  * the rings, mempools, etc. lists to be shared among multiple processes
  *
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index de213cc..3c8cbd8 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -332,16 +332,6 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 int rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr);
 
 /**
- * Get iommu class of PCI devices on the bus.
- * And return their preferred iova mapping mode.
- *
- * @return
- *   - enum rte_iova_mode.
- */
-enum rte_iova_mode
-rte_pci_get_iommu_class(void);
-
-/**
  * Map the PCI device resources in user space virtual memory address
  *
  * Note that driver should not call this function when flag
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index f2b4147..8d67b67 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -252,7 +252,6 @@ DPDK_17.11 {
 	rte_pci_addr_cmp;
 	rte_pci_addr_parse;
 	rte_pci_device_name;
-	rte_pci_get_iommu_class;
 	vfio_enable;
 	vfio_is_enabled;
 	vfio_noiommu_is_enabled;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 21/25] pci: use EAL exposed configuration
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (19 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 20/25] pci: do not expose IOVA mode getter Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 22/25] net/bonding: use local prefix for local function Gaetan Rivet
                             ` (4 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/bsdapp/eal/eal_pci.c        |  2 +-
 lib/librte_eal/linuxapp/eal/eal_pci.c      |  2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c  |  2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c | 18 +++++++++++-------
 4 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 7d82195..e73b7cd 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -368,7 +368,7 @@ rte_pci_scan(void)
 	};
 
 	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
+	if (!rte_eal_has_pci())
 		return 0;
 
 	fd = open("/dev/pci", O_RDONLY);
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 3a853a6..cee4b94 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -457,7 +457,7 @@ rte_pci_scan(void)
 	struct rte_pci_addr addr;
 
 	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
+	if (!rte_eal_has_pci())
 		return 0;
 
 #ifdef VFIO_PRESENT
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
index b639ab9..d17837a 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
@@ -214,7 +214,7 @@ pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
 		return -1;
 
 	/* create uio device if we've been asked to */
-	if (internal_config.create_uio_dev && create &&
+	if (rte_eal_create_uio_dev() && create &&
 			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
 		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
index 85e481d..4e2b6c9 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
@@ -209,14 +209,18 @@ static int
 pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
 {
 	int i, ret, intr_idx;
+	enum rte_intr_mode intr_mode;
 
 	/* default to invalid index */
 	intr_idx = VFIO_PCI_NUM_IRQS;
 
+	/* Get default / configured intr_mode */
+	intr_mode = rte_eal_vfio_intr_mode();
+
 	/* get interrupt type from internal config (MSI-X by default, can be
 	 * overridden from the command line
 	 */
-	switch (internal_config.vfio_intr_mode) {
+	switch (intr_mode) {
 	case RTE_INTR_MODE_MSIX:
 		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
 		break;
@@ -240,7 +244,7 @@ pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
 		int fd = -1;
 
 		/* skip interrupt modes we don't want */
-		if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE &&
+		if (intr_mode != RTE_INTR_MODE_NONE &&
 				i != intr_idx)
 			continue;
 
@@ -256,7 +260,7 @@ pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
 		/* if this vector cannot be used with eventfd, fail if we explicitly
 		 * specified interrupt type, otherwise continue */
 		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
-			if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE) {
+			if (intr_mode != RTE_INTR_MODE_NONE) {
 				RTE_LOG(ERR, EAL,
 						"  interrupt vector does not support eventfd!\n");
 				return -1;
@@ -277,15 +281,15 @@ pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
 
 		switch (i) {
 		case VFIO_PCI_MSIX_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSIX;
+			intr_mode = RTE_INTR_MODE_MSIX;
 			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
 			break;
 		case VFIO_PCI_MSI_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSI;
+			intr_mode = RTE_INTR_MODE_MSI;
 			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
 			break;
 		case VFIO_PCI_INTX_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_LEGACY;
+			intr_mode = RTE_INTR_MODE_LEGACY;
 			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
 			break;
 		default:
@@ -615,7 +619,7 @@ pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
 int
 pci_vfio_map_resource(struct rte_pci_device *dev)
 {
-	if (internal_config.process_type == RTE_PROC_PRIMARY)
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
 		return pci_vfio_map_resource_primary(dev);
 	else
 		return pci_vfio_map_resource_secondary(dev);
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 22/25] net/bonding: use local prefix for local function
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (20 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 21/25] pci: use EAL exposed configuration Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 23/25] pci: introduce PCI lib and bus Gaetan Rivet
                             ` (3 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

The current name conflicts with the librte_pci naming convention.
Additionally, it is easier to use gdb when having prefixed even private
functions.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/net/bonding/rte_eth_bond_args.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index c4dcefa..ebbcc5b 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -89,7 +89,7 @@ find_port_id_by_dev_name(const char *name)
 }
 
 static inline int
-pci_addr_cmp(const struct rte_device *dev, const void *_pci_addr)
+bond_pci_addr_cmp(const struct rte_device *dev, const void *_pci_addr)
 {
 	struct rte_pci_device *pdev;
 	const struct rte_pci_addr *paddr = _pci_addr;
@@ -118,7 +118,7 @@ parse_port_id(const char *port_str)
 
 	/* try parsing as pci address, physical devices */
 	if (pci_bus->parse(port_str, &dev_addr) == 0) {
-		dev = pci_bus->find_device(NULL, pci_addr_cmp, &dev_addr);
+		dev = pci_bus->find_device(NULL, bond_pci_addr_cmp, &dev_addr);
 		if (dev == NULL) {
 			RTE_LOG(ERR, PMD, "unable to find PCI device\n");
 			return -1;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 23/25] pci: introduce PCI lib and bus
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (21 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 22/25] net/bonding: use local prefix for local function Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 24/25] doc: add notes on EAL PCI API update Gaetan Rivet
                             ` (2 subsequent siblings)
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

The PCI lib defines the types and methods allowing to use PCI elements.

The PCI bus implements a bus driver for PCI devices by constructing
rte_bus elements using the PCI lib.

Move the relevant code out of the EAL to its expected place.

Libraries, drivers, unit tests and applications are updated to use the
new rte_bus_pci.h header when necessary.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 app/test-pmd/testpmd.h                       |   1 +
 config/common_base                           |  10 +
 drivers/bus/Makefile                         |   2 +
 drivers/bus/pci/Makefile                     |  62 ++
 drivers/bus/pci/bsd/Makefile                 |  32 ++
 drivers/bus/pci/bsd/pci.c                    | 681 ++++++++++++++++++++++
 drivers/bus/pci/include/rte_bus_pci.h        | 340 +++++++++++
 drivers/bus/pci/linux/Makefile               |  36 ++
 drivers/bus/pci/linux/pci.c                  | 826 +++++++++++++++++++++++++++
 drivers/bus/pci/linux/pci_init.h             |  99 ++++
 drivers/bus/pci/linux/pci_uio.c              | 568 ++++++++++++++++++
 drivers/bus/pci/linux/pci_vfio.c             | 756 ++++++++++++++++++++++++
 drivers/bus/pci/pci_common.c                 | 535 +++++++++++++++++
 drivers/bus/pci/pci_common_uio.c             | 235 ++++++++
 drivers/bus/pci/private.h                    | 248 ++++++++
 drivers/bus/pci/rte_bus_pci_version.map      |  17 +
 drivers/crypto/qat/Makefile                  |   1 +
 drivers/crypto/qat/qat_qp.c                  |   1 +
 drivers/crypto/qat/rte_qat_cryptodev.c       |   1 +
 drivers/event/octeontx/Makefile              |   1 +
 drivers/event/skeleton/Makefile              |   1 +
 drivers/mempool/octeontx/Makefile            |   1 +
 drivers/mempool/octeontx/octeontx_fpavf.c    |   2 +-
 drivers/mempool/octeontx/octeontx_ssovf.c    |   1 +
 drivers/net/ark/Makefile                     |   1 +
 drivers/net/ark/ark_ethdev.c                 |   1 +
 drivers/net/avp/Makefile                     |   1 +
 drivers/net/avp/avp_ethdev.c                 |   2 +
 drivers/net/bnx2x/Makefile                   |   1 +
 drivers/net/bnxt/Makefile                    |   1 +
 drivers/net/bnxt/bnxt.h                      |   1 +
 drivers/net/bonding/Makefile                 |   1 +
 drivers/net/bonding/rte_eth_bond_args.c      |   1 +
 drivers/net/cxgbe/Makefile                   |   1 +
 drivers/net/cxgbe/base/adapter.h             |   1 +
 drivers/net/cxgbe/cxgbe_ethdev.c             |   1 +
 drivers/net/e1000/Makefile                   |   1 +
 drivers/net/e1000/em_ethdev.c                |   1 +
 drivers/net/e1000/igb_ethdev.c               |   1 +
 drivers/net/e1000/igb_pf.c                   |   1 +
 drivers/net/ena/Makefile                     |   1 +
 drivers/net/ena/ena_ethdev.h                 |   1 +
 drivers/net/enic/Makefile                    |   1 +
 drivers/net/enic/base/vnic_dev.h             |   4 +-
 drivers/net/enic/enic_ethdev.c               |   1 +
 drivers/net/enic/enic_main.c                 |   1 +
 drivers/net/fm10k/Makefile                   |   1 +
 drivers/net/i40e/Makefile                    |   1 +
 drivers/net/i40e/i40e_ethdev.c               |   1 +
 drivers/net/i40e/i40e_ethdev_vf.c            |   1 +
 drivers/net/ixgbe/Makefile                   |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c             |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.h             |   1 +
 drivers/net/liquidio/Makefile                |   1 +
 drivers/net/mlx4/Makefile                    |   1 +
 drivers/net/mlx4/mlx4_ethdev.c               |   1 +
 drivers/net/mlx5/Makefile                    |   1 +
 drivers/net/mlx5/mlx5.c                      |   1 +
 drivers/net/mlx5/mlx5_ethdev.c               |   1 +
 drivers/net/nfp/Makefile                     |   1 +
 drivers/net/nfp/nfp_nfpu.c                   |   2 +-
 drivers/net/nfp/nfp_nfpu.h                   |   2 +-
 drivers/net/octeontx/Makefile                |   1 +
 drivers/net/octeontx/base/octeontx_pkivf.c   |   2 +-
 drivers/net/octeontx/base/octeontx_pkovf.c   |   2 +-
 drivers/net/qede/Makefile                    |   1 +
 drivers/net/sfc/Makefile                     |   1 +
 drivers/net/sfc/sfc.h                        |   1 +
 drivers/net/sfc/sfc_ethdev.c                 |   1 +
 drivers/net/szedata2/Makefile                |   1 +
 drivers/net/thunderx/Makefile                |   1 +
 drivers/net/thunderx/nicvf_ethdev.c          |   1 +
 drivers/net/virtio/Makefile                  |   1 +
 drivers/net/virtio/virtio_ethdev.c           |   1 +
 drivers/net/virtio/virtio_pci.h              |   1 +
 drivers/net/vmxnet3/Makefile                 |   1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c         |   1 +
 lib/Makefile                                 |   2 +
 lib/librte_eal/bsdapp/eal/Makefile           |   3 -
 lib/librte_eal/bsdapp/eal/eal.c              |   1 -
 lib/librte_eal/bsdapp/eal/eal_pci.c          | 680 ----------------------
 lib/librte_eal/common/Makefile               |   2 +-
 lib/librte_eal/common/eal_common_pci.c       | 693 ----------------------
 lib/librte_eal/common/eal_common_pci_uio.c   | 233 --------
 lib/librte_eal/common/eal_private.h          | 206 -------
 lib/librte_eal/common/include/rte_pci.h      | 533 -----------------
 lib/librte_eal/linuxapp/eal/Makefile         |   8 -
 lib/librte_eal/linuxapp/eal/eal.c            |   1 -
 lib/librte_eal/linuxapp/eal/eal_interrupts.c |   1 -
 lib/librte_eal/linuxapp/eal/eal_pci.c        | 823 --------------------------
 lib/librte_eal/linuxapp/eal/eal_pci_init.h   |  99 ----
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c    | 567 ------------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c   | 754 ------------------------
 lib/librte_eal/rte_eal_version.map           |  17 -
 lib/librte_ether/rte_ethdev.h                |   2 -
 lib/librte_ether/rte_ethdev_pci.h            |   1 +
 lib/librte_eventdev/rte_eventdev_pmd_pci.h   |   1 +
 lib/librte_pci/Makefile                      |  49 ++
 lib/librte_pci/include/rte_pci.h             | 279 +++++++++
 lib/librte_pci/rte_pci.c                     | 220 +++++++
 lib/librte_pci/rte_pci_version.map           |  15 +
 mk/rte.app.mk                                |   3 +
 test/test/test_kni.c                         |   1 +
 test/test/virtual_pmd.c                      |   1 +
 104 files changed, 5085 insertions(+), 4628 deletions(-)
 create mode 100644 drivers/bus/pci/Makefile
 create mode 100644 drivers/bus/pci/bsd/Makefile
 create mode 100644 drivers/bus/pci/bsd/pci.c
 create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
 create mode 100644 drivers/bus/pci/linux/Makefile
 create mode 100644 drivers/bus/pci/linux/pci.c
 create mode 100644 drivers/bus/pci/linux/pci_init.h
 create mode 100644 drivers/bus/pci/linux/pci_uio.c
 create mode 100644 drivers/bus/pci/linux/pci_vfio.c
 create mode 100644 drivers/bus/pci/pci_common.c
 create mode 100644 drivers/bus/pci/pci_common_uio.c
 create mode 100644 drivers/bus/pci/private.h
 create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
 delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
 delete mode 100644 lib/librte_eal/common/include/rte_pci.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
 create mode 100644 lib/librte_pci/Makefile
 create mode 100644 lib/librte_pci/include/rte_pci.h
 create mode 100644 lib/librte_pci/rte_pci.c
 create mode 100644 lib/librte_pci/rte_pci_version.map

diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 265b75f..726a5fd 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -35,6 +35,7 @@
 #define _TESTPMD_H_
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_gro.h>
 #include <rte_gso.h>
 
diff --git a/config/common_base b/config/common_base
index 4ddde59..7af7fe7 100644
--- a/config/common_base
+++ b/config/common_base
@@ -123,6 +123,11 @@ CONFIG_RTE_EAL_PMD_PATH=""
 CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
 
 #
+# Compile the PCI library
+#
+CONFIG_RTE_LIBRTE_PCI=y
+
+#
 # Compile the argument parser library
 #
 CONFIG_RTE_LIBRTE_KVARGS=y
@@ -148,6 +153,11 @@ CONFIG_RTE_ETHDEV_PROFILE_ITT_WASTED_RX_ITERATIONS=n
 CONFIG_RTE_ETHDEV_TX_PREPARE_NOOP=n
 
 #
+# Compile PCI bus driver
+#
+CONFIG_RTE_LIBRTE_PCI_BUS=y
+
+#
 # Compile burst-oriented Amazon ENA PMD driver
 #
 CONFIG_RTE_LIBRTE_ENA_PMD=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 4b29e3d..a220d27 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -36,4 +36,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += dpaa
 
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 
+DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/pci/Makefile b/drivers/bus/pci/Makefile
new file mode 100644
index 0000000..23aad5e
--- /dev/null
+++ b/drivers/bus/pci/Makefile
@@ -0,0 +1,62 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+LIB = librte_bus_pci.a
+LIBABIVER := 1
+EXPORT_MAP := rte_bus_pci_version.map
+
+CFLAGS := -I$(SRCDIR)/include -I$(SRCDIR) $(CFLAGS)
+CFLAGS += -O3 $(WERROR_FLAGS)
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),)
+SYSTEM := linux
+endif
+ifneq ($(CONFIG_RTE_EXEC_ENV_BSDAPP),)
+SYSTEM := bsd
+endif
+
+CFLAGS += -I$(RTE_SDK)/drivers/bus/pci/$(SYSTEM)
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/$(SYSTEM)app/eal
+
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
+LDLIBS += -lrte_ethdev -lrte_pci
+
+include $(RTE_SDK)/drivers/bus/pci/$(SYSTEM)/Makefile
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) := $(addprefix $(SYSTEM)/,$(SRCS))
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci_common.c
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci_common_uio.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI_BUS)-include += include/rte_bus_pci.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/pci/bsd/Makefile b/drivers/bus/pci/bsd/Makefile
new file mode 100644
index 0000000..4450913
--- /dev/null
+++ b/drivers/bus/pci/bsd/Makefile
@@ -0,0 +1,32 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += pci.c
diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
new file mode 100644
index 0000000..39d65c6
--- /dev/null
+++ b/drivers/bus/pci/bsd/pci.c
@@ -0,0 +1,681 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/pciio.h>
+#include <dev/pci/pcireg.h>
+
+#if defined(RTE_ARCH_X86)
+#include <machine/cpufunc.h>
+#endif
+
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_common.h>
+#include <rte_launch.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+#include <rte_debug.h>
+#include <rte_devargs.h>
+
+#include "eal_filesystem.h"
+#include "private.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in
+ * sysfs. Moreover, when a registered driver matches a device, the
+ * kernel driver currently using it is unloaded and replaced by
+ * igb_uio module, which is a very minimal userland driver for Intel
+ * network card, only providing access to PCI BAR to applications, and
+ * enabling bus master.
+ */
+
+extern struct rte_pci_bus rte_pci_bus;
+
+/* Map pci device */
+int
+rte_pci_map_device(struct rte_pci_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources */
+	switch (dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		/* map resources for devices that use uio */
+		ret = pci_uio_map_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+/* Unmap pci device */
+void
+rte_pci_unmap_device(struct rte_pci_device *dev)
+{
+	/* try unmapping the NIC resources */
+	switch (dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		/* unmap resources for devices that use uio */
+		pci_uio_unmap_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+void
+pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res)
+{
+	rte_free(uio_res);
+
+	if (dev->intr_handle.fd) {
+		close(dev->intr_handle.fd);
+		dev->intr_handle.fd = -1;
+		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	}
+}
+
+int
+pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res)
+{
+	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+
+	snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
+			dev->addr.bus, dev->addr.devid, dev->addr.function);
+
+	if (access(devname, O_RDWR) < 0) {
+		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+		return 1;
+	}
+
+	/* save fd if in primary process */
+	dev->intr_handle.fd = open(devname, O_RDWR);
+	if (dev->intr_handle.fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			devname, strerror(errno));
+		goto error;
+	}
+	dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+
+	/* allocate the mapping details for secondary processes*/
+	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
+	if (*uio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto error;
+	}
+
+	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
+	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
+
+	return 0;
+
+error:
+	pci_uio_free_resource(dev, *uio_res);
+	return -1;
+}
+
+int
+pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx)
+{
+	int fd;
+	char *devname;
+	void *mapaddr;
+	uint64_t offset;
+	uint64_t pagesz;
+	struct pci_map *maps;
+
+	maps = uio_res->maps;
+	devname = uio_res->path;
+	pagesz = sysconf(_SC_PAGESIZE);
+
+	/* allocate memory to keep path */
+	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+	if (maps[map_idx].path == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+				strerror(errno));
+		return -1;
+	}
+
+	/*
+	 * open resource file, to mmap it
+	 */
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				devname, strerror(errno));
+		goto error;
+	}
+
+	/* if matching map is found, then use it */
+	offset = res_idx * pagesz;
+	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
+			(size_t)dev->mem_resource[res_idx].len, 0);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		goto error;
+
+	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+	maps[map_idx].size = dev->mem_resource[res_idx].len;
+	maps[map_idx].addr = mapaddr;
+	maps[map_idx].offset = offset;
+	strcpy(maps[map_idx].path, devname);
+	dev->mem_resource[res_idx].addr = mapaddr;
+
+	return 0;
+
+error:
+	rte_free(maps[map_idx].path);
+	return -1;
+}
+
+static int
+pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
+{
+	struct rte_pci_device *dev;
+	struct pci_bar_io bar;
+	unsigned i, max;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL) {
+		return -1;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr.domain = conf->pc_sel.pc_domain;
+	dev->addr.bus = conf->pc_sel.pc_bus;
+	dev->addr.devid = conf->pc_sel.pc_dev;
+	dev->addr.function = conf->pc_sel.pc_func;
+
+	/* get vendor id */
+	dev->id.vendor_id = conf->pc_vendor;
+
+	/* get device id */
+	dev->id.device_id = conf->pc_device;
+
+	/* get subsystem_vendor id */
+	dev->id.subsystem_vendor_id = conf->pc_subvendor;
+
+	/* get subsystem_device id */
+	dev->id.subsystem_device_id = conf->pc_subdevice;
+
+	/* get class id */
+	dev->id.class_id = (conf->pc_class << 16) |
+			   (conf->pc_subclass << 8) |
+			   (conf->pc_progif);
+
+	/* TODO: get max_vfs */
+	dev->max_vfs = 0;
+
+	/* FreeBSD has no NUMA support (yet) */
+	dev->device.numa_node = 0;
+
+	pci_name_set(dev);
+
+	/* FreeBSD has only one pass through driver */
+	dev->kdrv = RTE_KDRV_NIC_UIO;
+
+	/* parse resources */
+	switch (conf->pc_hdr & PCIM_HDRTYPE) {
+	case PCIM_HDRTYPE_NORMAL:
+		max = PCIR_MAX_BAR_0;
+		break;
+	case PCIM_HDRTYPE_BRIDGE:
+		max = PCIR_MAX_BAR_1;
+		break;
+	case PCIM_HDRTYPE_CARDBUS:
+		max = PCIR_MAX_BAR_2;
+		break;
+	default:
+		goto skipdev;
+	}
+
+	for (i = 0; i <= max; i++) {
+		bar.pbi_sel = conf->pc_sel;
+		bar.pbi_reg = PCIR_BAR(i);
+		if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
+			continue;
+
+		dev->mem_resource[i].len = bar.pbi_length;
+		if (PCI_BAR_IO(bar.pbi_base)) {
+			dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
+			continue;
+		}
+		dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
+	}
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
+		rte_pci_add_device(dev);
+	}
+	else {
+		struct rte_pci_device *dev2 = NULL;
+		int ret;
+
+		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
+			ret = pci_addr_cmp(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+			else if (ret < 0) {
+				rte_pci_insert_device(dev2, dev);
+			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->max_vfs = dev->max_vfs;
+				pci_name_set(dev2);
+				memmove(dev2->mem_resource,
+					dev->mem_resource,
+					sizeof(dev->mem_resource));
+				free(dev);
+			}
+			return 0;
+		}
+		rte_pci_add_device(dev);
+	}
+
+	return 0;
+
+skipdev:
+	free(dev);
+	return 0;
+}
+
+/*
+ * Scan the content of the PCI bus, and add the devices in the devices
+ * list. Call pci_scan_one() for each pci entry found.
+ */
+int
+rte_pci_scan(void)
+{
+	int fd;
+	unsigned dev_count = 0;
+	struct pci_conf matches[16];
+	struct pci_conf_io conf_io = {
+			.pat_buf_len = 0,
+			.num_patterns = 0,
+			.patterns = NULL,
+			.match_buf_len = sizeof(matches),
+			.matches = &matches[0],
+	};
+
+	/* for debug purposes, PCI can be disabled */
+	if (!rte_eal_has_pci())
+		return 0;
+
+	fd = open("/dev/pci", O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	do {
+		unsigned i;
+		if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+			RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+					__func__, strerror(errno));
+			goto error;
+		}
+
+		for (i = 0; i < conf_io.num_matches; i++)
+			if (pci_scan_one(fd, &matches[i]) < 0)
+				goto error;
+
+		dev_count += conf_io.num_matches;
+	} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
+
+	close(fd);
+
+	RTE_LOG(DEBUG, EAL, "PCI scan found %u devices\n", dev_count);
+	return 0;
+
+error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/*
+ * Get iommu class of PCI devices on the bus.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void)
+{
+	/* Supports only RTE_KDRV_NIC_UIO */
+	return RTE_IOVA_PA;
+}
+
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+	int fd;
+	struct pci_conf matches[2];
+	struct pci_match_conf match = {
+		.pc_sel = {
+			.pc_domain = addr->domain,
+			.pc_bus = addr->bus,
+			.pc_dev = addr->devid,
+			.pc_func = addr->function,
+		},
+	};
+	struct pci_conf_io conf_io = {
+		.pat_buf_len = 0,
+		.num_patterns = 1,
+		.patterns = &match,
+		.match_buf_len = sizeof(matches),
+		.matches = &matches[0],
+	};
+
+	fd = open("/dev/pci", O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+				__func__, strerror(errno));
+		goto error;
+	}
+
+	if (conf_io.num_matches != 1)
+		goto error;
+
+	if (pci_scan_one(fd, &matches[0]) < 0)
+		goto error;
+
+	close(fd);
+
+	return 0;
+
+error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/* Read PCI config space. */
+int rte_pci_read_config(const struct rte_pci_device *dev,
+		void *buf, size_t len, off_t offset)
+{
+	int fd = -1;
+	int size;
+	struct pci_io pi = {
+		.pi_sel = {
+			.pc_domain = dev->addr.domain,
+			.pc_bus = dev->addr.bus,
+			.pc_dev = dev->addr.devid,
+			.pc_func = dev->addr.function,
+		},
+		.pi_reg = offset,
+	};
+
+	fd = open("/dev/pci", O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	while (len > 0) {
+		size = (len >= 4) ? 4 : ((len >= 2) ? 2 : 1);
+		pi.pi_width = size;
+
+		if (ioctl(fd, PCIOCREAD, &pi) < 0)
+			goto error;
+		memcpy(buf, &pi.pi_data, size);
+
+		buf = (char *)buf + size;
+		pi.pi_reg += size;
+		len -= size;
+	}
+	close(fd);
+
+	return 0;
+
+ error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/* Write PCI config space. */
+int rte_pci_write_config(const struct rte_pci_device *dev,
+		const void *buf, size_t len, off_t offset)
+{
+	int fd = -1;
+
+	struct pci_io pi = {
+		.pi_sel = {
+			.pc_domain = dev->addr.domain,
+			.pc_bus = dev->addr.bus,
+			.pc_dev = dev->addr.devid,
+			.pc_func = dev->addr.function,
+		},
+		.pi_reg = offset,
+		.pi_data = *(const uint32_t *)buf,
+		.pi_width = len,
+	};
+
+	if (len == 3 || len > sizeof(pi.pi_data)) {
+		RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__);
+		goto error;
+	}
+
+	memcpy(&pi.pi_data, buf, len);
+
+	fd = open("/dev/pci", O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	if (ioctl(fd, PCIOCWRITE, &pi) < 0)
+		goto error;
+
+	close(fd);
+	return 0;
+
+ error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+int
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p)
+{
+	int ret;
+
+	switch (dev->kdrv) {
+#if defined(RTE_ARCH_X86)
+	case RTE_KDRV_NIC_UIO:
+		if ((uintptr_t) dev->mem_resource[bar].addr <= UINT16_MAX) {
+			p->base = (uintptr_t)dev->mem_resource[bar].addr;
+			ret = 0;
+		} else
+			ret = -1;
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	if (!ret)
+		p->dev = dev;
+
+	return ret;
+}
+
+static void
+pci_uio_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+#if defined(RTE_ARCH_X86)
+	uint8_t *d;
+	int size;
+	unsigned short reg = p->base + offset;
+
+	for (d = data; len > 0; d += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+			*(uint32_t *)d = inl(reg);
+		} else if (len >= 2) {
+			size = 2;
+			*(uint16_t *)d = inw(reg);
+		} else {
+			size = 1;
+			*d = inb(reg);
+		}
+	}
+#else
+	RTE_SET_USED(p);
+	RTE_SET_USED(data);
+	RTE_SET_USED(len);
+	RTE_SET_USED(offset);
+#endif
+}
+
+void
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+pci_uio_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+#if defined(RTE_ARCH_X86)
+	const uint8_t *s;
+	int size;
+	unsigned short reg = p->base + offset;
+
+	for (s = data; len > 0; s += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+			outl(reg, *(const uint32_t *)s);
+		} else if (len >= 2) {
+			size = 2;
+			outw(reg, *(const uint16_t *)s);
+		} else {
+			size = 1;
+			outb(reg, *s);
+		}
+	}
+#else
+	RTE_SET_USED(p);
+	RTE_SET_USED(data);
+	RTE_SET_USED(len);
+	RTE_SET_USED(offset);
+#endif
+}
+
+void
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	default:
+		break;
+	}
+}
+
+int
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
+{
+	int ret;
+
+	switch (p->dev->kdrv) {
+#if defined(RTE_ARCH_X86)
+	case RTE_KDRV_NIC_UIO:
+		ret = 0;
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/bus/pci/include/rte_bus_pci.h b/drivers/bus/pci/include/rte_bus_pci.h
new file mode 100644
index 0000000..c0b619f
--- /dev/null
+++ b/drivers/bus/pci/include/rte_bus_pci.h
@@ -0,0 +1,340 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_BUS_PCI_H_
+#define _RTE_BUS_PCI_H_
+
+/**
+ * @file
+ *
+ * RTE PCI Bus Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+
+/** Pathname of PCI devices directory. */
+const char *pci_get_sysfs_path(void);
+
+/* Forward declarations */
+struct rte_pci_device;
+struct rte_pci_driver;
+
+/** List of PCI devices */
+TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
+/** List of PCI drivers */
+TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
+
+/* PCI Bus iterators */
+#define FOREACH_DEVICE_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
+
+#define FOREACH_DRIVER_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
+
+struct rte_devargs;
+
+/**
+ * A structure describing a PCI device.
+ */
+struct rte_pci_device {
+	TAILQ_ENTRY(rte_pci_device) next;   /**< Next probed PCI device. */
+	struct rte_device device;           /**< Inherit core device */
+	struct rte_pci_addr addr;           /**< PCI location. */
+	struct rte_pci_id id;               /**< PCI ID. */
+	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
+					    /**< PCI Memory Resource */
+	struct rte_intr_handle intr_handle; /**< Interrupt handle */
+	struct rte_pci_driver *driver;      /**< Associated driver */
+	uint16_t max_vfs;                   /**< sriov enable if not zero */
+	enum rte_kernel_driver kdrv;        /**< Kernel driver passthrough */
+	char name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_pci_device.
+ */
+#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
+
+#define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
+
+/** Any PCI device identifier (vendor, device, ...) */
+#define PCI_ANY_ID (0xffff)
+#define RTE_CLASS_ANY_ID (0xffffff)
+
+#ifdef __cplusplus
+/** C++ macro used to help building up tables of device IDs */
+#define RTE_PCI_DEVICE(vend, dev) \
+	RTE_CLASS_ANY_ID,         \
+	(vend),                   \
+	(dev),                    \
+	PCI_ANY_ID,               \
+	PCI_ANY_ID
+#else
+/** Macro used to help building up tables of device IDs */
+#define RTE_PCI_DEVICE(vend, dev)          \
+	.class_id = RTE_CLASS_ANY_ID,      \
+	.vendor_id = (vend),               \
+	.device_id = (dev),                \
+	.subsystem_vendor_id = PCI_ANY_ID, \
+	.subsystem_device_id = PCI_ANY_ID
+#endif
+
+/**
+ * Initialisation function for the driver called during PCI probing.
+ */
+typedef int (pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
+
+/**
+ * Uninitialisation function for the driver called during hotplugging.
+ */
+typedef int (pci_remove_t)(struct rte_pci_device *);
+
+/**
+ * A structure describing a PCI driver.
+ */
+struct rte_pci_driver {
+	TAILQ_ENTRY(rte_pci_driver) next;  /**< Next in list. */
+	struct rte_driver driver;          /**< Inherit core driver. */
+	struct rte_pci_bus *bus;           /**< PCI bus reference. */
+	pci_probe_t *probe;                /**< Device Probe function. */
+	pci_remove_t *remove;              /**< Device Remove function. */
+	const struct rte_pci_id *id_table; /**< ID table, NULL terminated. */
+	uint32_t drv_flags;                /**< Flags contolling handling of device. */
+};
+
+/**
+ * Structure describing the PCI bus
+ */
+struct rte_pci_bus {
+	struct rte_bus bus;               /**< Inherit the generic class */
+	struct rte_pci_device_list device_list;  /**< List of PCI devices */
+	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
+};
+
+/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
+#define RTE_PCI_DRV_NEED_MAPPING 0x0001
+/** Device driver supports link state interrupt */
+#define RTE_PCI_DRV_INTR_LSC	0x0008
+/** Device driver supports device removal interrupt */
+#define RTE_PCI_DRV_INTR_RMV 0x0010
+/** Device driver needs to keep mapped resources if unsupported dev detected */
+#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
+/** Device driver supports IOVA as VA */
+#define RTE_PCI_DRV_IOVA_AS_VA 0X0040
+
+/**
+ * Map the PCI device resources in user space virtual memory address
+ *
+ * Note that driver should not call this function when flag
+ * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for
+ * you when it's on.
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ *
+ * @return
+ *   0 on success, negative on error and positive if no driver
+ *   is found for the device.
+ */
+int rte_pci_map_device(struct rte_pci_device *dev);
+
+/**
+ * Unmap this device
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ */
+void rte_pci_unmap_device(struct rte_pci_device *dev);
+
+/**
+ * Dump the content of the PCI bus.
+ *
+ * @param f
+ *   A pointer to a file for output
+ */
+void rte_pci_dump(FILE *f);
+
+/**
+ * Register a PCI driver.
+ *
+ * @param driver
+ *   A pointer to a rte_pci_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_pci_register(struct rte_pci_driver *driver);
+
+/** Helper for PCI device registration from driver (eth, crypto) instance */
+#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
+RTE_INIT(pciinitfn_ ##nm); \
+static void pciinitfn_ ##nm(void) \
+{\
+	(pci_drv).driver.name = RTE_STR(nm);\
+	rte_pci_register(&pci_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a PCI driver.
+ *
+ * @param driver
+ *   A pointer to a rte_pci_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_pci_unregister(struct rte_pci_driver *driver);
+
+/**
+ * Read PCI config space.
+ *
+ * @param device
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ * @param buf
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into PCI config space
+ */
+int rte_pci_read_config(const struct rte_pci_device *device,
+		void *buf, size_t len, off_t offset);
+
+/**
+ * Write PCI config space.
+ *
+ * @param device
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ * @param buf
+ *   A data buffer containing the bytes should be written
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into PCI config space
+ */
+int rte_pci_write_config(const struct rte_pci_device *device,
+		const void *buf, size_t len, off_t offset);
+
+/**
+ * A structure used to access io resources for a pci device.
+ * rte_pci_ioport is arch, os, driver specific, and should not be used outside
+ * of pci ioport api.
+ */
+struct rte_pci_ioport {
+	struct rte_pci_device *dev;
+	uint64_t base;
+	uint64_t len; /* only filled for memory mapped ports */
+};
+
+/**
+ * Initialize a rte_pci_ioport object for a pci device io resource.
+ *
+ * This object is then used to gain access to those io resources (see below).
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use.
+ * @param bar
+ *   Index of the io pci resource we want to access.
+ * @param p
+ *   The rte_pci_ioport object to be initialized.
+ * @return
+ *  0 on success, negative on error.
+ */
+int rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p);
+
+/**
+ * Release any resources used in a rte_pci_ioport object.
+ *
+ * @param p
+ *   The rte_pci_ioport object to be uninitialized.
+ * @return
+ *  0 on success, negative on error.
+ */
+int rte_pci_ioport_unmap(struct rte_pci_ioport *p);
+
+/**
+ * Read from a io pci resource.
+ *
+ * @param p
+ *   The rte_pci_ioport object from which we want to read.
+ * @param data
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into the pci io resource.
+ */
+void rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset);
+
+/**
+ * Write to a io pci resource.
+ *
+ * @param p
+ *   The rte_pci_ioport object to which we want to write.
+ * @param data
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into the pci io resource.
+ */
+void rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_BUS_PCI_H_ */
diff --git a/drivers/bus/pci/linux/Makefile b/drivers/bus/pci/linux/Makefile
new file mode 100644
index 0000000..77c5f97
--- /dev/null
+++ b/drivers/bus/pci/linux/Makefile
@@ -0,0 +1,36 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += pci.c
+SRCS += pci_uio.c
+SRCS += pci_vfio.c
+
+CFLAGS += -D_GNU_SOURCE
diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c
new file mode 100644
index 0000000..6faeace
--- /dev/null
+++ b/drivers/bus/pci/linux/pci.c
@@ -0,0 +1,826 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <dirent.h>
+
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+#include <rte_devargs.h>
+#include <rte_memcpy.h>
+#include <rte_vfio.h>
+
+#include "eal_private.h"
+#include "eal_filesystem.h"
+
+#include "private.h"
+#include "pci_init.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in sysfs.
+ * When a registered device matches a driver, it is then initialized with
+ * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
+ */
+
+extern struct rte_pci_bus rte_pci_bus;
+
+static int
+pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
+{
+	int count;
+	char path[PATH_MAX];
+	char *name;
+
+	if (!filename || !dri_name)
+		return -1;
+
+	count = readlink(filename, path, PATH_MAX);
+	if (count >= PATH_MAX)
+		return -1;
+
+	/* For device does not have a driver */
+	if (count < 0)
+		return 1;
+
+	path[count] = '\0';
+
+	name = strrchr(path, '/');
+	if (name) {
+		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
+		return 0;
+	}
+
+	return -1;
+}
+
+/* Map pci device */
+int
+rte_pci_map_device(struct rte_pci_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_map_resource(dev);
+#endif
+		break;
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+		if (rte_eal_using_phys_addrs()) {
+			/* map resources for devices that use uio */
+			ret = pci_uio_map_resource(dev);
+		}
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+/* Unmap pci device */
+void
+rte_pci_unmap_device(struct rte_pci_device *dev)
+{
+	/* try unmapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+		if (pci_vfio_is_enabled())
+			pci_vfio_unmap_resource(dev);
+#endif
+		break;
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+		/* unmap resources for devices that use uio */
+		pci_uio_unmap_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+void *
+pci_find_max_end_va(void)
+{
+	const struct rte_memseg *seg = rte_eal_get_physmem_layout();
+	const struct rte_memseg *last = seg;
+	unsigned i = 0;
+
+	for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
+		if (seg->addr == NULL)
+			break;
+
+		if (seg->addr > last->addr)
+			last = seg;
+
+	}
+	return RTE_PTR_ADD(last->addr, last->len);
+}
+
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int
+pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+	uint64_t *end_addr, uint64_t *flags)
+{
+	union pci_resource_info {
+		struct {
+			char *phys_addr;
+			char *end_addr;
+			char *flags;
+		};
+		char *ptrs[PCI_RESOURCE_FMT_NVAL];
+	} res_info;
+
+	if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
+		RTE_LOG(ERR, EAL,
+			"%s(): bad resource format\n", __func__);
+		return -1;
+	}
+	errno = 0;
+	*phys_addr = strtoull(res_info.phys_addr, NULL, 16);
+	*end_addr = strtoull(res_info.end_addr, NULL, 16);
+	*flags = strtoull(res_info.flags, NULL, 16);
+	if (errno != 0) {
+		RTE_LOG(ERR, EAL,
+			"%s(): bad resource format\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
+
+/* parse the "resource" sysfs file */
+static int
+pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
+{
+	FILE *f;
+	char buf[BUFSIZ];
+	int i;
+	uint64_t phys_addr, end_addr, flags;
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
+		return -1;
+	}
+
+	for (i = 0; i<PCI_MAX_RESOURCE; i++) {
+
+		if (fgets(buf, sizeof(buf), f) == NULL) {
+			RTE_LOG(ERR, EAL,
+				"%s(): cannot read resource\n", __func__);
+			goto error;
+		}
+		if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+				&end_addr, &flags) < 0)
+			goto error;
+
+		if (flags & IORESOURCE_MEM) {
+			dev->mem_resource[i].phys_addr = phys_addr;
+			dev->mem_resource[i].len = end_addr - phys_addr + 1;
+			/* not mapped for now */
+			dev->mem_resource[i].addr = NULL;
+		}
+	}
+	fclose(f);
+	return 0;
+
+error:
+	fclose(f);
+	return -1;
+}
+
+/* Scan one pci sysfs entry, and fill the devices list from it. */
+static int
+pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
+{
+	char filename[PATH_MAX];
+	unsigned long tmp;
+	struct rte_pci_device *dev;
+	char driver[PATH_MAX];
+	int ret;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL)
+		return -1;
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr = *addr;
+
+	/* get vendor id */
+	snprintf(filename, sizeof(filename), "%s/vendor", dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.vendor_id = (uint16_t)tmp;
+
+	/* get device id */
+	snprintf(filename, sizeof(filename), "%s/device", dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.device_id = (uint16_t)tmp;
+
+	/* get subsystem_vendor id */
+	snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.subsystem_vendor_id = (uint16_t)tmp;
+
+	/* get subsystem_device id */
+	snprintf(filename, sizeof(filename), "%s/subsystem_device",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.subsystem_device_id = (uint16_t)tmp;
+
+	/* get class_id */
+	snprintf(filename, sizeof(filename), "%s/class",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	/* the least 24 bits are valid: class, subclass, program interface */
+	dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
+
+	/* get max_vfs */
+	dev->max_vfs = 0;
+	snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
+	if (!access(filename, F_OK) &&
+	    eal_parse_sysfs_value(filename, &tmp) == 0)
+		dev->max_vfs = (uint16_t)tmp;
+	else {
+		/* for non igb_uio driver, need kernel version >= 3.8 */
+		snprintf(filename, sizeof(filename),
+			 "%s/sriov_numvfs", dirname);
+		if (!access(filename, F_OK) &&
+		    eal_parse_sysfs_value(filename, &tmp) == 0)
+			dev->max_vfs = (uint16_t)tmp;
+	}
+
+	/* get numa node, default to 0 if not present */
+	snprintf(filename, sizeof(filename), "%s/numa_node",
+		 dirname);
+
+	if (access(filename, F_OK) != -1) {
+		if (eal_parse_sysfs_value(filename, &tmp) == 0)
+			dev->device.numa_node = tmp;
+		else
+			dev->device.numa_node = -1;
+	} else {
+		dev->device.numa_node = 0;
+	}
+
+	pci_name_set(dev);
+
+	/* parse resources */
+	snprintf(filename, sizeof(filename), "%s/resource", dirname);
+	if (pci_parse_sysfs_resource(filename, dev) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
+		free(dev);
+		return -1;
+	}
+
+	/* parse driver */
+	snprintf(filename, sizeof(filename), "%s/driver", dirname);
+	ret = pci_get_kernel_driver_by_path(filename, driver);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
+		free(dev);
+		return -1;
+	}
+
+	if (!ret) {
+		if (!strcmp(driver, "vfio-pci"))
+			dev->kdrv = RTE_KDRV_VFIO;
+		else if (!strcmp(driver, "igb_uio"))
+			dev->kdrv = RTE_KDRV_IGB_UIO;
+		else if (!strcmp(driver, "uio_pci_generic"))
+			dev->kdrv = RTE_KDRV_UIO_GENERIC;
+		else
+			dev->kdrv = RTE_KDRV_UNKNOWN;
+	} else
+		dev->kdrv = RTE_KDRV_NONE;
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
+		rte_pci_add_device(dev);
+	} else {
+		struct rte_pci_device *dev2;
+		int ret;
+
+		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
+			ret = pci_addr_cmp(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+
+			if (ret < 0) {
+				rte_pci_insert_device(dev2, dev);
+			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->max_vfs = dev->max_vfs;
+				pci_name_set(dev2);
+				memmove(dev2->mem_resource, dev->mem_resource,
+					sizeof(dev->mem_resource));
+				free(dev);
+			}
+			return 0;
+		}
+
+		rte_pci_add_device(dev);
+	}
+
+	return 0;
+}
+
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+	char filename[PATH_MAX];
+
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
+		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
+		 addr->function);
+
+	return pci_scan_one(filename, addr);
+}
+
+/*
+ * split up a pci address into its constituent parts.
+ */
+static int
+parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
+{
+	/* first split on ':' */
+	union splitaddr {
+		struct {
+			char *domain;
+			char *bus;
+			char *devid;
+			char *function;
+		};
+		char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
+	} splitaddr;
+
+	char *buf_copy = strndup(buf, bufsize);
+	if (buf_copy == NULL)
+		return -1;
+
+	if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
+			!= PCI_FMT_NVAL - 1)
+		goto error;
+	/* final split is on '.' between devid and function */
+	splitaddr.function = strchr(splitaddr.devid,'.');
+	if (splitaddr.function == NULL)
+		goto error;
+	*splitaddr.function++ = '\0';
+
+	/* now convert to int values */
+	errno = 0;
+	addr->domain = strtoul(splitaddr.domain, NULL, 16);
+	addr->bus = strtoul(splitaddr.bus, NULL, 16);
+	addr->devid = strtoul(splitaddr.devid, NULL, 16);
+	addr->function = strtoul(splitaddr.function, NULL, 10);
+	if (errno != 0)
+		goto error;
+
+	free(buf_copy); /* free the copy made with strdup */
+	return 0;
+error:
+	free(buf_copy);
+	return -1;
+}
+
+/*
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ */
+int
+rte_pci_scan(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+	struct rte_pci_addr addr;
+
+	/* for debug purposes, PCI can be disabled */
+	if (!rte_eal_has_pci())
+		return 0;
+
+#ifdef VFIO_PRESENT
+	if (!pci_vfio_is_enabled())
+		RTE_LOG(DEBUG, EAL, "VFIO PCI modules not loaded\n");
+#endif
+
+	dir = opendir(pci_get_sysfs_path());
+	if (dir == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
+			continue;
+
+		snprintf(dirname, sizeof(dirname), "%s/%s",
+				pci_get_sysfs_path(), e->d_name);
+
+		if (pci_scan_one(dirname, &addr) < 0)
+			goto error;
+	}
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
+
+/*
+ * Is pci device bound to any kdrv
+ */
+static inline int
+pci_one_device_is_bound(void)
+{
+	struct rte_pci_device *dev = NULL;
+	int ret = 0;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (dev->kdrv == RTE_KDRV_UNKNOWN ||
+		    dev->kdrv == RTE_KDRV_NONE) {
+			continue;
+		} else {
+			ret = 1;
+			break;
+		}
+	}
+	return ret;
+}
+
+/*
+ * Any one of the device bound to uio
+ */
+static inline int
+pci_one_device_bound_uio(void)
+{
+	struct rte_pci_device *dev = NULL;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (dev->kdrv == RTE_KDRV_IGB_UIO ||
+		   dev->kdrv == RTE_KDRV_UIO_GENERIC) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * Any one of the device has iova as va
+ */
+static inline int
+pci_one_device_has_iova_va(void)
+{
+	struct rte_pci_device *dev = NULL;
+	struct rte_pci_driver *drv = NULL;
+
+	FOREACH_DRIVER_ON_PCIBUS(drv) {
+		if (drv && drv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) {
+			FOREACH_DEVICE_ON_PCIBUS(dev) {
+				if (dev->kdrv == RTE_KDRV_VFIO &&
+				    rte_pci_match(drv, dev))
+					return 1;
+			}
+		}
+	}
+	return 0;
+}
+
+/*
+ * Get iommu class of PCI devices on the bus.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void)
+{
+	bool is_bound;
+	bool is_vfio_noiommu_enabled = true;
+	bool has_iova_va;
+	bool is_bound_uio;
+
+	is_bound = pci_one_device_is_bound();
+	if (!is_bound)
+		return RTE_IOVA_DC;
+
+	has_iova_va = pci_one_device_has_iova_va();
+	is_bound_uio = pci_one_device_bound_uio();
+#ifdef VFIO_PRESENT
+	is_vfio_noiommu_enabled = vfio_noiommu_is_enabled() == true ?
+					true : false;
+#endif
+
+	if (has_iova_va && !is_bound_uio && !is_vfio_noiommu_enabled)
+		return RTE_IOVA_VA;
+
+	if (has_iova_va) {
+		RTE_LOG(WARNING, EAL, "Some devices want iova as va but pa will be used because.. ");
+		if (is_vfio_noiommu_enabled)
+			RTE_LOG(WARNING, EAL, "vfio-noiommu mode configured\n");
+		if (is_bound_uio)
+			RTE_LOG(WARNING, EAL, "few device bound to UIO\n");
+	}
+
+	return RTE_IOVA_PA;
+}
+
+/* Read PCI config space. */
+int rte_pci_read_config(const struct rte_pci_device *device,
+		void *buf, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &device->intr_handle;
+
+	switch (intr_handle->type) {
+	case RTE_INTR_HANDLE_UIO:
+	case RTE_INTR_HANDLE_UIO_INTX:
+		return pci_uio_read_config(intr_handle, buf, len, offset);
+
+#ifdef VFIO_PRESENT
+	case RTE_INTR_HANDLE_VFIO_MSIX:
+	case RTE_INTR_HANDLE_VFIO_MSI:
+	case RTE_INTR_HANDLE_VFIO_LEGACY:
+		return pci_vfio_read_config(intr_handle, buf, len, offset);
+#endif
+	default:
+		RTE_LOG(ERR, EAL,
+			"Unknown handle type of fd %d\n",
+					intr_handle->fd);
+		return -1;
+	}
+}
+
+/* Write PCI config space. */
+int rte_pci_write_config(const struct rte_pci_device *device,
+		const void *buf, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &device->intr_handle;
+
+	switch (intr_handle->type) {
+	case RTE_INTR_HANDLE_UIO:
+	case RTE_INTR_HANDLE_UIO_INTX:
+		return pci_uio_write_config(intr_handle, buf, len, offset);
+
+#ifdef VFIO_PRESENT
+	case RTE_INTR_HANDLE_VFIO_MSIX:
+	case RTE_INTR_HANDLE_VFIO_MSI:
+	case RTE_INTR_HANDLE_VFIO_LEGACY:
+		return pci_vfio_write_config(intr_handle, buf, len, offset);
+#endif
+	default:
+		RTE_LOG(ERR, EAL,
+			"Unknown handle type of fd %d\n",
+					intr_handle->fd);
+		return -1;
+	}
+}
+
+#if defined(RTE_ARCH_X86)
+static int
+pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
+		struct rte_pci_ioport *p)
+{
+	uint16_t start, end;
+	FILE *fp;
+	char *line = NULL;
+	char pci_id[16];
+	int found = 0;
+	size_t linesz;
+
+	snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
+		 dev->addr.domain, dev->addr.bus,
+		 dev->addr.devid, dev->addr.function);
+
+	fp = fopen("/proc/ioports", "r");
+	if (fp == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);
+		return -1;
+	}
+
+	while (getdelim(&line, &linesz, '\n', fp) > 0) {
+		char *ptr = line;
+		char *left;
+		int n;
+
+		n = strcspn(ptr, ":");
+		ptr[n] = 0;
+		left = &ptr[n + 1];
+
+		while (*left && isspace(*left))
+			left++;
+
+		if (!strncmp(left, pci_id, strlen(pci_id))) {
+			found = 1;
+
+			while (*ptr && isspace(*ptr))
+				ptr++;
+
+			sscanf(ptr, "%04hx-%04hx", &start, &end);
+
+			break;
+		}
+	}
+
+	free(line);
+	fclose(fp);
+
+	if (!found)
+		return -1;
+
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	p->base = start;
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
+
+	return 0;
+}
+#endif
+
+int
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p)
+{
+	int ret = -1;
+
+	switch (dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_ioport_map(dev, bar, p);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		ret = pci_uio_ioport_map(dev, bar, p);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+		ret = pci_ioport_map(dev, bar, p);
+#else
+		ret = pci_uio_ioport_map(dev, bar, p);
+#endif
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		ret = pci_ioport_map(dev, bar, p);
+#endif
+		break;
+	default:
+		break;
+	}
+
+	if (!ret)
+		p->dev = dev;
+
+	return ret;
+}
+
+void
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		pci_vfio_ioport_read(p, data, len, offset);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		pci_uio_ioport_read(p, data, len, offset);
+#endif
+		break;
+	default:
+		break;
+	}
+}
+
+void
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		pci_vfio_ioport_write(p, data, len, offset);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		pci_uio_ioport_write(p, data, len, offset);
+#endif
+		break;
+	default:
+		break;
+	}
+}
+
+int
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
+{
+	int ret = -1;
+
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_ioport_unmap(p);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		ret = pci_uio_ioport_unmap(p);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+		ret = 0;
+#else
+		ret = pci_uio_ioport_unmap(p);
+#endif
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		ret = 0;
+#endif
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/bus/pci/linux/pci_init.h b/drivers/bus/pci/linux/pci_init.h
new file mode 100644
index 0000000..c94ba19
--- /dev/null
+++ b/drivers/bus/pci/linux/pci_init.h
@@ -0,0 +1,99 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EAL_PCI_INIT_H_
+#define EAL_PCI_INIT_H_
+
+#include <rte_vfio.h>
+
+/** IO resource type: */
+#define IORESOURCE_IO         0x00000100
+#define IORESOURCE_MEM        0x00000200
+
+/*
+ * Helper function to map PCI resources right after hugepages in virtual memory
+ */
+extern void *pci_map_addr;
+void *pci_find_max_end_va(void);
+
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+	uint64_t *end_addr, uint64_t *flags);
+
+int pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res);
+void pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res);
+int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx);
+
+int pci_uio_read_config(const struct rte_intr_handle *intr_handle,
+			void *buf, size_t len, off_t offs);
+int pci_uio_write_config(const struct rte_intr_handle *intr_handle,
+			 const void *buf, size_t len, off_t offs);
+
+int pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		       struct rte_pci_ioport *p);
+void pci_uio_ioport_read(struct rte_pci_ioport *p,
+			 void *data, size_t len, off_t offset);
+void pci_uio_ioport_write(struct rte_pci_ioport *p,
+			  const void *data, size_t len, off_t offset);
+int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
+
+#ifdef RTE_EAL_VFIO
+
+/* access config space */
+int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
+			 void *buf, size_t len, off_t offs);
+int pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
+			  const void *buf, size_t len, off_t offs);
+
+int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
+		        struct rte_pci_ioport *p);
+void pci_vfio_ioport_read(struct rte_pci_ioport *p,
+			  void *data, size_t len, off_t offset);
+void pci_vfio_ioport_write(struct rte_pci_ioport *p,
+			   const void *data, size_t len, off_t offset);
+int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
+
+/* map/unmap VFIO resource prototype */
+int pci_vfio_map_resource(struct rte_pci_device *dev);
+int pci_vfio_unmap_resource(struct rte_pci_device *dev);
+
+int pci_vfio_is_enabled(void);
+
+#endif
+
+#endif /* EAL_PCI_INIT_H_ */
diff --git a/drivers/bus/pci/linux/pci_uio.c b/drivers/bus/pci/linux/pci_uio.c
new file mode 100644
index 0000000..8cf6218
--- /dev/null
+++ b/drivers/bus/pci/linux/pci_uio.c
@@ -0,0 +1,568 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/sysmacros.h>
+#include <linux/pci_regs.h>
+
+#if defined(RTE_ARCH_X86)
+#include <sys/io.h>
+#endif
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_common.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "pci_init.h"
+
+void *pci_map_addr = NULL;
+
+#define OFF_MAX              ((uint64_t)(off_t)-1)
+
+int
+pci_uio_read_config(const struct rte_intr_handle *intr_handle,
+		    void *buf, size_t len, off_t offset)
+{
+	return pread(intr_handle->uio_cfg_fd, buf, len, offset);
+}
+
+int
+pci_uio_write_config(const struct rte_intr_handle *intr_handle,
+		     const void *buf, size_t len, off_t offset)
+{
+	return pwrite(intr_handle->uio_cfg_fd, buf, len, offset);
+}
+
+static int
+pci_uio_set_bus_master(int dev_fd)
+{
+	uint16_t reg;
+	int ret;
+
+	ret = pread(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL,
+			"Cannot read command from PCI config space!\n");
+		return -1;
+	}
+
+	/* return if bus mastering is already on */
+	if (reg & PCI_COMMAND_MASTER)
+		return 0;
+
+	reg |= PCI_COMMAND_MASTER;
+
+	ret = pwrite(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL,
+			"Cannot write command to PCI config space!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
+{
+	FILE *f;
+	char filename[PATH_MAX];
+	int ret;
+	unsigned major, minor;
+	dev_t dev;
+
+	/* get the name of the sysfs file that contains the major and minor
+	 * of the uio device and read its content */
+	snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path);
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n",
+			__func__);
+		return -1;
+	}
+
+	ret = fscanf(f, "%u:%u", &major, &minor);
+	if (ret != 2) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n",
+			__func__);
+		fclose(f);
+		return -1;
+	}
+	fclose(f);
+
+	/* create the char device "mknod /dev/uioX c major minor" */
+	snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
+	dev = makedev(major, minor);
+	ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
+	if (ret != 0) {
+		RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	return ret;
+}
+
+/*
+ * Return the uioX char device used for a pci device. On success, return
+ * the UIO number and fill dstbuf string with the path of the device in
+ * sysfs. On error, return a negative value. In this case dstbuf is
+ * invalid.
+ */
+static int
+pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
+			   unsigned int buflen, int create)
+{
+	struct rte_pci_addr *loc = &dev->addr;
+	int uio_num = -1;
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+
+	/* depending on kernel version, uio can be located in uio/uioX
+	 * or uio:uioX */
+
+	snprintf(dirname, sizeof(dirname),
+			"%s/" PCI_PRI_FMT "/uio", pci_get_sysfs_path(),
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	dir = opendir(dirname);
+	if (dir == NULL) {
+		/* retry with the parent directory */
+		snprintf(dirname, sizeof(dirname),
+				"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
+				loc->domain, loc->bus, loc->devid, loc->function);
+		dir = opendir(dirname);
+
+		if (dir == NULL) {
+			RTE_LOG(ERR, EAL, "Cannot opendir %s\n", dirname);
+			return -1;
+		}
+	}
+
+	/* take the first file starting with "uio" */
+	while ((e = readdir(dir)) != NULL) {
+		/* format could be uio%d ...*/
+		int shortprefix_len = sizeof("uio") - 1;
+		/* ... or uio:uio%d */
+		int longprefix_len = sizeof("uio:uio") - 1;
+		char *endptr;
+
+		if (strncmp(e->d_name, "uio", 3) != 0)
+			continue;
+
+		/* first try uio%d */
+		errno = 0;
+		uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
+		if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
+			snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
+			break;
+		}
+
+		/* then try uio:uio%d */
+		errno = 0;
+		uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
+		if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
+			snprintf(dstbuf, buflen, "%s/uio:uio%u", dirname, uio_num);
+			break;
+		}
+	}
+	closedir(dir);
+
+	/* No uio resource found */
+	if (e == NULL)
+		return -1;
+
+	/* create uio device if we've been asked to */
+	if (rte_eal_create_uio_dev() && create &&
+			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
+		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
+
+	return uio_num;
+}
+
+void
+pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res)
+{
+	rte_free(uio_res);
+
+	if (dev->intr_handle.uio_cfg_fd >= 0) {
+		close(dev->intr_handle.uio_cfg_fd);
+		dev->intr_handle.uio_cfg_fd = -1;
+	}
+	if (dev->intr_handle.fd >= 0) {
+		close(dev->intr_handle.fd);
+		dev->intr_handle.fd = -1;
+		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	}
+}
+
+int
+pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res)
+{
+	char dirname[PATH_MAX];
+	char cfgname[PATH_MAX];
+	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	int uio_num;
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+
+	/* find uio resource */
+	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 1);
+	if (uio_num < 0) {
+		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+		return 1;
+	}
+	snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
+
+	/* save fd if in primary process */
+	dev->intr_handle.fd = open(devname, O_RDWR);
+	if (dev->intr_handle.fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			devname, strerror(errno));
+		goto error;
+	}
+
+	snprintf(cfgname, sizeof(cfgname),
+			"/sys/class/uio/uio%u/device/config", uio_num);
+	dev->intr_handle.uio_cfg_fd = open(cfgname, O_RDWR);
+	if (dev->intr_handle.uio_cfg_fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			cfgname, strerror(errno));
+		goto error;
+	}
+
+	if (dev->kdrv == RTE_KDRV_IGB_UIO)
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+	else {
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
+
+		/* set bus master that is not done by uio_pci_generic */
+		if (pci_uio_set_bus_master(dev->intr_handle.uio_cfg_fd)) {
+			RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
+			goto error;
+		}
+	}
+
+	/* allocate the mapping details for secondary processes*/
+	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
+	if (*uio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto error;
+	}
+
+	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
+	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
+
+	return 0;
+
+error:
+	pci_uio_free_resource(dev, *uio_res);
+	return -1;
+}
+
+int
+pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx)
+{
+	int fd;
+	char devname[PATH_MAX];
+	void *mapaddr;
+	struct rte_pci_addr *loc;
+	struct pci_map *maps;
+
+	loc = &dev->addr;
+	maps = uio_res->maps;
+
+	/* update devname for mmap  */
+	snprintf(devname, sizeof(devname),
+			"%s/" PCI_PRI_FMT "/resource%d",
+			pci_get_sysfs_path(),
+			loc->domain, loc->bus, loc->devid,
+			loc->function, res_idx);
+
+	/* allocate memory to keep path */
+	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+	if (maps[map_idx].path == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+				strerror(errno));
+		return -1;
+	}
+
+	/*
+	 * open resource file, to mmap it
+	 */
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				devname, strerror(errno));
+		goto error;
+	}
+
+	/* try mapping somewhere close to the end of hugepages */
+	if (pci_map_addr == NULL)
+		pci_map_addr = pci_find_max_end_va();
+
+	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
+			(size_t)dev->mem_resource[res_idx].len, 0);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		goto error;
+
+	pci_map_addr = RTE_PTR_ADD(mapaddr,
+			(size_t)dev->mem_resource[res_idx].len);
+
+	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+	maps[map_idx].size = dev->mem_resource[res_idx].len;
+	maps[map_idx].addr = mapaddr;
+	maps[map_idx].offset = 0;
+	strcpy(maps[map_idx].path, devname);
+	dev->mem_resource[res_idx].addr = mapaddr;
+
+	return 0;
+
+error:
+	rte_free(maps[map_idx].path);
+	return -1;
+}
+
+#if defined(RTE_ARCH_X86)
+int
+pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		   struct rte_pci_ioport *p)
+{
+	char dirname[PATH_MAX];
+	char filename[PATH_MAX];
+	int uio_num;
+	unsigned long start;
+
+	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 0);
+	if (uio_num < 0)
+		return -1;
+
+	/* get portio start */
+	snprintf(filename, sizeof(filename),
+		 "%s/portio/port%d/start", dirname, bar);
+	if (eal_parse_sysfs_value(filename, &start) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
+			__func__);
+		return -1;
+	}
+	/* ensure we don't get anything funny here, read/write will cast to
+	 * uin16_t */
+	if (start > UINT16_MAX)
+		return -1;
+
+	/* FIXME only for primary process ? */
+	if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {
+
+		snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
+		dev->intr_handle.fd = open(filename, O_RDWR);
+		if (dev->intr_handle.fd < 0) {
+			RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				filename, strerror(errno));
+			return -1;
+		}
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+	}
+
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);
+
+	p->base = start;
+	p->len = 0;
+	return 0;
+}
+#else
+int
+pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		   struct rte_pci_ioport *p)
+{
+	FILE *f;
+	char buf[BUFSIZ];
+	char filename[PATH_MAX];
+	uint64_t phys_addr, end_addr, flags;
+	int fd, i;
+	void *addr;
+
+	/* open and read addresses of the corresponding resource in sysfs */
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
+		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function);
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",
+			strerror(errno));
+		return -1;
+	}
+	for (i = 0; i < bar + 1; i++) {
+		if (fgets(buf, sizeof(buf), f) == NULL) {
+			RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");
+			goto error;
+		}
+	}
+	if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+			&end_addr, &flags) < 0)
+		goto error;
+	if ((flags & IORESOURCE_IO) == 0) {
+		RTE_LOG(ERR, EAL, "BAR %d is not an IO resource\n", bar);
+		goto error;
+	}
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
+		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function, bar);
+
+	/* mmap the pci resource */
+	fd = open(filename, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
+			strerror(errno));
+		goto error;
+	}
+	addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
+		MAP_SHARED, fd, 0);
+	close(fd);
+	if (addr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s\n",
+			strerror(errno));
+		goto error;
+	}
+
+	/* strangely, the base address is mmap addr + phys_addr */
+	p->base = (uintptr_t)addr + phys_addr;
+	p->len = end_addr + 1;
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"\n", p->base);
+	fclose(f);
+
+	return 0;
+
+error:
+	fclose(f);
+	return -1;
+}
+#endif
+
+void
+pci_uio_ioport_read(struct rte_pci_ioport *p,
+		    void *data, size_t len, off_t offset)
+{
+	uint8_t *d;
+	int size;
+	uintptr_t reg = p->base + offset;
+
+	for (d = data; len > 0; d += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+#if defined(RTE_ARCH_X86)
+			*(uint32_t *)d = inl(reg);
+#else
+			*(uint32_t *)d = *(volatile uint32_t *)reg;
+#endif
+		} else if (len >= 2) {
+			size = 2;
+#if defined(RTE_ARCH_X86)
+			*(uint16_t *)d = inw(reg);
+#else
+			*(uint16_t *)d = *(volatile uint16_t *)reg;
+#endif
+		} else {
+			size = 1;
+#if defined(RTE_ARCH_X86)
+			*d = inb(reg);
+#else
+			*d = *(volatile uint8_t *)reg;
+#endif
+		}
+	}
+}
+
+void
+pci_uio_ioport_write(struct rte_pci_ioport *p,
+		     const void *data, size_t len, off_t offset)
+{
+	const uint8_t *s;
+	int size;
+	uintptr_t reg = p->base + offset;
+
+	for (s = data; len > 0; s += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+#if defined(RTE_ARCH_X86)
+			outl_p(*(const uint32_t *)s, reg);
+#else
+			*(volatile uint32_t *)reg = *(const uint32_t *)s;
+#endif
+		} else if (len >= 2) {
+			size = 2;
+#if defined(RTE_ARCH_X86)
+			outw_p(*(const uint16_t *)s, reg);
+#else
+			*(volatile uint16_t *)reg = *(const uint16_t *)s;
+#endif
+		} else {
+			size = 1;
+#if defined(RTE_ARCH_X86)
+			outb_p(*s, reg);
+#else
+			*(volatile uint8_t *)reg = *s;
+#endif
+		}
+	}
+}
+
+int
+pci_uio_ioport_unmap(struct rte_pci_ioport *p)
+{
+#if defined(RTE_ARCH_X86)
+	RTE_SET_USED(p);
+	/* FIXME close intr fd ? */
+	return 0;
+#else
+	return munmap((void *)(uintptr_t)p->base, p->len);
+#endif
+}
diff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c
new file mode 100644
index 0000000..31c3c12
--- /dev/null
+++ b/drivers/bus/pci/linux/pci_vfio.c
@@ -0,0 +1,756 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <fcntl.h>
+#include <linux/pci_regs.h>
+#include <sys/eventfd.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+#include <rte_vfio.h>
+
+#include "eal_filesystem.h"
+
+#include "pci_init.h"
+#include "private.h"
+
+/**
+ * @file
+ * PCI probing under linux (VFIO version)
+ *
+ * This code tries to determine if the PCI device is bound to VFIO driver,
+ * and initialize it (map BARs, set up interrupts) if that's the case.
+ *
+ * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
+ */
+
+#ifdef VFIO_PRESENT
+
+#define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
+#define PAGE_MASK   (~(PAGE_SIZE - 1))
+
+static struct rte_tailq_elem rte_vfio_tailq = {
+	.name = "VFIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_vfio_tailq)
+
+int
+pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
+		    void *buf, size_t len, off_t offs)
+{
+	return pread64(intr_handle->vfio_dev_fd, buf, len,
+	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
+}
+
+int
+pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
+		    const void *buf, size_t len, off_t offs)
+{
+	return pwrite64(intr_handle->vfio_dev_fd, buf, len,
+	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
+}
+
+/* get PCI BAR number where MSI-X interrupts are */
+static int
+pci_vfio_get_msix_bar(int fd, struct pci_msix_table *msix_table)
+{
+	int ret;
+	uint32_t reg;
+	uint16_t flags;
+	uint8_t cap_id, cap_offset;
+
+	/* read PCI capability pointer from config space */
+	ret = pread64(fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_CAPABILITY_LIST);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
+				"config space!\n");
+		return -1;
+	}
+
+	/* we need first byte */
+	cap_offset = reg & 0xFF;
+
+	while (cap_offset) {
+
+		/* read PCI capability ID */
+		ret = pread64(fd, &reg, sizeof(reg),
+				VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+				cap_offset);
+		if (ret != sizeof(reg)) {
+			RTE_LOG(ERR, EAL, "Cannot read capability ID from PCI "
+					"config space!\n");
+			return -1;
+		}
+
+		/* we need first byte */
+		cap_id = reg & 0xFF;
+
+		/* if we haven't reached MSI-X, check next capability */
+		if (cap_id != PCI_CAP_ID_MSIX) {
+			ret = pread64(fd, &reg, sizeof(reg),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset);
+			if (ret != sizeof(reg)) {
+				RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
+						"config space!\n");
+				return -1;
+			}
+
+			/* we need second byte */
+			cap_offset = (reg & 0xFF00) >> 8;
+
+			continue;
+		}
+		/* else, read table offset */
+		else {
+			/* table offset resides in the next 4 bytes */
+			ret = pread64(fd, &reg, sizeof(reg),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset + 4);
+			if (ret != sizeof(reg)) {
+				RTE_LOG(ERR, EAL, "Cannot read table offset from PCI config "
+						"space!\n");
+				return -1;
+			}
+
+			ret = pread64(fd, &flags, sizeof(flags),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset + 2);
+			if (ret != sizeof(flags)) {
+				RTE_LOG(ERR, EAL, "Cannot read table flags from PCI config "
+						"space!\n");
+				return -1;
+			}
+
+			msix_table->bar_index = reg & RTE_PCI_MSIX_TABLE_BIR;
+			msix_table->offset = reg & RTE_PCI_MSIX_TABLE_OFFSET;
+			msix_table->size =
+				16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE));
+
+			return 0;
+		}
+	}
+	return 0;
+}
+
+/* set PCI bus mastering */
+static int
+pci_vfio_set_bus_master(int dev_fd, bool op)
+{
+	uint16_t reg;
+	int ret;
+
+	ret = pread64(dev_fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n");
+		return -1;
+	}
+
+	if (op)
+		/* set the master bit */
+		reg |= PCI_COMMAND_MASTER;
+	else
+		reg &= ~(PCI_COMMAND_MASTER);
+
+	ret = pwrite64(dev_fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_COMMAND);
+
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* set up interrupt support (but not enable interrupts) */
+static int
+pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
+{
+	int i, ret, intr_idx;
+	enum rte_intr_mode intr_mode;
+
+	/* default to invalid index */
+	intr_idx = VFIO_PCI_NUM_IRQS;
+
+	/* Get default / configured intr_mode */
+	intr_mode = rte_eal_vfio_intr_mode();
+
+	/* get interrupt type from internal config (MSI-X by default, can be
+	 * overridden from the command line
+	 */
+	switch (intr_mode) {
+	case RTE_INTR_MODE_MSIX:
+		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
+		break;
+	case RTE_INTR_MODE_MSI:
+		intr_idx = VFIO_PCI_MSI_IRQ_INDEX;
+		break;
+	case RTE_INTR_MODE_LEGACY:
+		intr_idx = VFIO_PCI_INTX_IRQ_INDEX;
+		break;
+	/* don't do anything if we want to automatically determine interrupt type */
+	case RTE_INTR_MODE_NONE:
+		break;
+	default:
+		RTE_LOG(ERR, EAL, "  unknown default interrupt type!\n");
+		return -1;
+	}
+
+	/* start from MSI-X interrupt type */
+	for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) {
+		struct vfio_irq_info irq = { .argsz = sizeof(irq) };
+		int fd = -1;
+
+		/* skip interrupt modes we don't want */
+		if (intr_mode != RTE_INTR_MODE_NONE &&
+				i != intr_idx)
+			continue;
+
+		irq.index = i;
+
+		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  cannot get IRQ info, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+
+		/* if this vector cannot be used with eventfd, fail if we explicitly
+		 * specified interrupt type, otherwise continue */
+		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
+			if (intr_mode != RTE_INTR_MODE_NONE) {
+				RTE_LOG(ERR, EAL,
+						"  interrupt vector does not support eventfd!\n");
+				return -1;
+			} else
+				continue;
+		}
+
+		/* set up an eventfd for interrupts */
+		fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
+		if (fd < 0) {
+			RTE_LOG(ERR, EAL, "  cannot set up eventfd, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+
+		dev->intr_handle.fd = fd;
+		dev->intr_handle.vfio_dev_fd = vfio_dev_fd;
+
+		switch (i) {
+		case VFIO_PCI_MSIX_IRQ_INDEX:
+			intr_mode = RTE_INTR_MODE_MSIX;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
+			break;
+		case VFIO_PCI_MSI_IRQ_INDEX:
+			intr_mode = RTE_INTR_MODE_MSI;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
+			break;
+		case VFIO_PCI_INTX_IRQ_INDEX:
+			intr_mode = RTE_INTR_MODE_LEGACY;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
+			break;
+		default:
+			RTE_LOG(ERR, EAL, "  unknown interrupt type!\n");
+			return -1;
+		}
+
+		return 0;
+	}
+
+	/* if we're here, we haven't found a suitable interrupt vector */
+	return -1;
+}
+
+static int
+pci_vfio_is_ioport_bar(int vfio_dev_fd, int bar_index)
+{
+	uint32_t ioport_bar;
+	int ret;
+
+	ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar),
+			  VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX)
+			  + PCI_BASE_ADDRESS_0 + bar_index*4);
+	if (ret != sizeof(ioport_bar)) {
+		RTE_LOG(ERR, EAL, "Cannot read command (%x) from config space!\n",
+			PCI_BASE_ADDRESS_0 + bar_index*4);
+		return -1;
+	}
+
+	return (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) != 0;
+}
+
+static int
+pci_vfio_setup_device(struct rte_pci_device *dev, int vfio_dev_fd)
+{
+	if (pci_vfio_setup_interrupts(dev, vfio_dev_fd) != 0) {
+		RTE_LOG(ERR, EAL, "Error setting up interrupts!\n");
+		return -1;
+	}
+
+	/* set bus mastering for the device */
+	if (pci_vfio_set_bus_master(vfio_dev_fd, true)) {
+		RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
+		return -1;
+	}
+
+	/* Reset the device */
+	ioctl(vfio_dev_fd, VFIO_DEVICE_RESET);
+
+	return 0;
+}
+
+static int
+pci_vfio_mmap_bar(int vfio_dev_fd, struct mapped_pci_resource *vfio_res,
+		int bar_index, int additional_flags)
+{
+	struct memreg {
+		unsigned long offset, size;
+	} memreg[2] = {};
+	void *bar_addr;
+	struct pci_msix_table *msix_table = &vfio_res->msix_table;
+	struct pci_map *bar = &vfio_res->maps[bar_index];
+
+	if (bar->size == 0)
+		/* Skip this BAR */
+		return 0;
+
+	if (msix_table->bar_index == bar_index) {
+		/*
+		 * VFIO will not let us map the MSI-X table,
+		 * but we can map around it.
+		 */
+		uint32_t table_start = msix_table->offset;
+		uint32_t table_end = table_start + msix_table->size;
+		table_end = (table_end + ~PAGE_MASK) & PAGE_MASK;
+		table_start &= PAGE_MASK;
+
+		if (table_start == 0 && table_end >= bar->size) {
+			/* Cannot map this BAR */
+			RTE_LOG(DEBUG, EAL, "Skipping BAR%d\n", bar_index);
+			bar->size = 0;
+			bar->addr = 0;
+			return 0;
+		}
+
+		memreg[0].offset = bar->offset;
+		memreg[0].size = table_start;
+		memreg[1].offset = bar->offset + table_end;
+		memreg[1].size = bar->size - table_end;
+
+		RTE_LOG(DEBUG, EAL,
+			"Trying to map BAR%d that contains the MSI-X "
+			"table. Trying offsets: "
+			"0x%04lx:0x%04lx, 0x%04lx:0x%04lx\n", bar_index,
+			memreg[0].offset, memreg[0].size,
+			memreg[1].offset, memreg[1].size);
+	} else {
+		memreg[0].offset = bar->offset;
+		memreg[0].size = bar->size;
+	}
+
+	/* reserve the address using an inaccessible mapping */
+	bar_addr = mmap(bar->addr, bar->size, 0, MAP_PRIVATE |
+			MAP_ANONYMOUS | additional_flags, -1, 0);
+	if (bar_addr != MAP_FAILED) {
+		void *map_addr = NULL;
+		if (memreg[0].size) {
+			/* actual map of first part */
+			map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
+							memreg[0].offset,
+							memreg[0].size,
+							MAP_FIXED);
+		}
+
+		/* if there's a second part, try to map it */
+		if (map_addr != MAP_FAILED
+			&& memreg[1].offset && memreg[1].size) {
+			void *second_addr = RTE_PTR_ADD(bar_addr,
+							memreg[1].offset -
+							(uintptr_t)bar->offset);
+			map_addr = pci_map_resource(second_addr,
+							vfio_dev_fd,
+							memreg[1].offset,
+							memreg[1].size,
+							MAP_FIXED);
+		}
+
+		if (map_addr == MAP_FAILED || !map_addr) {
+			munmap(bar_addr, bar->size);
+			bar_addr = MAP_FAILED;
+			RTE_LOG(ERR, EAL, "Failed to map pci BAR%d\n",
+					bar_index);
+			return -1;
+		}
+	} else {
+		RTE_LOG(ERR, EAL,
+				"Failed to create inaccessible mapping for BAR%d\n",
+				bar_index);
+		return -1;
+	}
+
+	bar->addr = bar_addr;
+	return 0;
+}
+
+static int
+pci_vfio_map_resource_primary(struct rte_pci_device *dev)
+{
+	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+	char pci_addr[PATH_MAX] = {0};
+	int vfio_dev_fd;
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list =
+		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+
+	struct pci_map *maps;
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
+					&vfio_dev_fd, &device_info);
+	if (ret)
+		return ret;
+
+	/* allocate vfio_res and get region info */
+	vfio_res = rte_zmalloc("VFIO_RES", sizeof(*vfio_res), 0);
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto err_vfio_dev_fd;
+	}
+	memcpy(&vfio_res->pci_addr, &dev->addr, sizeof(vfio_res->pci_addr));
+
+	/* get number of registers (up to BAR5) */
+	vfio_res->nb_maps = RTE_MIN((int) device_info.num_regions,
+			VFIO_PCI_BAR5_REGION_INDEX + 1);
+
+	/* map BARs */
+	maps = vfio_res->maps;
+
+	vfio_res->msix_table.bar_index = -1;
+	/* get MSI-X BAR, if any (we have to know where it is because we can't
+	 * easily mmap it when using VFIO)
+	 */
+	ret = pci_vfio_get_msix_bar(vfio_dev_fd, &vfio_res->msix_table);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "  %s cannot get MSI-X BAR number!\n",
+				pci_addr);
+		goto err_vfio_dev_fd;
+	}
+
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+		struct vfio_region_info reg = { .argsz = sizeof(reg) };
+		void *bar_addr;
+
+		reg.index = i;
+
+		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg);
+		if (ret) {
+			RTE_LOG(ERR, EAL, "  %s cannot get device region info "
+					"error %i (%s)\n", pci_addr, errno, strerror(errno));
+			goto err_vfio_res;
+		}
+
+		/* chk for io port region */
+		ret = pci_vfio_is_ioport_bar(vfio_dev_fd, i);
+		if (ret < 0)
+			goto err_vfio_res;
+		else if (ret) {
+			RTE_LOG(INFO, EAL, "Ignore mapping IO port bar(%d)\n",
+					i);
+			continue;
+		}
+
+		/* skip non-mmapable BARs */
+		if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0)
+			continue;
+
+		/* try mapping somewhere close to the end of hugepages */
+		if (pci_map_addr == NULL)
+			pci_map_addr = pci_find_max_end_va();
+
+		bar_addr = pci_map_addr;
+		pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
+
+		maps[i].addr = bar_addr;
+		maps[i].offset = reg.offset;
+		maps[i].size = reg.size;
+		maps[i].path = NULL; /* vfio doesn't have per-resource paths */
+
+		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, 0);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
+					pci_addr, i, strerror(errno));
+			goto err_vfio_res;
+		}
+
+		dev->mem_resource[i].addr = maps[i].addr;
+	}
+
+	if (pci_vfio_setup_device(dev, vfio_dev_fd) < 0) {
+		RTE_LOG(ERR, EAL, "  %s setup device failed\n", pci_addr);
+		goto err_vfio_res;
+	}
+
+	TAILQ_INSERT_TAIL(vfio_res_list, vfio_res, next);
+
+	return 0;
+err_vfio_res:
+	rte_free(vfio_res);
+err_vfio_dev_fd:
+	close(vfio_dev_fd);
+	return -1;
+}
+
+static int
+pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
+{
+	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+	char pci_addr[PATH_MAX] = {0};
+	int vfio_dev_fd;
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list =
+		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+
+	struct pci_map *maps;
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
+					&vfio_dev_fd, &device_info);
+	if (ret)
+		return ret;
+
+	/* if we're in a secondary process, just find our tailq entry */
+	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
+		if (pci_addr_cmp(&vfio_res->pci_addr,
+						 &dev->addr))
+			continue;
+		break;
+	}
+	/* if we haven't found our tailq entry, something's wrong */
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
+				pci_addr);
+		goto err_vfio_dev_fd;
+	}
+
+	/* map BARs */
+	maps = vfio_res->maps;
+
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, MAP_FIXED);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
+					pci_addr, i, strerror(errno));
+			goto err_vfio_dev_fd;
+		}
+
+		dev->mem_resource[i].addr = maps[i].addr;
+	}
+
+	return 0;
+err_vfio_dev_fd:
+	close(vfio_dev_fd);
+	return -1;
+}
+
+/*
+ * map the PCI resources of a PCI device in virtual memory (VFIO version).
+ * primary and secondary processes follow almost exactly the same path
+ */
+int
+pci_vfio_map_resource(struct rte_pci_device *dev)
+{
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		return pci_vfio_map_resource_primary(dev);
+	else
+		return pci_vfio_map_resource_secondary(dev);
+}
+
+int
+pci_vfio_unmap_resource(struct rte_pci_device *dev)
+{
+	char pci_addr[PATH_MAX] = {0};
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list;
+
+	struct pci_map *maps;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+
+	if (close(dev->intr_handle.fd) < 0) {
+		RTE_LOG(INFO, EAL, "Error when closing eventfd file descriptor for %s\n",
+			pci_addr);
+		return -1;
+	}
+
+	if (pci_vfio_set_bus_master(dev->intr_handle.vfio_dev_fd, false)) {
+		RTE_LOG(ERR, EAL, "  %s cannot unset bus mastering for PCI device!\n",
+				pci_addr);
+		return -1;
+	}
+
+	ret = vfio_release_device(pci_get_sysfs_path(), pci_addr,
+				  dev->intr_handle.vfio_dev_fd);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot release device\n", __func__);
+		return ret;
+	}
+
+	vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+	/* Get vfio_res */
+	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
+		if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
+			continue;
+		break;
+	}
+	/* if we haven't found our tailq entry, something's wrong */
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
+				pci_addr);
+		return -1;
+	}
+
+	/* unmap BARs */
+	maps = vfio_res->maps;
+
+	RTE_LOG(INFO, EAL, "Releasing pci mapped resource for %s\n",
+		pci_addr);
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+
+		/*
+		 * We do not need to be aware of MSI-X table BAR mappings as
+		 * when mapping. Just using current maps array is enough
+		 */
+		if (maps[i].addr) {
+			RTE_LOG(INFO, EAL, "Calling pci_unmap_resource for %s at %p\n",
+				pci_addr, maps[i].addr);
+			pci_unmap_resource(maps[i].addr, maps[i].size);
+		}
+	}
+
+	TAILQ_REMOVE(vfio_res_list, vfio_res, next);
+
+	return 0;
+}
+
+int
+pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
+		    struct rte_pci_ioport *p)
+{
+	if (bar < VFIO_PCI_BAR0_REGION_INDEX ||
+	    bar > VFIO_PCI_BAR5_REGION_INDEX) {
+		RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar);
+		return -1;
+	}
+
+	p->dev = dev;
+	p->base = VFIO_GET_REGION_ADDR(bar);
+	return 0;
+}
+
+void
+pci_vfio_ioport_read(struct rte_pci_ioport *p,
+		     void *data, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
+
+	if (pread64(intr_handle->vfio_dev_fd, data,
+		    len, p->base + offset) <= 0)
+		RTE_LOG(ERR, EAL,
+			"Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n",
+			VFIO_GET_REGION_IDX(p->base), (int)offset);
+}
+
+void
+pci_vfio_ioport_write(struct rte_pci_ioport *p,
+		      const void *data, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
+
+	if (pwrite64(intr_handle->vfio_dev_fd, data,
+		     len, p->base + offset) <= 0)
+		RTE_LOG(ERR, EAL,
+			"Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n",
+			VFIO_GET_REGION_IDX(p->base), (int)offset);
+}
+
+int
+pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
+{
+	RTE_SET_USED(p);
+	return -1;
+}
+
+int
+pci_vfio_is_enabled(void)
+{
+	return vfio_is_enabled("vfio_pci");
+}
+#endif
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
new file mode 100644
index 0000000..7f522d3
--- /dev/null
+++ b/drivers/bus/pci/pci_common.c
@@ -0,0 +1,535 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+
+#include "private.h"
+
+extern struct rte_pci_bus rte_pci_bus;
+
+#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
+
+const char *pci_get_sysfs_path(void)
+{
+	const char *path = NULL;
+
+	path = getenv("SYSFS_PCI_DEVICES");
+	if (path == NULL)
+		return SYSFS_PCI_DEVICES;
+
+	return path;
+}
+
+static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
+{
+	struct rte_devargs *devargs;
+	struct rte_pci_addr addr;
+	struct rte_bus *pbus;
+
+	pbus = rte_bus_find_by_name("pci");
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->bus != pbus)
+			continue;
+		devargs->bus->parse(devargs->name, &addr);
+		if (!pci_addr_cmp(&dev->addr, &addr))
+			return devargs;
+	}
+	return NULL;
+}
+
+void
+pci_name_set(struct rte_pci_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	/* Each device has its internal, canonical name set. */
+	rte_pci_device_name(&dev->addr,
+			dev->name, sizeof(dev->name));
+	devargs = pci_devargs_lookup(dev);
+	dev->device.devargs = devargs;
+	/* In blacklist mode, if the device is not blacklisted, no
+	 * rte_devargs exists for it.
+	 */
+	if (devargs != NULL)
+		/* If an rte_devargs exists, the generic rte_device uses the
+		 * given name as its namea
+		 */
+		dev->device.name = dev->device.devargs->name;
+	else
+		/* Otherwise, it uses the internal, canonical form. */
+		dev->device.name = dev->name;
+}
+
+/*
+ * Match the PCI Driver and Device using the ID Table
+ */
+int
+rte_pci_match(const struct rte_pci_driver *pci_drv,
+	      const struct rte_pci_device *pci_dev)
+{
+	const struct rte_pci_id *id_table;
+
+	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
+	     id_table++) {
+		/* check if device's identifiers match the driver's ones */
+		if (id_table->vendor_id != pci_dev->id.vendor_id &&
+				id_table->vendor_id != PCI_ANY_ID)
+			continue;
+		if (id_table->device_id != pci_dev->id.device_id &&
+				id_table->device_id != PCI_ANY_ID)
+			continue;
+		if (id_table->subsystem_vendor_id !=
+		    pci_dev->id.subsystem_vendor_id &&
+		    id_table->subsystem_vendor_id != PCI_ANY_ID)
+			continue;
+		if (id_table->subsystem_device_id !=
+		    pci_dev->id.subsystem_device_id &&
+		    id_table->subsystem_device_id != PCI_ANY_ID)
+			continue;
+		if (id_table->class_id != pci_dev->id.class_id &&
+				id_table->class_id != RTE_CLASS_ANY_ID)
+			continue;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * If vendor/device ID match, call the probe() function of the
+ * driver.
+ */
+static int
+rte_pci_probe_one_driver(struct rte_pci_driver *dr,
+			 struct rte_pci_device *dev)
+{
+	int ret;
+	struct rte_pci_addr *loc;
+
+	if ((dr == NULL) || (dev == NULL))
+		return -EINVAL;
+
+	loc = &dev->addr;
+
+	/* The device is not blacklisted; Check if driver supports it */
+	if (!rte_pci_match(dr, dev))
+		/* Match of device and driver failed */
+		return 1;
+
+	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			loc->domain, loc->bus, loc->devid, loc->function,
+			dev->device.numa_node);
+
+	/* no initialization when blacklisted, return without error */
+	if (dev->device.devargs != NULL &&
+		dev->device.devargs->policy ==
+			RTE_DEV_BLACKLISTED) {
+		RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
+			" initializing\n");
+		return 1;
+	}
+
+	if (dev->device.numa_node < 0) {
+		RTE_LOG(WARNING, EAL, "  Invalid NUMA socket, default to 0\n");
+		dev->device.numa_node = 0;
+	}
+
+	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
+		dev->id.device_id, dr->driver.name);
+
+	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+		/* map resources for devices that use igb_uio */
+		ret = rte_pci_map_device(dev);
+		if (ret != 0)
+			return ret;
+	}
+
+	/* reference driver structure */
+	dev->driver = dr;
+	dev->device.driver = &dr->driver;
+
+	/* call the driver probe() function */
+	ret = dr->probe(dr, dev);
+	if (ret) {
+		dev->driver = NULL;
+		dev->device.driver = NULL;
+		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
+			/* Don't unmap if device is unsupported and
+			 * driver needs mapped resources.
+			 */
+			!(ret > 0 &&
+				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
+			rte_pci_unmap_device(dev);
+	}
+
+	return ret;
+}
+
+/*
+ * If vendor/device ID match, call the remove() function of the
+ * driver.
+ */
+static int
+rte_pci_detach_dev(struct rte_pci_device *dev)
+{
+	struct rte_pci_addr *loc;
+	struct rte_pci_driver *dr;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	dr = dev->driver;
+	loc = &dev->addr;
+
+	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			loc->domain, loc->bus, loc->devid,
+			loc->function, dev->device.numa_node);
+
+	RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
+			dev->id.device_id, dr->driver.name);
+
+	if (dr->remove && (dr->remove(dev) < 0))
+		return -1;	/* negative value is an error */
+
+	/* clear driver structure */
+	dev->driver = NULL;
+
+	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
+		/* unmap resources for devices that use igb_uio */
+		rte_pci_unmap_device(dev);
+
+	return 0;
+}
+
+/*
+ * If vendor/device ID match, call the probe() function of all
+ * registered driver for the given device. Return -1 if initialization
+ * failed, return 1 if no driver is found for this device.
+ */
+static int
+pci_probe_all_drivers(struct rte_pci_device *dev)
+{
+	struct rte_pci_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	/* Check if a driver is already loaded */
+	if (dev->driver != NULL)
+		return 0;
+
+	FOREACH_DRIVER_ON_PCIBUS(dr) {
+		rc = rte_pci_probe_one_driver(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * Find the pci device specified by pci address, then invoke probe function of
+ * the driver of the device.
+ */
+int
+rte_pci_probe_one(const struct rte_pci_addr *addr)
+{
+	struct rte_pci_device *dev = NULL;
+
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	/* update current pci device in global list, kernel bindings might have
+	 * changed since last time we looked at it.
+	 */
+	if (pci_update_device(addr) < 0)
+		goto err_return;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (pci_addr_cmp(&dev->addr, addr))
+			continue;
+
+		ret = pci_probe_all_drivers(dev);
+		if (ret)
+			goto err_return;
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL,
+		"Requested device " PCI_PRI_FMT " cannot be used\n",
+		addr->domain, addr->bus, addr->devid, addr->function);
+	return -1;
+}
+
+/*
+ * Detach device specified by its pci address.
+ */
+int
+rte_pci_detach(const struct rte_pci_addr *addr)
+{
+	struct rte_pci_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (pci_addr_cmp(&dev->addr, addr))
+			continue;
+
+		ret = rte_pci_detach_dev(dev);
+		if (ret < 0)
+			/* negative value is an error */
+			goto err_return;
+		if (ret > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+
+		rte_pci_remove_device(dev);
+		free(dev);
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
+			" cannot be used\n", dev->addr.domain, dev->addr.bus,
+			dev->addr.devid, dev->addr.function);
+	return -1;
+}
+
+/*
+ * Scan the content of the PCI bus, and call the probe() function for
+ * all registered drivers that have a matching entry in its id_table
+ * for discovered devices.
+ */
+int
+rte_pci_probe(void)
+{
+	struct rte_pci_device *dev = NULL;
+	size_t probed = 0, failed = 0;
+	struct rte_devargs *devargs;
+	int probe_all = 0;
+	int ret = 0;
+
+	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
+		probe_all = 1;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		probed++;
+
+		devargs = dev->device.devargs;
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = pci_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->policy == RTE_DEV_WHITELISTED)
+			ret = pci_probe_all_drivers(dev);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
+				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
+				 dev->addr.devid, dev->addr.function);
+			rte_errno = errno;
+			failed++;
+			ret = 0;
+		}
+	}
+
+	return (probed && probed == failed) ? -1 : 0;
+}
+
+/* dump one device */
+static int
+pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
+{
+	int i;
+
+	fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
+	       dev->addr.devid, dev->addr.function);
+	fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
+	       dev->id.device_id);
+
+	for (i = 0; i != sizeof(dev->mem_resource) /
+		sizeof(dev->mem_resource[0]); i++) {
+		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
+			dev->mem_resource[i].phys_addr,
+			dev->mem_resource[i].len);
+	}
+	return 0;
+}
+
+/* dump devices on the bus */
+void
+rte_pci_dump(FILE *f)
+{
+	struct rte_pci_device *dev = NULL;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		pci_dump_one_device(f, dev);
+	}
+}
+
+static int
+pci_parse(const char *name, void *addr)
+{
+	struct rte_pci_addr *out = addr;
+	struct rte_pci_addr pci_addr;
+	bool parse;
+
+	parse = (pci_addr_parse(name, &pci_addr) == 0);
+	if (parse && addr != NULL)
+		*out = pci_addr;
+	return parse == false;
+}
+
+/* register a driver */
+void
+rte_pci_register(struct rte_pci_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
+	driver->bus = &rte_pci_bus;
+}
+
+/* unregister a driver */
+void
+rte_pci_unregister(struct rte_pci_driver *driver)
+{
+	TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
+	driver->bus = NULL;
+}
+
+/* Add a device to PCI bus */
+void
+rte_pci_add_device(struct rte_pci_device *pci_dev)
+{
+	TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
+}
+
+/* Insert a device into a predefined position in PCI bus */
+void
+rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+		      struct rte_pci_device *new_pci_dev)
+{
+	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
+}
+
+/* Remove a device from PCI bus */
+void
+rte_pci_remove_device(struct rte_pci_device *pci_dev)
+{
+	TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
+}
+
+static struct rte_device *
+pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		const void *data)
+{
+	struct rte_pci_device *dev;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (start && &dev->device == start) {
+			start = NULL; /* starting point found */
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+
+	return NULL;
+}
+
+static int
+pci_plug(struct rte_device *dev)
+{
+	return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
+}
+
+static int
+pci_unplug(struct rte_device *dev)
+{
+	struct rte_pci_device *pdev;
+	int ret;
+
+	pdev = RTE_DEV_TO_PCI(dev);
+	ret = rte_pci_detach_dev(pdev);
+	rte_pci_remove_device(pdev);
+	free(pdev);
+	return ret;
+}
+
+struct rte_pci_bus rte_pci_bus = {
+	.bus = {
+		.scan = rte_pci_scan,
+		.probe = rte_pci_probe,
+		.find_device = pci_find_device,
+		.plug = pci_plug,
+		.unplug = pci_unplug,
+		.parse = pci_parse,
+		.get_iommu_class = rte_pci_get_iommu_class,
+	},
+	.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
+	.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(pci, rte_pci_bus.bus);
diff --git a/drivers/bus/pci/pci_common_uio.c b/drivers/bus/pci/pci_common_uio.c
new file mode 100644
index 0000000..b58bcf5
--- /dev/null
+++ b/drivers/bus/pci/pci_common_uio.c
@@ -0,0 +1,235 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_tailq.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+
+#include "private.h"
+
+static struct rte_tailq_elem rte_uio_tailq = {
+	.name = "UIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_uio_tailq)
+
+static int
+pci_uio_map_secondary(struct rte_pci_device *dev)
+{
+	int fd, i, j;
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	TAILQ_FOREACH(uio_res, uio_res_list, next) {
+
+		/* skip this element if it doesn't match our PCI address */
+		if (pci_addr_cmp(&uio_res->pci_addr, &dev->addr))
+			continue;
+
+		for (i = 0; i != uio_res->nb_maps; i++) {
+			/*
+			 * open devname, to mmap it
+			 */
+			fd = open(uio_res->maps[i].path, O_RDWR);
+			if (fd < 0) {
+				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+					uio_res->maps[i].path, strerror(errno));
+				return -1;
+			}
+
+			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
+					fd, (off_t)uio_res->maps[i].offset,
+					(size_t)uio_res->maps[i].size, 0);
+			/* fd is not needed in slave process, close it */
+			close(fd);
+			if (mapaddr != uio_res->maps[i].addr) {
+				RTE_LOG(ERR, EAL,
+					"Cannot mmap device resource file %s to address: %p\n",
+					uio_res->maps[i].path,
+					uio_res->maps[i].addr);
+				if (mapaddr != MAP_FAILED) {
+					/* unmap addrs correctly mapped */
+					for (j = 0; j < i; j++)
+						pci_unmap_resource(
+							uio_res->maps[j].addr,
+							(size_t)uio_res->maps[j].size);
+					/* unmap addr wrongly mapped */
+					pci_unmap_resource(mapaddr,
+						(size_t)uio_res->maps[i].size);
+				}
+				return -1;
+			}
+		}
+		return 0;
+	}
+
+	RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
+	return 1;
+}
+
+/* map the PCI resource of a PCI device in virtual memory */
+int
+pci_uio_map_resource(struct rte_pci_device *dev)
+{
+	int i, map_idx = 0, ret;
+	uint64_t phaddr;
+	struct mapped_pci_resource *uio_res = NULL;
+	struct mapped_pci_res_list *uio_res_list =
+		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.uio_cfg_fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* secondary processes - use already recorded details */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return pci_uio_map_secondary(dev);
+
+	/* allocate uio resource */
+	ret = pci_uio_alloc_resource(dev, &uio_res);
+	if (ret)
+		return ret;
+
+	/* Map all BARs */
+	for (i = 0; i != PCI_MAX_RESOURCE; i++) {
+		/* skip empty BAR */
+		phaddr = dev->mem_resource[i].phys_addr;
+		if (phaddr == 0)
+			continue;
+
+		ret = pci_uio_map_resource_by_index(dev, i,
+				uio_res, map_idx);
+		if (ret)
+			goto error;
+
+		map_idx++;
+	}
+
+	uio_res->nb_maps = map_idx;
+
+	TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
+
+	return 0;
+error:
+	for (i = 0; i < map_idx; i++) {
+		pci_unmap_resource(uio_res->maps[i].addr,
+				(size_t)uio_res->maps[i].size);
+		rte_free(uio_res->maps[i].path);
+	}
+	pci_uio_free_resource(dev, uio_res);
+	return -1;
+}
+
+static void
+pci_uio_unmap(struct mapped_pci_resource *uio_res)
+{
+	int i;
+
+	if (uio_res == NULL)
+		return;
+
+	for (i = 0; i != uio_res->nb_maps; i++) {
+		pci_unmap_resource(uio_res->maps[i].addr,
+				(size_t)uio_res->maps[i].size);
+		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+			rte_free(uio_res->maps[i].path);
+	}
+}
+
+static struct mapped_pci_resource *
+pci_uio_find_resource(struct rte_pci_device *dev)
+{
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	if (dev == NULL)
+		return NULL;
+
+	TAILQ_FOREACH(uio_res, uio_res_list, next) {
+
+		/* skip this element if it doesn't match our PCI address */
+		if (!pci_addr_cmp(&uio_res->pci_addr, &dev->addr))
+			return uio_res;
+	}
+	return NULL;
+}
+
+/* unmap the PCI resource of a PCI device in virtual memory */
+void
+pci_uio_unmap_resource(struct rte_pci_device *dev)
+{
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	if (dev == NULL)
+		return;
+
+	/* find an entry for the device */
+	uio_res = pci_uio_find_resource(dev);
+	if (uio_res == NULL)
+		return;
+
+	/* secondary processes - just free maps */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return pci_uio_unmap(uio_res);
+
+	TAILQ_REMOVE(uio_res_list, uio_res, next);
+
+	/* unmap all resources */
+	pci_uio_unmap(uio_res);
+
+	/* free uio resource */
+	rte_free(uio_res);
+
+	/* close fd if in primary process */
+	close(dev->intr_handle.fd);
+	if (dev->intr_handle.uio_cfg_fd >= 0) {
+		close(dev->intr_handle.uio_cfg_fd);
+		dev->intr_handle.uio_cfg_fd = -1;
+	}
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+}
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
new file mode 100644
index 0000000..2283f09
--- /dev/null
+++ b/drivers/bus/pci/private.h
@@ -0,0 +1,248 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PCI_PRIVATE_H_
+#define _PCI_PRIVATE_H_
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+
+struct rte_pci_driver;
+struct rte_pci_device;
+
+/**
+ * Probe the PCI bus
+ *
+ * @return
+ *   - 0 on success.
+ *   - !0 on error.
+ */
+int
+rte_pci_probe(void);
+
+/**
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ *
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_pci_scan(void);
+
+/**
+ * Probe the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the probe() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to probe.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_probe_one(const struct rte_pci_addr *addr);
+
+/**
+ * Close the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the remove() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_detach(const struct rte_pci_addr *addr);
+
+/**
+ * Find the name of a PCI device.
+ */
+void
+pci_name_set(struct rte_pci_device *dev);
+
+/**
+ * Add a PCI device to the PCI Bus (append to PCI Device list). This function
+ * also updates the bus references of the PCI Device (and the generic device
+ * object embedded within.
+ *
+ * @param pci_dev
+ *	PCI device to add
+ * @return void
+ */
+void rte_pci_add_device(struct rte_pci_device *pci_dev);
+
+/**
+ * Insert a PCI device in the PCI Bus at a particular location in the device
+ * list. It also updates the PCI Bus reference of the new devices to be
+ * inserted.
+ *
+ * @param exist_pci_dev
+ *	Existing PCI device in PCI Bus
+ * @param new_pci_dev
+ *	PCI device to be added before exist_pci_dev
+ * @return void
+ */
+void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+		struct rte_pci_device *new_pci_dev);
+
+/**
+ * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
+ * in the PCI device object as well as the generic device object.
+ *
+ * @param pci_device
+ *	PCI device to be removed from PCI Bus
+ * @return void
+ */
+void rte_pci_remove_device(struct rte_pci_device *pci_device);
+
+/**
+ * Update a pci device object by asking the kernel for the latest information.
+ *
+ * This function is private to EAL.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to look for
+ * @return
+ *   - 0 on success.
+ *   - negative on error.
+ */
+int pci_update_device(const struct rte_pci_addr *addr);
+
+/**
+ * Unbind kernel driver for this device
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_unbind_kernel_driver(struct rte_pci_device *dev);
+
+/**
+ * Map the PCI resource of a PCI device in virtual memory
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_map_resource(struct rte_pci_device *dev);
+
+/**
+ * Unmap the PCI resource of a PCI device
+ *
+ * This function is private to EAL.
+ */
+void pci_uio_unmap_resource(struct rte_pci_device *dev);
+
+/**
+ * Allocate uio resource for PCI device
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device to allocate uio resource
+ * @param uio_res
+ *   Pointer to uio resource.
+ *   If the function returns 0, the pointer will be filled.
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res);
+
+/**
+ * Free uio resource for PCI device
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device to free uio resource
+ * @param uio_res
+ *   Pointer to uio resource.
+ */
+void pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res);
+
+/**
+ * Map device memory to uio resource
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device that has memory information.
+ * @param res_idx
+ *   Memory resource index of the PCI device.
+ * @param uio_res
+ *  uio resource that will keep mapping information.
+ * @param map_idx
+ *   Mapping information index of the uio resource.
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx);
+
+/*
+ * Match the PCI Driver and Device using the ID Table
+ *
+ * @param pci_drv
+ *      PCI driver from which ID table would be extracted
+ * @param pci_dev
+ *      PCI device to match against the driver
+ * @return
+ *      1 for successful match
+ *      0 for unsuccessful match
+ */
+int
+rte_pci_match(const struct rte_pci_driver *pci_drv,
+	      const struct rte_pci_device *pci_dev);
+
+/**
+ * Get iommu class of PCI devices on the bus.
+ * And return their preferred iova mapping mode.
+ *
+ * @return
+ *   - enum rte_iova_mode.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void);
+
+#endif /* _PCI_PRIVATE_H_ */
diff --git a/drivers/bus/pci/rte_bus_pci_version.map b/drivers/bus/pci/rte_bus_pci_version.map
new file mode 100644
index 0000000..ee67033
--- /dev/null
+++ b/drivers/bus/pci/rte_bus_pci_version.map
@@ -0,0 +1,17 @@
+DPDK_17.11 {
+	global:
+
+	rte_pci_dump;
+	rte_pci_ioport_map;
+	rte_pci_ioport_read;
+	rte_pci_ioport_unmap;
+	rte_pci_ioport_write;
+	rte_pci_map_device;
+	rte_pci_read_config;
+	rte_pci_register;
+	rte_pci_unmap_device;
+	rte_pci_unregister;
+	rte_pci_write_config;
+
+	local: *;
+};
diff --git a/drivers/crypto/qat/Makefile b/drivers/crypto/qat/Makefile
index c38b80d..745d019 100644
--- a/drivers/crypto/qat/Makefile
+++ b/drivers/crypto/qat/Makefile
@@ -45,6 +45,7 @@ CFLAGS += -I$(SRCDIR)/qat_adf
 LDLIBS += -lcrypto
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_cryptodev
+LDLIBS += -lrte_pci -lrte_bus_pci
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat_crypto.c
diff --git a/drivers/crypto/qat/qat_qp.c b/drivers/crypto/qat/qat_qp.c
index 8bd60ff..814ba17 100644
--- a/drivers/crypto/qat/qat_qp.c
+++ b/drivers/crypto/qat/qat_qp.c
@@ -37,6 +37,7 @@
 #include <rte_memzone.h>
 #include <rte_cryptodev_pmd.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_prefetch.h>
 
diff --git a/drivers/crypto/qat/rte_qat_cryptodev.c b/drivers/crypto/qat/rte_qat_cryptodev.c
index 701c5a6..4f8e4bf 100644
--- a/drivers/crypto/qat/rte_qat_cryptodev.c
+++ b/drivers/crypto/qat/rte_qat_cryptodev.c
@@ -31,6 +31,7 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <rte_bus_pci.h>
 #include <rte_common.h>
 #include <rte_dev.h>
 #include <rte_malloc.h>
diff --git a/drivers/event/octeontx/Makefile b/drivers/event/octeontx/Makefile
index 59639b2..ae901a3 100644
--- a/drivers/event/octeontx/Makefile
+++ b/drivers/event/octeontx/Makefile
@@ -42,6 +42,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/mempool/octeontx/
 CFLAGS += -I$(RTE_SDK)/drivers/net/octeontx/
 
 LDLIBS += -lrte_eal -lrte_eventdev -lrte_mempool_octeontx
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_octeontx_ssovf_version.map
 
diff --git a/drivers/event/skeleton/Makefile b/drivers/event/skeleton/Makefile
index e4a9f41..65e1641 100644
--- a/drivers/event/skeleton/Makefile
+++ b/drivers/event/skeleton/Makefile
@@ -39,6 +39,7 @@ LIB = librte_pmd_skeleton_event.a
 
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_eventdev
+LDLIBS += -lrte_pci -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_skeleton_event_version.map
 
diff --git a/drivers/mempool/octeontx/Makefile b/drivers/mempool/octeontx/Makefile
index 4e8477b..a2e2863 100644
--- a/drivers/mempool/octeontx/Makefile
+++ b/drivers/mempool/octeontx/Makefile
@@ -63,5 +63,6 @@ CFLAGS_rte_mempool_octeontx.o += -Ofast
 endif
 
 LDLIBS += -lrte_eal -lrte_mempool -lrte_ring -lrte_mbuf
+LDLIBS += -lrte_bus_pci
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/mempool/octeontx/octeontx_fpavf.c b/drivers/mempool/octeontx/octeontx_fpavf.c
index 831c48d..07b6ffb 100644
--- a/drivers/mempool/octeontx/octeontx_fpavf.c
+++ b/drivers/mempool/octeontx/octeontx_fpavf.c
@@ -41,7 +41,7 @@
 
 #include <rte_atomic.h>
 #include <rte_eal.h>
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_errno.h>
 #include <rte_memory.h>
 #include <rte_malloc.h>
diff --git a/drivers/mempool/octeontx/octeontx_ssovf.c b/drivers/mempool/octeontx/octeontx_ssovf.c
index 9953b2e..012c887 100644
--- a/drivers/mempool/octeontx/octeontx_ssovf.c
+++ b/drivers/mempool/octeontx/octeontx_ssovf.c
@@ -35,6 +35,7 @@
 #include <rte_eal.h>
 #include <rte_io.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "octeontx_mbox.h"
 #include "octeontx_pool_logs.h"
diff --git a/drivers/net/ark/Makefile b/drivers/net/ark/Makefile
index 5f70415..f1433bd 100644
--- a/drivers/net/ark/Makefile
+++ b/drivers/net/ark/Makefile
@@ -64,5 +64,6 @@ LDLIBS += -ldl
 endif
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index dae1f3d..384be47 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -35,6 +35,7 @@
 #include <sys/stat.h>
 #include <dlfcn.h>
 
+#include <rte_bus_pci.h>
 #include <rte_ethdev_pci.h>
 #include <rte_kvargs.h>
 
diff --git a/drivers/net/avp/Makefile b/drivers/net/avp/Makefile
index a754fa0..c29ecf4 100644
--- a/drivers/net/avp/Makefile
+++ b/drivers/net/avp/Makefile
@@ -41,6 +41,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_avp_version.map
 
diff --git a/drivers/net/avp/avp_ethdev.c b/drivers/net/avp/avp_ethdev.c
index b97a90c..89e91e2 100644
--- a/drivers/net/avp/avp_ethdev.c
+++ b/drivers/net/avp/avp_ethdev.c
@@ -36,6 +36,7 @@
 #include <errno.h>
 #include <unistd.h>
 
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_memcpy.h>
@@ -45,6 +46,7 @@
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
diff --git a/drivers/net/bnx2x/Makefile b/drivers/net/bnx2x/Makefile
index 762d42e..90ff8b1 100644
--- a/drivers/net/bnx2x/Makefile
+++ b/drivers/net/bnx2x/Makefile
@@ -11,6 +11,7 @@ CFLAGS += -DZLIB_CONST
 LDLIBS += -lz
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_bnx2x_version.map
 
diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 7aed17e..2aa0441 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -46,6 +46,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_bnxt_version.map
 
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 294a174..039b248 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -39,6 +39,7 @@
 #include <sys/queue.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_memory.h>
 #include <rte_lcore.h>
diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 84ef4ed..b86b240 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -40,6 +40,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_cmdline
+LDLIBS += -lrte_pci -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_bond_version.map
 
diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index ebbcc5b..e816da3 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -33,6 +33,7 @@
 
 #include <rte_devargs.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 
 #include <cmdline_parse.h>
diff --git a/drivers/net/cxgbe/Makefile b/drivers/net/cxgbe/Makefile
index 49a49c7..65df142 100644
--- a/drivers/net/cxgbe/Makefile
+++ b/drivers/net/cxgbe/Makefile
@@ -64,6 +64,7 @@ CFLAGS_BASE_DRIVER =
 endif
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 #
 # Add extra flags for base driver files (also known as shared code)
diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index 5e5f221..f2057af 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -36,6 +36,7 @@
 #ifndef __T4_ADAPTER_H__
 #define __T4_ADAPTER_H__
 
+#include <rte_bus_pci.h>
 #include <rte_mbuf.h>
 #include <rte_io.h>
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 02b4f62..b1405e5 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/e1000/Makefile b/drivers/net/e1000/Makefile
index 833034e..3f0344b 100644
--- a/drivers/net/e1000/Makefile
+++ b/drivers/net/e1000/Makefile
@@ -40,6 +40,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_e1000_version.map
 
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 6ebfa6d..3bd9e79 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 003bdf0..323ee34 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/e1000/igb_pf.c b/drivers/net/e1000/igb_pf.c
index 6809d30..cd6ae2f 100644
--- a/drivers/net/e1000/igb_pf.c
+++ b/drivers/net/e1000/igb_pf.c
@@ -39,6 +39,7 @@
 #include <stdarg.h>
 #include <inttypes.h>
 
+#include <rte_bus_pci.h>
 #include <rte_interrupts.h>
 #include <rte_log.h>
 #include <rte_debug.h>
diff --git a/drivers/net/ena/Makefile b/drivers/net/ena/Makefile
index 1cab5e2..f9bfe05 100644
--- a/drivers/net/ena/Makefile
+++ b/drivers/net/ena/Makefile
@@ -54,5 +54,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena_eth_com.c
 CFLAGS += $(INCLUDES)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/ena/ena_ethdev.h b/drivers/net/ena/ena_ethdev.h
index dc3080f..be8bc9f 100644
--- a/drivers/net/ena/ena_ethdev.h
+++ b/drivers/net/ena/ena_ethdev.h
@@ -35,6 +35,7 @@
 #define _ENA_ETHDEV_H_
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "ena_com.h"
 
diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile
index 6a99a99..5191db5 100644
--- a/drivers/net/enic/Makefile
+++ b/drivers/net/enic/Makefile
@@ -47,6 +47,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -Wno-strict-aliasing
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
+LDLIBS += -lrte_bus_pci
 
 VPATH += $(SRCDIR)/src
 
diff --git a/drivers/net/enic/base/vnic_dev.h b/drivers/net/enic/base/vnic_dev.h
index 9a9e691..c9ca25b 100644
--- a/drivers/net/enic/base/vnic_dev.h
+++ b/drivers/net/enic/base/vnic_dev.h
@@ -35,8 +35,10 @@
 #ifndef _VNIC_DEV_H_
 #define _VNIC_DEV_H_
 
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+
 #include "enic_compat.h"
-#include "rte_pci.h"
 #include "vnic_resource.h"
 #include "vnic_devcmd.h"
 
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 5386b2a..7a7e2d9 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -37,6 +37,7 @@
 
 #include <rte_dev.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_string_fns.h>
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 5211670..be62447 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -40,6 +40,7 @@
 #include <libgen.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_memzone.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
diff --git a/drivers/net/fm10k/Makefile b/drivers/net/fm10k/Makefile
index 9d02c21..1129596 100644
--- a/drivers/net/fm10k/Makefile
+++ b/drivers/net/fm10k/Makefile
@@ -78,6 +78,7 @@ endif
 endif
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
+LDLIBS += -lrte_bus_pci
 
 #
 # Add extra flags for base driver source files to disable warnings in them
diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile
index 1ec6160..9ab8c84 100644
--- a/drivers/net/i40e/Makefile
+++ b/drivers/net/i40e/Makefile
@@ -41,6 +41,7 @@ CFLAGS += $(WERROR_FLAGS) -DPF_DRIVER -DVF_DRIVER -DINTEGRATED_VF
 CFLAGS += -DX722_A0_SUPPORT
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_i40e_version.map
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index f40c463..80158cb 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_eal.h>
 #include <rte_string_fns.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 9f14875..2777333 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -47,6 +47,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
index 6a144e7..c4a2b26 100644
--- a/drivers/net/ixgbe/Makefile
+++ b/drivers/net/ixgbe/Makefile
@@ -84,6 +84,7 @@ endif
 endif
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
+LDLIBS += -lrte_bus_pci
 
 #
 # Add extra flags for base driver files (also known as shared code)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 14b9c53..d32647c 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index e28c856..5156483 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -41,6 +41,7 @@
 #include <rte_time.h>
 #include <rte_hash.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tm_driver.h>
 
 /* need update link, bit flag */
diff --git a/drivers/net/liquidio/Makefile b/drivers/net/liquidio/Makefile
index 79120d1..5110099 100644
--- a/drivers/net/liquidio/Makefile
+++ b/drivers/net/liquidio/Makefile
@@ -42,6 +42,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)/base -I$(SRCDIR)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_lio_version.map
 
diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile
index fc5ea3c..f1f47c2 100644
--- a/drivers/net/mlx4/Makefile
+++ b/drivers/net/mlx4/Makefile
@@ -57,6 +57,7 @@ CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -libverbs -lmlx4
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 # A few warnings cannot be avoided in external headers.
 CFLAGS += -Wno-error=cast-qual
diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
index ca2170e..b0acd12 100644
--- a/drivers/net/mlx4/mlx4_ethdev.c
+++ b/drivers/net/mlx4/mlx4_ethdev.c
@@ -61,6 +61,7 @@
 #pragma GCC diagnostic error "-Wpedantic"
 #endif
 
+#include <rte_bus_pci.h>
 #include <rte_errno.h>
 #include <rte_ethdev.h>
 #include <rte_ether.h>
diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile
index e78840f..d2ce27a 100644
--- a/drivers/net/mlx5/Makefile
+++ b/drivers/net/mlx5/Makefile
@@ -67,6 +67,7 @@ CFLAGS += -Wno-strict-prototypes
 LDLIBS += -libverbs -lmlx5
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 # A few warnings cannot be avoided in external headers.
 CFLAGS += -Wno-error=cast-qual
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 29221dc..d60ef74 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -54,6 +54,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_common.h>
 #include <rte_kvargs.h>
 
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index e06dce3..c31ea4b 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -56,6 +56,7 @@
 
 #include <rte_atomic.h>
 #include <rte_ethdev.h>
+#include <rte_bus_pci.h>
 #include <rte_mbuf.h>
 #include <rte_common.h>
 #include <rte_interrupts.h>
diff --git a/drivers/net/nfp/Makefile b/drivers/net/nfp/Makefile
index c1e51cb..4ba066a 100644
--- a/drivers/net/nfp/Makefile
+++ b/drivers/net/nfp/Makefile
@@ -42,6 +42,7 @@ CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lm
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_nfp_version.map
 
diff --git a/drivers/net/nfp/nfp_nfpu.c b/drivers/net/nfp/nfp_nfpu.c
index 556ded3..5775d8d 100644
--- a/drivers/net/nfp/nfp_nfpu.c
+++ b/drivers/net/nfp/nfp_nfpu.c
@@ -8,7 +8,7 @@
 #include <fcntl.h>
 #include <sys/types.h>
 
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_malloc.h>
 
 #include "nfp_nfpu.h"
diff --git a/drivers/net/nfp/nfp_nfpu.h b/drivers/net/nfp/nfp_nfpu.h
index 31511b3..e56fa09 100644
--- a/drivers/net/nfp/nfp_nfpu.h
+++ b/drivers/net/nfp/nfp_nfpu.h
@@ -42,7 +42,7 @@
  */
 
 
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include "nfp_nspu.h"
 
 typedef struct {
diff --git a/drivers/net/octeontx/Makefile b/drivers/net/octeontx/Makefile
index 0a8775a..515edd8 100644
--- a/drivers/net/octeontx/Makefile
+++ b/drivers/net/octeontx/Makefile
@@ -65,5 +65,6 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_mempool_octeontx
 LDLIBS += -lrte_eventdev
+LDLIBS += -lrte_bus_pci
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/octeontx/base/octeontx_pkivf.c b/drivers/net/octeontx/base/octeontx_pkivf.c
index f9e4053..b97f05c 100644
--- a/drivers/net/octeontx/base/octeontx_pkivf.c
+++ b/drivers/net/octeontx/base/octeontx_pkivf.c
@@ -32,7 +32,7 @@
 #include <string.h>
 
 #include <rte_eal.h>
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "octeontx_pkivf.h"
 
diff --git a/drivers/net/octeontx/base/octeontx_pkovf.c b/drivers/net/octeontx/base/octeontx_pkovf.c
index a8f6e5d..2bf607b 100644
--- a/drivers/net/octeontx/base/octeontx_pkovf.c
+++ b/drivers/net/octeontx/base/octeontx_pkovf.c
@@ -37,7 +37,7 @@
 #include <rte_cycles.h>
 #include <rte_malloc.h>
 #include <rte_memory.h>
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_spinlock.h>
 
 #include "../octeontx_logs.h"
diff --git a/drivers/net/qede/Makefile b/drivers/net/qede/Makefile
index 5e8e087..a166e9f 100644
--- a/drivers/net/qede/Makefile
+++ b/drivers/net/qede/Makefile
@@ -15,6 +15,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_qede_version.map
 
diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile
index e097a66..2cfd62a 100644
--- a/drivers/net/sfc/Makefile
+++ b/drivers/net/sfc/Makefile
@@ -71,6 +71,7 @@ CFLAGS_sfc_ef10_tx.o += -wd3656
 endif
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 #
 # List of base driver object files for which
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index c170384..7f11bf2 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -35,6 +35,7 @@
 #include <stdbool.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_kvargs.h>
 #include <rte_spinlock.h>
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index bd09191..430e24f 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -33,6 +33,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_errno.h>
 
 #include "efx.h"
diff --git a/drivers/net/szedata2/Makefile b/drivers/net/szedata2/Makefile
index f38125d..0ebd3ec 100644
--- a/drivers/net/szedata2/Makefile
+++ b/drivers/net/szedata2/Makefile
@@ -41,6 +41,7 @@ CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lsze2
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_szedata2_version.map
 
diff --git a/drivers/net/thunderx/Makefile b/drivers/net/thunderx/Makefile
index 183ac4b..e50e1ad 100644
--- a/drivers/net/thunderx/Makefile
+++ b/drivers/net/thunderx/Makefile
@@ -42,6 +42,7 @@ CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lm
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_thunderx_nicvf_version.map
 
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index 551b371..24ac3f9 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -61,6 +61,7 @@
 #include <rte_malloc.h>
 #include <rte_random.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tailq.h>
 
 #include "base/nicvf_plat.h"
diff --git a/drivers/net/virtio/Makefile b/drivers/net/virtio/Makefile
index 156b2e8..32e99da 100644
--- a/drivers/net/virtio/Makefile
+++ b/drivers/net/virtio/Makefile
@@ -40,6 +40,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_virtio_version.map
 
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index bfbd737..1c04b56 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -46,6 +46,7 @@
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_common.h>
 #include <rte_errno.h>
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 5f3b6c8..36d452c 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -37,6 +37,7 @@
 #include <stdint.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 
 struct virtqueue;
diff --git a/drivers/net/vmxnet3/Makefile b/drivers/net/vmxnet3/Makefile
index 9359a7b..f09de96 100644
--- a/drivers/net/vmxnet3/Makefile
+++ b/drivers/net/vmxnet3/Makefile
@@ -65,6 +65,7 @@ CFLAGS_BASE_DRIVER += -Wno-strict-aliasing -Wno-format-extra-args
 endif
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 VPATH += $(SRCDIR)/base
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 58bc4f2..9772386 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/lib/Makefile b/lib/Makefile
index 6e45700..377cee8 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-y += librte_compat
 DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
+DIRS-$(CONFIG_RTE_LIBRTE_PCI) += librte_pci
+DEPDIRS-librte_pci := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
 DEPDIRS-librte_ring := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 351fa57..934c12b 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -55,7 +55,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
@@ -69,8 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_errno.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index af15812..09112b6 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -66,7 +66,6 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_bus.h>
-#include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_version.h>
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
deleted file mode 100644
index e73b7cd..0000000
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ /dev/null
@@ -1,680 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-#include <limits.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/pciio.h>
-#include <dev/pci/pcireg.h>
-
-#if defined(RTE_ARCH_X86)
-#include <machine/cpufunc.h>
-#endif
-
-#include <rte_interrupts.h>
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_common.h>
-#include <rte_launch.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_eal.h>
-#include <rte_eal_memconfig.h>
-#include <rte_per_lcore.h>
-#include <rte_lcore.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-#include <rte_debug.h>
-#include <rte_devargs.h>
-
-#include "eal_filesystem.h"
-#include "eal_private.h"
-
-/**
- * @file
- * PCI probing under linux
- *
- * This code is used to simulate a PCI probe by parsing information in
- * sysfs. Moreover, when a registered driver matches a device, the
- * kernel driver currently using it is unloaded and replaced by
- * igb_uio module, which is a very minimal userland driver for Intel
- * network card, only providing access to PCI BAR to applications, and
- * enabling bus master.
- */
-
-extern struct rte_pci_bus rte_pci_bus;
-
-/* Map pci device */
-int
-rte_pci_map_device(struct rte_pci_device *dev)
-{
-	int ret = -1;
-
-	/* try mapping the NIC resources */
-	switch (dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		/* map resources for devices that use uio */
-		ret = pci_uio_map_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		ret = 1;
-		break;
-	}
-
-	return ret;
-}
-
-/* Unmap pci device */
-void
-rte_pci_unmap_device(struct rte_pci_device *dev)
-{
-	/* try unmapping the NIC resources */
-	switch (dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		/* unmap resources for devices that use uio */
-		pci_uio_unmap_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		break;
-	}
-}
-
-void
-pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res)
-{
-	rte_free(uio_res);
-
-	if (dev->intr_handle.fd) {
-		close(dev->intr_handle.fd);
-		dev->intr_handle.fd = -1;
-		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	}
-}
-
-int
-pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res)
-{
-	char devname[PATH_MAX]; /* contains the /dev/uioX */
-	struct rte_pci_addr *loc;
-
-	loc = &dev->addr;
-
-	snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
-			dev->addr.bus, dev->addr.devid, dev->addr.function);
-
-	if (access(devname, O_RDWR) < 0) {
-		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
-				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
-		return 1;
-	}
-
-	/* save fd if in primary process */
-	dev->intr_handle.fd = open(devname, O_RDWR);
-	if (dev->intr_handle.fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			devname, strerror(errno));
-		goto error;
-	}
-	dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-
-	/* allocate the mapping details for secondary processes*/
-	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
-	if (*uio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto error;
-	}
-
-	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
-	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
-
-	return 0;
-
-error:
-	pci_uio_free_resource(dev, *uio_res);
-	return -1;
-}
-
-int
-pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx)
-{
-	int fd;
-	char *devname;
-	void *mapaddr;
-	uint64_t offset;
-	uint64_t pagesz;
-	struct pci_map *maps;
-
-	maps = uio_res->maps;
-	devname = uio_res->path;
-	pagesz = sysconf(_SC_PAGESIZE);
-
-	/* allocate memory to keep path */
-	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
-	if (maps[map_idx].path == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
-				strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * open resource file, to mmap it
-	 */
-	fd = open(devname, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				devname, strerror(errno));
-		goto error;
-	}
-
-	/* if matching map is found, then use it */
-	offset = res_idx * pagesz;
-	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
-			(size_t)dev->mem_resource[res_idx].len, 0);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		goto error;
-
-	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
-	maps[map_idx].size = dev->mem_resource[res_idx].len;
-	maps[map_idx].addr = mapaddr;
-	maps[map_idx].offset = offset;
-	strcpy(maps[map_idx].path, devname);
-	dev->mem_resource[res_idx].addr = mapaddr;
-
-	return 0;
-
-error:
-	rte_free(maps[map_idx].path);
-	return -1;
-}
-
-static int
-pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
-{
-	struct rte_pci_device *dev;
-	struct pci_bar_io bar;
-	unsigned i, max;
-
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL) {
-		return -1;
-	}
-
-	memset(dev, 0, sizeof(*dev));
-	dev->addr.domain = conf->pc_sel.pc_domain;
-	dev->addr.bus = conf->pc_sel.pc_bus;
-	dev->addr.devid = conf->pc_sel.pc_dev;
-	dev->addr.function = conf->pc_sel.pc_func;
-
-	/* get vendor id */
-	dev->id.vendor_id = conf->pc_vendor;
-
-	/* get device id */
-	dev->id.device_id = conf->pc_device;
-
-	/* get subsystem_vendor id */
-	dev->id.subsystem_vendor_id = conf->pc_subvendor;
-
-	/* get subsystem_device id */
-	dev->id.subsystem_device_id = conf->pc_subdevice;
-
-	/* get class id */
-	dev->id.class_id = (conf->pc_class << 16) |
-			   (conf->pc_subclass << 8) |
-			   (conf->pc_progif);
-
-	/* TODO: get max_vfs */
-	dev->max_vfs = 0;
-
-	/* FreeBSD has no NUMA support (yet) */
-	dev->device.numa_node = 0;
-
-	pci_name_set(dev);
-
-	/* FreeBSD has only one pass through driver */
-	dev->kdrv = RTE_KDRV_NIC_UIO;
-
-	/* parse resources */
-	switch (conf->pc_hdr & PCIM_HDRTYPE) {
-	case PCIM_HDRTYPE_NORMAL:
-		max = PCIR_MAX_BAR_0;
-		break;
-	case PCIM_HDRTYPE_BRIDGE:
-		max = PCIR_MAX_BAR_1;
-		break;
-	case PCIM_HDRTYPE_CARDBUS:
-		max = PCIR_MAX_BAR_2;
-		break;
-	default:
-		goto skipdev;
-	}
-
-	for (i = 0; i <= max; i++) {
-		bar.pbi_sel = conf->pc_sel;
-		bar.pbi_reg = PCIR_BAR(i);
-		if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
-			continue;
-
-		dev->mem_resource[i].len = bar.pbi_length;
-		if (PCI_BAR_IO(bar.pbi_base)) {
-			dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
-			continue;
-		}
-		dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
-	}
-
-	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-		rte_pci_add_device(dev);
-	}
-	else {
-		struct rte_pci_device *dev2 = NULL;
-		int ret;
-
-		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr);
-			if (ret > 0)
-				continue;
-			else if (ret < 0) {
-				rte_pci_insert_device(dev2, dev);
-			} else { /* already registered */
-				dev2->kdrv = dev->kdrv;
-				dev2->max_vfs = dev->max_vfs;
-				pci_name_set(dev2);
-				memmove(dev2->mem_resource,
-					dev->mem_resource,
-					sizeof(dev->mem_resource));
-				free(dev);
-			}
-			return 0;
-		}
-		rte_pci_add_device(dev);
-	}
-
-	return 0;
-
-skipdev:
-	free(dev);
-	return 0;
-}
-
-/*
- * Scan the content of the PCI bus, and add the devices in the devices
- * list. Call pci_scan_one() for each pci entry found.
- */
-int
-rte_pci_scan(void)
-{
-	int fd;
-	unsigned dev_count = 0;
-	struct pci_conf matches[16];
-	struct pci_conf_io conf_io = {
-			.pat_buf_len = 0,
-			.num_patterns = 0,
-			.patterns = NULL,
-			.match_buf_len = sizeof(matches),
-			.matches = &matches[0],
-	};
-
-	/* for debug purposes, PCI can be disabled */
-	if (!rte_eal_has_pci())
-		return 0;
-
-	fd = open("/dev/pci", O_RDONLY);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	do {
-		unsigned i;
-		if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
-			RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
-					__func__, strerror(errno));
-			goto error;
-		}
-
-		for (i = 0; i < conf_io.num_matches; i++)
-			if (pci_scan_one(fd, &matches[i]) < 0)
-				goto error;
-
-		dev_count += conf_io.num_matches;
-	} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
-
-	close(fd);
-
-	RTE_LOG(DEBUG, EAL, "PCI scan found %u devices\n", dev_count);
-	return 0;
-
-error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/*
- * Get iommu class of PCI devices on the bus.
- */
-enum rte_iova_mode
-rte_pci_get_iommu_class(void)
-{
-	/* Supports only RTE_KDRV_NIC_UIO */
-	return RTE_IOVA_PA;
-}
-
-int
-pci_update_device(const struct rte_pci_addr *addr)
-{
-	int fd;
-	struct pci_conf matches[2];
-	struct pci_match_conf match = {
-		.pc_sel = {
-			.pc_domain = addr->domain,
-			.pc_bus = addr->bus,
-			.pc_dev = addr->devid,
-			.pc_func = addr->function,
-		},
-	};
-	struct pci_conf_io conf_io = {
-		.pat_buf_len = 0,
-		.num_patterns = 1,
-		.patterns = &match,
-		.match_buf_len = sizeof(matches),
-		.matches = &matches[0],
-	};
-
-	fd = open("/dev/pci", O_RDONLY);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
-				__func__, strerror(errno));
-		goto error;
-	}
-
-	if (conf_io.num_matches != 1)
-		goto error;
-
-	if (pci_scan_one(fd, &matches[0]) < 0)
-		goto error;
-
-	close(fd);
-
-	return 0;
-
-error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/* Read PCI config space. */
-int rte_pci_read_config(const struct rte_pci_device *dev,
-		void *buf, size_t len, off_t offset)
-{
-	int fd = -1;
-	int size;
-	struct pci_io pi = {
-		.pi_sel = {
-			.pc_domain = dev->addr.domain,
-			.pc_bus = dev->addr.bus,
-			.pc_dev = dev->addr.devid,
-			.pc_func = dev->addr.function,
-		},
-		.pi_reg = offset,
-	};
-
-	fd = open("/dev/pci", O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	while (len > 0) {
-		size = (len >= 4) ? 4 : ((len >= 2) ? 2 : 1);
-		pi.pi_width = size;
-
-		if (ioctl(fd, PCIOCREAD, &pi) < 0)
-			goto error;
-		memcpy(buf, &pi.pi_data, size);
-
-		buf = (char *)buf + size;
-		pi.pi_reg += size;
-		len -= size;
-	}
-	close(fd);
-
-	return 0;
-
- error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/* Write PCI config space. */
-int rte_pci_write_config(const struct rte_pci_device *dev,
-		const void *buf, size_t len, off_t offset)
-{
-	int fd = -1;
-
-	struct pci_io pi = {
-		.pi_sel = {
-			.pc_domain = dev->addr.domain,
-			.pc_bus = dev->addr.bus,
-			.pc_dev = dev->addr.devid,
-			.pc_func = dev->addr.function,
-		},
-		.pi_reg = offset,
-		.pi_data = *(const uint32_t *)buf,
-		.pi_width = len,
-	};
-
-	if (len == 3 || len > sizeof(pi.pi_data)) {
-		RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__);
-		goto error;
-	}
-
-	memcpy(&pi.pi_data, buf, len);
-
-	fd = open("/dev/pci", O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	if (ioctl(fd, PCIOCWRITE, &pi) < 0)
-		goto error;
-
-	close(fd);
-	return 0;
-
- error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-int
-rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p)
-{
-	int ret;
-
-	switch (dev->kdrv) {
-#if defined(RTE_ARCH_X86)
-	case RTE_KDRV_NIC_UIO:
-		if ((uintptr_t) dev->mem_resource[bar].addr <= UINT16_MAX) {
-			p->base = (uintptr_t)dev->mem_resource[bar].addr;
-			ret = 0;
-		} else
-			ret = -1;
-		break;
-#endif
-	default:
-		ret = -1;
-		break;
-	}
-
-	if (!ret)
-		p->dev = dev;
-
-	return ret;
-}
-
-static void
-pci_uio_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-#if defined(RTE_ARCH_X86)
-	uint8_t *d;
-	int size;
-	unsigned short reg = p->base + offset;
-
-	for (d = data; len > 0; d += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-			*(uint32_t *)d = inl(reg);
-		} else if (len >= 2) {
-			size = 2;
-			*(uint16_t *)d = inw(reg);
-		} else {
-			size = 1;
-			*d = inb(reg);
-		}
-	}
-#else
-	RTE_SET_USED(p);
-	RTE_SET_USED(data);
-	RTE_SET_USED(len);
-	RTE_SET_USED(offset);
-#endif
-}
-
-void
-rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	default:
-		break;
-	}
-}
-
-static void
-pci_uio_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-#if defined(RTE_ARCH_X86)
-	const uint8_t *s;
-	int size;
-	unsigned short reg = p->base + offset;
-
-	for (s = data; len > 0; s += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-			outl(reg, *(const uint32_t *)s);
-		} else if (len >= 2) {
-			size = 2;
-			outw(reg, *(const uint16_t *)s);
-		} else {
-			size = 1;
-			outb(reg, *s);
-		}
-	}
-#else
-	RTE_SET_USED(p);
-	RTE_SET_USED(data);
-	RTE_SET_USED(len);
-	RTE_SET_USED(offset);
-#endif
-}
-
-void
-rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	default:
-		break;
-	}
-}
-
-int
-rte_pci_ioport_unmap(struct rte_pci_ioport *p)
-{
-	int ret;
-
-	switch (p->dev->kdrv) {
-#if defined(RTE_ARCH_X86)
-	case RTE_KDRV_NIC_UIO:
-		ret = 0;
-		break;
-#endif
-	default:
-		ret = -1;
-		break;
-	}
-
-	return ret;
-}
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 64ff811..16a2f26 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -34,7 +34,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_eal_interrupts.h
 INC += rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h
 INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
deleted file mode 100644
index 0a51dd8..0000000
--- a/lib/librte_eal/common/eal_common_pci.c
+++ /dev/null
@@ -1,693 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   Copyright 2013-2014 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-
-#include <rte_errno.h>
-#include <rte_interrupts.h>
-#include <rte_log.h>
-#include <rte_bus.h>
-#include <rte_pci.h>
-#include <rte_per_lcore.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_eal.h>
-#include <rte_string_fns.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-
-#include "eal_private.h"
-
-extern struct rte_pci_bus rte_pci_bus;
-
-#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
-
-const char *pci_get_sysfs_path(void)
-{
-	const char *path = NULL;
-
-	path = getenv("SYSFS_PCI_DEVICES");
-	if (path == NULL)
-		return SYSFS_PCI_DEVICES;
-
-	return path;
-}
-
-static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_pci_addr addr;
-	struct rte_bus *pbus;
-
-	pbus = rte_bus_find_by_name("pci");
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-		if (devargs->bus != pbus)
-			continue;
-		devargs->bus->parse(devargs->name, &addr);
-		if (!rte_pci_addr_cmp(&dev->addr, &addr))
-			return devargs;
-	}
-	return NULL;
-}
-
-static inline const char *
-get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
-{
-	unsigned long val;
-	uint8_t *u8 = _u8;
-	char *end;
-
-	errno = 0;
-	val = strtoul(in, &end, 16);
-	if (errno != 0 || end[0] != dlm || val > UINT8_MAX) {
-		errno = errno ? errno : EINVAL;
-		return NULL;
-	}
-	*u8 = (uint8_t)val;
-	return end + 1;
-}
-
-
-static int
-rte_pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
-{
-	const char *in = input;
-
-	dev_addr->domain = 0;
-	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
-	if (in == NULL)
-		return -EINVAL;
-	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
-	if (in == NULL)
-		return -EINVAL;
-	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
-	if (in == NULL)
-		return -EINVAL;
-	return 0;
-}
-
-int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	return rte_pci_bdf_parse(input, dev_addr);
-}
-
-static int
-rte_pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
-{
-	const char *in = input;
-	unsigned long val;
-	char *end;
-
-	errno = 0;
-	val = strtoul(in, &end, 16);
-	if (errno != 0 || end[0] != ':' || val > UINT16_MAX)
-		return -EINVAL;
-	dev_addr->domain = (uint16_t)val;
-	in = end + 1;
-	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
-	if (in == NULL)
-		return -EINVAL;
-	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
-	if (in == NULL)
-		return -EINVAL;
-	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
-	if (in == NULL)
-		return -EINVAL;
-	return 0;
-}
-
-int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	return rte_pci_dbdf_parse(input, dev_addr);
-}
-
-void
-rte_pci_device_name(const struct rte_pci_addr *addr,
-		     char *output, size_t size)
-{
-	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
-	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
-			    addr->domain, addr->bus,
-			    addr->devid, addr->function) >= 0);
-}
-
-int
-rte_pci_addr_cmp(const struct rte_pci_addr *addr,
-		 const struct rte_pci_addr *addr2)
-{
-	uint64_t dev_addr, dev_addr2;
-
-	if ((addr == NULL) || (addr2 == NULL))
-		 return -1;
-
-	dev_addr = ((uint64_t)addr->domain << 24) |
-		 (addr->bus << 16) | (addr->devid << 8) | addr->function;
-	dev_addr2 = ((uint64_t)addr2->domain << 24) |
-		 (addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
-
-	if (dev_addr > dev_addr2)
-		 return 1;
-	else if (dev_addr < dev_addr2)
-		 return -1;
-	else
-		 return 0;
-}
-
-int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			 const struct rte_pci_addr *addr2)
-{
-	return rte_pci_addr_cmp(addr, addr2);
-}
-
-int
-rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr)
-{
-	if (rte_pci_bdf_parse(str, addr) == 0 ||
-	    rte_pci_dbdf_parse(str, addr) == 0)
-		return 0;
-	return -1;
-}
-
-void
-pci_name_set(struct rte_pci_device *dev)
-{
-	struct rte_devargs *devargs;
-
-	/* Each device has its internal, canonical name set. */
-	rte_pci_device_name(&dev->addr,
-			dev->name, sizeof(dev->name));
-	devargs = pci_devargs_lookup(dev);
-	dev->device.devargs = devargs;
-	/* In blacklist mode, if the device is not blacklisted, no
-	 * rte_devargs exists for it.
-	 */
-	if (devargs != NULL)
-		/* If an rte_devargs exists, the generic rte_device uses the
-		 * given name as its namea
-		 */
-		dev->device.name = dev->device.devargs->name;
-	else
-		/* Otherwise, it uses the internal, canonical form. */
-		dev->device.name = dev->name;
-}
-
-/* map a particular resource from a file */
-void *
-pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
-		 int additional_flags)
-{
-	void *mapaddr;
-
-	/* Map the PCI memory resource of device */
-	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
-			MAP_SHARED | additional_flags, fd, offset);
-	if (mapaddr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
-			__func__, fd, requested_addr,
-			(unsigned long)size, (unsigned long)offset,
-			strerror(errno), mapaddr);
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
-
-	return mapaddr;
-}
-
-/* unmap a particular resource */
-void
-pci_unmap_resource(void *requested_addr, size_t size)
-{
-	if (requested_addr == NULL)
-		return;
-
-	/* Unmap the PCI memory resource of device */
-	if (munmap(requested_addr, size)) {
-		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
-			__func__, requested_addr, (unsigned long)size,
-			strerror(errno));
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
-				requested_addr);
-}
-
-/*
- * Match the PCI Driver and Device using the ID Table
- */
-int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev)
-{
-	const struct rte_pci_id *id_table;
-
-	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
-	     id_table++) {
-		/* check if device's identifiers match the driver's ones */
-		if (id_table->vendor_id != pci_dev->id.vendor_id &&
-				id_table->vendor_id != PCI_ANY_ID)
-			continue;
-		if (id_table->device_id != pci_dev->id.device_id &&
-				id_table->device_id != PCI_ANY_ID)
-			continue;
-		if (id_table->subsystem_vendor_id !=
-		    pci_dev->id.subsystem_vendor_id &&
-		    id_table->subsystem_vendor_id != PCI_ANY_ID)
-			continue;
-		if (id_table->subsystem_device_id !=
-		    pci_dev->id.subsystem_device_id &&
-		    id_table->subsystem_device_id != PCI_ANY_ID)
-			continue;
-		if (id_table->class_id != pci_dev->id.class_id &&
-				id_table->class_id != RTE_CLASS_ANY_ID)
-			continue;
-
-		return 1;
-	}
-
-	return 0;
-}
-
-/*
- * If vendor/device ID match, call the probe() function of the
- * driver.
- */
-static int
-rte_pci_probe_one_driver(struct rte_pci_driver *dr,
-			 struct rte_pci_device *dev)
-{
-	int ret;
-	struct rte_pci_addr *loc;
-
-	if ((dr == NULL) || (dev == NULL))
-		return -EINVAL;
-
-	loc = &dev->addr;
-
-	/* The device is not blacklisted; Check if driver supports it */
-	if (!rte_pci_match(dr, dev))
-		/* Match of device and driver failed */
-		return 1;
-
-	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-			loc->domain, loc->bus, loc->devid, loc->function,
-			dev->device.numa_node);
-
-	/* no initialization when blacklisted, return without error */
-	if (dev->device.devargs != NULL &&
-		dev->device.devargs->policy ==
-			RTE_DEV_BLACKLISTED) {
-		RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
-			" initializing\n");
-		return 1;
-	}
-
-	if (dev->device.numa_node < 0) {
-		RTE_LOG(WARNING, EAL, "  Invalid NUMA socket, default to 0\n");
-		dev->device.numa_node = 0;
-	}
-
-	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
-		dev->id.device_id, dr->driver.name);
-
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
-		/* map resources for devices that use igb_uio */
-		ret = rte_pci_map_device(dev);
-		if (ret != 0)
-			return ret;
-	}
-
-	/* reference driver structure */
-	dev->driver = dr;
-	dev->device.driver = &dr->driver;
-
-	/* call the driver probe() function */
-	ret = dr->probe(dr, dev);
-	if (ret) {
-		dev->driver = NULL;
-		dev->device.driver = NULL;
-		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
-			/* Don't unmap if device is unsupported and
-			 * driver needs mapped resources.
-			 */
-			!(ret > 0 &&
-				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
-			rte_pci_unmap_device(dev);
-	}
-
-	return ret;
-}
-
-/*
- * If vendor/device ID match, call the remove() function of the
- * driver.
- */
-static int
-rte_pci_detach_dev(struct rte_pci_device *dev)
-{
-	struct rte_pci_addr *loc;
-	struct rte_pci_driver *dr;
-
-	if (dev == NULL)
-		return -EINVAL;
-
-	dr = dev->driver;
-	loc = &dev->addr;
-
-	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-			loc->domain, loc->bus, loc->devid,
-			loc->function, dev->device.numa_node);
-
-	RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
-			dev->id.device_id, dr->driver.name);
-
-	if (dr->remove && (dr->remove(dev) < 0))
-		return -1;	/* negative value is an error */
-
-	/* clear driver structure */
-	dev->driver = NULL;
-
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
-		/* unmap resources for devices that use igb_uio */
-		rte_pci_unmap_device(dev);
-
-	return 0;
-}
-
-/*
- * If vendor/device ID match, call the probe() function of all
- * registered driver for the given device. Return -1 if initialization
- * failed, return 1 if no driver is found for this device.
- */
-static int
-pci_probe_all_drivers(struct rte_pci_device *dev)
-{
-	struct rte_pci_driver *dr = NULL;
-	int rc = 0;
-
-	if (dev == NULL)
-		return -1;
-
-	/* Check if a driver is already loaded */
-	if (dev->driver != NULL)
-		return 0;
-
-	FOREACH_DRIVER_ON_PCIBUS(dr) {
-		rc = rte_pci_probe_one_driver(dr, dev);
-		if (rc < 0)
-			/* negative value is an error */
-			return -1;
-		if (rc > 0)
-			/* positive value means driver doesn't support it */
-			continue;
-		return 0;
-	}
-	return 1;
-}
-
-/*
- * Find the pci device specified by pci address, then invoke probe function of
- * the driver of the device.
- */
-int
-rte_pci_probe_one(const struct rte_pci_addr *addr)
-{
-	struct rte_pci_device *dev = NULL;
-
-	int ret = 0;
-
-	if (addr == NULL)
-		return -1;
-
-	/* update current pci device in global list, kernel bindings might have
-	 * changed since last time we looked at it.
-	 */
-	if (pci_update_device(addr) < 0)
-		goto err_return;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_pci_addr_cmp(&dev->addr, addr))
-			continue;
-
-		ret = pci_probe_all_drivers(dev);
-		if (ret)
-			goto err_return;
-		return 0;
-	}
-	return -1;
-
-err_return:
-	RTE_LOG(WARNING, EAL,
-		"Requested device " PCI_PRI_FMT " cannot be used\n",
-		addr->domain, addr->bus, addr->devid, addr->function);
-	return -1;
-}
-
-/*
- * Detach device specified by its pci address.
- */
-int
-rte_pci_detach(const struct rte_pci_addr *addr)
-{
-	struct rte_pci_device *dev = NULL;
-	int ret = 0;
-
-	if (addr == NULL)
-		return -1;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_pci_addr_cmp(&dev->addr, addr))
-			continue;
-
-		ret = rte_pci_detach_dev(dev);
-		if (ret < 0)
-			/* negative value is an error */
-			goto err_return;
-		if (ret > 0)
-			/* positive value means driver doesn't support it */
-			continue;
-
-		rte_pci_remove_device(dev);
-		free(dev);
-		return 0;
-	}
-	return -1;
-
-err_return:
-	RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
-			" cannot be used\n", dev->addr.domain, dev->addr.bus,
-			dev->addr.devid, dev->addr.function);
-	return -1;
-}
-
-/*
- * Scan the content of the PCI bus, and call the probe() function for
- * all registered drivers that have a matching entry in its id_table
- * for discovered devices.
- */
-int
-rte_pci_probe(void)
-{
-	struct rte_pci_device *dev = NULL;
-	size_t probed = 0, failed = 0;
-	struct rte_devargs *devargs;
-	int probe_all = 0;
-	int ret = 0;
-
-	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
-		probe_all = 1;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		probed++;
-
-		devargs = dev->device.devargs;
-		/* probe all or only whitelisted devices */
-		if (probe_all)
-			ret = pci_probe_all_drivers(dev);
-		else if (devargs != NULL &&
-			devargs->policy == RTE_DEV_WHITELISTED)
-			ret = pci_probe_all_drivers(dev);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
-				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
-				 dev->addr.devid, dev->addr.function);
-			rte_errno = errno;
-			failed++;
-			ret = 0;
-		}
-	}
-
-	return (probed && probed == failed) ? -1 : 0;
-}
-
-/* dump one device */
-static int
-pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
-{
-	int i;
-
-	fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
-	       dev->addr.devid, dev->addr.function);
-	fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
-	       dev->id.device_id);
-
-	for (i = 0; i != sizeof(dev->mem_resource) /
-		sizeof(dev->mem_resource[0]); i++) {
-		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
-			dev->mem_resource[i].phys_addr,
-			dev->mem_resource[i].len);
-	}
-	return 0;
-}
-
-/* dump devices on the bus */
-void
-rte_pci_dump(FILE *f)
-{
-	struct rte_pci_device *dev = NULL;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		pci_dump_one_device(f, dev);
-	}
-}
-
-static int
-pci_parse(const char *name, void *addr)
-{
-	struct rte_pci_addr *out = addr;
-	struct rte_pci_addr pci_addr;
-	bool parse;
-
-	parse = (rte_pci_addr_parse(name, &pci_addr) == 0);
-	if (parse && addr != NULL)
-		*out = pci_addr;
-	return parse == false;
-}
-
-/* register a driver */
-void
-rte_pci_register(struct rte_pci_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
-	driver->bus = &rte_pci_bus;
-}
-
-/* unregister a driver */
-void
-rte_pci_unregister(struct rte_pci_driver *driver)
-{
-	TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
-	driver->bus = NULL;
-}
-
-/* Add a device to PCI bus */
-void
-rte_pci_add_device(struct rte_pci_device *pci_dev)
-{
-	TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
-}
-
-/* Insert a device into a predefined position in PCI bus */
-void
-rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
-		      struct rte_pci_device *new_pci_dev)
-{
-	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
-}
-
-/* Remove a device from PCI bus */
-void
-rte_pci_remove_device(struct rte_pci_device *pci_dev)
-{
-	TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
-}
-
-static struct rte_device *
-pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		const void *data)
-{
-	struct rte_pci_device *dev;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (start && &dev->device == start) {
-			start = NULL; /* starting point found */
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-
-	return NULL;
-}
-
-static int
-pci_plug(struct rte_device *dev)
-{
-	return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
-}
-
-static int
-pci_unplug(struct rte_device *dev)
-{
-	struct rte_pci_device *pdev;
-	int ret;
-
-	pdev = RTE_DEV_TO_PCI(dev);
-	ret = rte_pci_detach_dev(pdev);
-	rte_pci_remove_device(pdev);
-	free(pdev);
-	return ret;
-}
-
-struct rte_pci_bus rte_pci_bus = {
-	.bus = {
-		.scan = rte_pci_scan,
-		.probe = rte_pci_probe,
-		.find_device = pci_find_device,
-		.plug = pci_plug,
-		.unplug = pci_unplug,
-		.parse = pci_parse,
-		.get_iommu_class = rte_pci_get_iommu_class,
-	},
-	.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
-	.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
-};
-
-RTE_REGISTER_BUS(pci, rte_pci_bus.bus);
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
deleted file mode 100644
index 9df3833..0000000
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include <rte_eal.h>
-#include <rte_tailq.h>
-#include <rte_log.h>
-#include <rte_malloc.h>
-
-#include "eal_private.h"
-
-static struct rte_tailq_elem rte_uio_tailq = {
-	.name = "UIO_RESOURCE_LIST",
-};
-EAL_REGISTER_TAILQ(rte_uio_tailq)
-
-static int
-pci_uio_map_secondary(struct rte_pci_device *dev)
-{
-	int fd, i, j;
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	TAILQ_FOREACH(uio_res, uio_res_list, next) {
-
-		/* skip this element if it doesn't match our PCI address */
-		if (rte_pci_addr_cmp(&uio_res->pci_addr, &dev->addr))
-			continue;
-
-		for (i = 0; i != uio_res->nb_maps; i++) {
-			/*
-			 * open devname, to mmap it
-			 */
-			fd = open(uio_res->maps[i].path, O_RDWR);
-			if (fd < 0) {
-				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-					uio_res->maps[i].path, strerror(errno));
-				return -1;
-			}
-
-			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
-					fd, (off_t)uio_res->maps[i].offset,
-					(size_t)uio_res->maps[i].size, 0);
-			/* fd is not needed in slave process, close it */
-			close(fd);
-			if (mapaddr != uio_res->maps[i].addr) {
-				RTE_LOG(ERR, EAL,
-					"Cannot mmap device resource file %s to address: %p\n",
-					uio_res->maps[i].path,
-					uio_res->maps[i].addr);
-				if (mapaddr != MAP_FAILED) {
-					/* unmap addrs correctly mapped */
-					for (j = 0; j < i; j++)
-						pci_unmap_resource(
-							uio_res->maps[j].addr,
-							(size_t)uio_res->maps[j].size);
-					/* unmap addr wrongly mapped */
-					pci_unmap_resource(mapaddr,
-						(size_t)uio_res->maps[i].size);
-				}
-				return -1;
-			}
-		}
-		return 0;
-	}
-
-	RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
-	return 1;
-}
-
-/* map the PCI resource of a PCI device in virtual memory */
-int
-pci_uio_map_resource(struct rte_pci_device *dev)
-{
-	int i, map_idx = 0, ret;
-	uint64_t phaddr;
-	struct mapped_pci_resource *uio_res = NULL;
-	struct mapped_pci_res_list *uio_res_list =
-		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.uio_cfg_fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* secondary processes - use already recorded details */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return pci_uio_map_secondary(dev);
-
-	/* allocate uio resource */
-	ret = pci_uio_alloc_resource(dev, &uio_res);
-	if (ret)
-		return ret;
-
-	/* Map all BARs */
-	for (i = 0; i != PCI_MAX_RESOURCE; i++) {
-		/* skip empty BAR */
-		phaddr = dev->mem_resource[i].phys_addr;
-		if (phaddr == 0)
-			continue;
-
-		ret = pci_uio_map_resource_by_index(dev, i,
-				uio_res, map_idx);
-		if (ret)
-			goto error;
-
-		map_idx++;
-	}
-
-	uio_res->nb_maps = map_idx;
-
-	TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
-
-	return 0;
-error:
-	for (i = 0; i < map_idx; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
-				(size_t)uio_res->maps[i].size);
-		rte_free(uio_res->maps[i].path);
-	}
-	pci_uio_free_resource(dev, uio_res);
-	return -1;
-}
-
-static void
-pci_uio_unmap(struct mapped_pci_resource *uio_res)
-{
-	int i;
-
-	if (uio_res == NULL)
-		return;
-
-	for (i = 0; i != uio_res->nb_maps; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
-				(size_t)uio_res->maps[i].size);
-		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-			rte_free(uio_res->maps[i].path);
-	}
-}
-
-static struct mapped_pci_resource *
-pci_uio_find_resource(struct rte_pci_device *dev)
-{
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	if (dev == NULL)
-		return NULL;
-
-	TAILQ_FOREACH(uio_res, uio_res_list, next) {
-
-		/* skip this element if it doesn't match our PCI address */
-		if (!rte_pci_addr_cmp(&uio_res->pci_addr, &dev->addr))
-			return uio_res;
-	}
-	return NULL;
-}
-
-/* unmap the PCI resource of a PCI device in virtual memory */
-void
-pci_uio_unmap_resource(struct rte_pci_device *dev)
-{
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	if (dev == NULL)
-		return;
-
-	/* find an entry for the device */
-	uio_res = pci_uio_find_resource(dev);
-	if (uio_res == NULL)
-		return;
-
-	/* secondary processes - just free maps */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return pci_uio_unmap(uio_res);
-
-	TAILQ_REMOVE(uio_res_list, uio_res, next);
-
-	/* unmap all resources */
-	pci_uio_unmap(uio_res);
-
-	/* free uio resource */
-	rte_free(uio_res);
-
-	/* close fd if in primary process */
-	close(dev->intr_handle.fd);
-	if (dev->intr_handle.uio_cfg_fd >= 0) {
-		close(dev->intr_handle.uio_cfg_fd);
-		dev->intr_handle.uio_cfg_fd = -1;
-	}
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 4eb1bd2..462226f 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -37,7 +37,6 @@
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
-#include <rte_pci.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -110,211 +109,6 @@ int rte_eal_timer_init(void);
  */
 int rte_eal_log_init(const char *id, int facility);
 
-struct rte_pci_driver;
-struct rte_pci_device;
-
-/**
- * Probe the PCI bus
- *
- * @return
- *   - 0 on success.
- *   - !0 on error.
- */
-int
-rte_pci_probe(void);
-
-/**
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- *
- * @return
- *  0 on success, negative on error
- */
-int rte_pci_scan(void);
-
-/**
- * Probe the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the probe() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *     The PCI Bus-Device-Function address to probe.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_probe_one(const struct rte_pci_addr *addr);
-
-/**
- * Close the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the remove() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *     The PCI Bus-Device-Function address to close.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_detach(const struct rte_pci_addr *addr);
-
-/**
- * Find the name of a PCI device.
- */
-void pci_name_set(struct rte_pci_device *dev);
-
-/**
- * Add a PCI device to the PCI Bus (append to PCI Device list). This function
- * also updates the bus references of the PCI Device (and the generic device
- * object embedded within.
- *
- * @param pci_dev
- *	PCI device to add
- * @return void
- */
-void rte_pci_add_device(struct rte_pci_device *pci_dev);
-
-/**
- * Insert a PCI device in the PCI Bus at a particular location in the device
- * list. It also updates the PCI Bus reference of the new devices to be
- * inserted.
- *
- * @param exist_pci_dev
- *	Existing PCI device in PCI Bus
- * @param new_pci_dev
- *	PCI device to be added before exist_pci_dev
- * @return void
- */
-void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
-		struct rte_pci_device *new_pci_dev);
-
-/**
- * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
- * in the PCI device object as well as the generic device object.
- *
- * @param pci_device
- *	PCI device to be removed from PCI Bus
- * @return void
- */
-void rte_pci_remove_device(struct rte_pci_device *pci_device);
-
-/**
- * Update a pci device object by asking the kernel for the latest information.
- *
- * This function is private to EAL.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to look for
- * @return
- *   - 0 on success.
- *   - negative on error.
- */
-int pci_update_device(const struct rte_pci_addr *addr);
-
-/**
- * Unbind kernel driver for this device
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int pci_unbind_kernel_driver(struct rte_pci_device *dev);
-
-/**
- * Map the PCI resource of a PCI device in virtual memory
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_map_resource(struct rte_pci_device *dev);
-
-/**
- * Unmap the PCI resource of a PCI device
- *
- * This function is private to EAL.
- */
-void pci_uio_unmap_resource(struct rte_pci_device *dev);
-
-/**
- * Allocate uio resource for PCI device
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device to allocate uio resource
- * @param uio_res
- *   Pointer to uio resource.
- *   If the function returns 0, the pointer will be filled.
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res);
-
-/**
- * Free uio resource for PCI device
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device to free uio resource
- * @param uio_res
- *   Pointer to uio resource.
- */
-void pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res);
-
-/**
- * Map device memory to uio resource
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device that has memory information.
- * @param res_idx
- *   Memory resource index of the PCI device.
- * @param uio_res
- *  uio resource that will keep mapping information.
- * @param map_idx
- *   Mapping information index of the uio resource.
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx);
-
-/*
- * Match the PCI Driver and Device using the ID Table
- *
- * @param pci_drv
- *      PCI driver from which ID table would be extracted
- * @param pci_dev
- *      PCI device to match against the driver
- * @return
- *      1 for successful match
- *      0 for unsuccessful match
- */
-int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev);
-
-/**
- * Get iommu class of PCI devices on the bus.
- * And return their preferred iova mapping mode.
- *
- * @return
- *   - enum rte_iova_mode.
- */
-enum rte_iova_mode
-rte_pci_get_iommu_class(void);
-
 /**
  * Init tail queues for non-EAL library structures. This is to allow
  * the rings, mempools, etc. lists to be shared among multiple processes
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
deleted file mode 100644
index 3c8cbd8..0000000
--- a/lib/librte_eal/common/include/rte_pci.h
+++ /dev/null
@@ -1,533 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   Copyright 2013-2014 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_PCI_H_
-#define _RTE_PCI_H_
-
-/**
- * @file
- *
- * RTE PCI Interface
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <errno.h>
-#include <sys/queue.h>
-#include <stdint.h>
-#include <inttypes.h>
-
-#include <rte_debug.h>
-#include <rte_interrupts.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-
-/** Pathname of PCI devices directory. */
-const char *pci_get_sysfs_path(void);
-
-/** Formatting string for PCI device identifier: Ex: 0000:00:01.0 */
-#define PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
-#define PCI_PRI_STR_SIZE sizeof("XXXXXXXX:XX:XX.X")
-
-/** Short formatting string, without domain, for PCI device: Ex: 00:01.0 */
-#define PCI_SHORT_PRI_FMT "%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
-
-/** Nb. of values in PCI device identifier format string. */
-#define PCI_FMT_NVAL 4
-
-/** Nb. of values in PCI resource format. */
-#define PCI_RESOURCE_FMT_NVAL 3
-
-/** Maximum number of PCI resources. */
-#define PCI_MAX_RESOURCE 6
-
-/* Forward declarations */
-struct rte_pci_device;
-struct rte_pci_driver;
-
-/** List of PCI devices */
-TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
-/** List of PCI drivers */
-TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
-
-/* PCI Bus iterators */
-#define FOREACH_DEVICE_ON_PCIBUS(p)	\
-		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
-
-#define FOREACH_DRIVER_ON_PCIBUS(p)	\
-		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
-
-/**
- * A structure describing an ID for a PCI driver. Each driver provides a
- * table of these IDs for each device that it supports.
- */
-struct rte_pci_id {
-	uint32_t class_id;            /**< Class ID (class, subclass, pi) or RTE_CLASS_ANY_ID. */
-	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
-	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
-	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
-	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
-};
-
-/**
- * A structure describing the location of a PCI device.
- */
-struct rte_pci_addr {
-	uint32_t domain;                /**< Device domain */
-	uint8_t bus;                    /**< Device bus */
-	uint8_t devid;                  /**< Device ID */
-	uint8_t function;               /**< Device function. */
-};
-
-struct rte_devargs;
-
-/**
- * A structure describing a PCI device.
- */
-struct rte_pci_device {
-	TAILQ_ENTRY(rte_pci_device) next;       /**< Next probed PCI device. */
-	struct rte_device device;               /**< Inherit core device */
-	struct rte_pci_addr addr;               /**< PCI location. */
-	struct rte_pci_id id;                   /**< PCI ID. */
-	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
-						/**< PCI Memory Resource */
-	struct rte_intr_handle intr_handle;     /**< Interrupt handle */
-	struct rte_pci_driver *driver;          /**< Associated driver */
-	uint16_t max_vfs;                       /**< sriov enable if not zero */
-	enum rte_kernel_driver kdrv;            /**< Kernel driver passthrough */
-	char name[PCI_PRI_STR_SIZE+1];          /**< PCI location (ASCII) */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_pci_device.
- */
-#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
-
-/** Any PCI device identifier (vendor, device, ...) */
-#define PCI_ANY_ID (0xffff)
-#define RTE_CLASS_ANY_ID (0xffffff)
-
-#ifdef __cplusplus
-/** C++ macro used to help building up tables of device IDs */
-#define RTE_PCI_DEVICE(vend, dev) \
-	RTE_CLASS_ANY_ID,         \
-	(vend),                   \
-	(dev),                    \
-	PCI_ANY_ID,               \
-	PCI_ANY_ID
-#else
-/** Macro used to help building up tables of device IDs */
-#define RTE_PCI_DEVICE(vend, dev)          \
-	.class_id = RTE_CLASS_ANY_ID,      \
-	.vendor_id = (vend),               \
-	.device_id = (dev),                \
-	.subsystem_vendor_id = PCI_ANY_ID, \
-	.subsystem_device_id = PCI_ANY_ID
-#endif
-
-/**
- * Initialisation function for the driver called during PCI probing.
- */
-typedef int (pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
-
-/**
- * Uninitialisation function for the driver called during hotplugging.
- */
-typedef int (pci_remove_t)(struct rte_pci_device *);
-
-/**
- * A structure describing a PCI driver.
- */
-struct rte_pci_driver {
-	TAILQ_ENTRY(rte_pci_driver) next;       /**< Next in list. */
-	struct rte_driver driver;               /**< Inherit core driver. */
-	struct rte_pci_bus *bus;                /**< PCI bus reference. */
-	pci_probe_t *probe;                     /**< Device Probe function. */
-	pci_remove_t *remove;                   /**< Device Remove function. */
-	const struct rte_pci_id *id_table;	/**< ID table, NULL terminated. */
-	uint32_t drv_flags;                     /**< Flags contolling handling of device. */
-};
-
-/**
- * Structure describing the PCI bus
- */
-struct rte_pci_bus {
-	struct rte_bus bus;               /**< Inherit the generic class */
-	struct rte_pci_device_list device_list;  /**< List of PCI devices */
-	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
-};
-
-/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
-#define RTE_PCI_DRV_NEED_MAPPING 0x0001
-/** Device driver supports link state interrupt */
-#define RTE_PCI_DRV_INTR_LSC	0x0008
-/** Device driver supports device removal interrupt */
-#define RTE_PCI_DRV_INTR_RMV 0x0010
-/** Device driver needs to keep mapped resources if unsupported dev detected */
-#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
-/** Device driver supports IOVA as VA */
-#define RTE_PCI_DRV_IOVA_AS_VA 0X0040
-
-/**
- * A structure describing a PCI mapping.
- */
-struct pci_map {
-	void *addr;
-	char *path;
-	uint64_t offset;
-	uint64_t size;
-	uint64_t phaddr;
-};
-
-struct pci_msix_table {
-	int bar_index;
-	uint32_t offset;
-	uint32_t size;
-};
-
-/**
- * A structure describing a mapped PCI resource.
- * For multi-process we need to reproduce all PCI mappings in secondary
- * processes, so save them in a tailq.
- */
-struct mapped_pci_resource {
-	TAILQ_ENTRY(mapped_pci_resource) next;
-
-	struct rte_pci_addr pci_addr;
-	char path[PATH_MAX];
-	int nb_maps;
-	struct pci_map maps[PCI_MAX_RESOURCE];
-	struct pci_msix_table msix_table;
-};
-
-/** mapped pci device list */
-TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
-
-/**
- * @deprecated
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided without
- * a domain prefix (i.e. domain returned is always 0)
- *
- * @param input
- *	The input string to be parsed. Should have the format XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned. Domain will always be
- *	returned as 0
- * @return
- *  0 on success, negative on error.
- */
-int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
-
-/**
- * @deprecated
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided including
- * a domain prefix.
- *
- * @param input
- *	The input string to be parsed. Should have the format XXXX:XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned
- * @return
- *  0 on success, negative on error.
- */
-int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
-
-/**
- * Utility function to write a pci device name, this device name can later be
- * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
- * BDF helpers.
- *
- * @param addr
- *	The PCI Bus-Device-Function address
- * @param output
- *	The output buffer string
- * @param size
- *	The output buffer size
- */
-void rte_pci_device_name(const struct rte_pci_addr *addr, char *output,
-			 size_t size);
-
-/**
- * Utility function to compare two PCI device addresses.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to compare
- * @param addr2
- *	The PCI Bus-Device-Function address to compare
- * @return
- *	0 on equal PCI address.
- *	Positive on addr is greater than addr2.
- *	Negative on addr is less than addr2, or error.
- */
-int rte_pci_addr_cmp(const struct rte_pci_addr *addr,
-		     const struct rte_pci_addr *addr2);
-
-/**
- * @deprecated
- * Utility function to compare two PCI device addresses.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to compare
- * @param addr2
- *	The PCI Bus-Device-Function address to compare
- * @return
- *	0 on equal PCI address.
- *	Positive on addr is greater than addr2.
- *	Negative on addr is less than addr2, or error.
- */
-int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			     const struct rte_pci_addr *addr2);
-
-/**
- * Utility function to parse a string into a PCI location.
- *
- * @param str
- *     The string to parse
- * @param addr
- *     The reference to the structure where the location
- *     is stored.
- * @return
- *     0 on success
- *     <0 otherwise
- */
-int rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr);
-
-/**
- * Map the PCI device resources in user space virtual memory address
- *
- * Note that driver should not call this function when flag
- * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for
- * you when it's on.
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- *
- * @return
- *   0 on success, negative on error and positive if no driver
- *   is found for the device.
- */
-int rte_pci_map_device(struct rte_pci_device *dev);
-
-/**
- * Unmap this device
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- */
-void rte_pci_unmap_device(struct rte_pci_device *dev);
-
-/**
- * @internal
- * Map a particular resource from a file.
- *
- * @param requested_addr
- *      The starting address for the new mapping range.
- * @param fd
- *      The file descriptor.
- * @param offset
- *      The offset for the mapping range.
- * @param size
- *      The size for the mapping range.
- * @param additional_flags
- *      The additional flags for the mapping range.
- * @return
- *   - On success, the function returns a pointer to the mapped area.
- *   - On error, the value MAP_FAILED is returned.
- */
-void *pci_map_resource(void *requested_addr, int fd, off_t offset,
-		size_t size, int additional_flags);
-
-/**
- * @internal
- * Unmap a particular resource.
- *
- * @param requested_addr
- *      The address for the unmapping range.
- * @param size
- *      The size for the unmapping range.
- */
-void pci_unmap_resource(void *requested_addr, size_t size);
-
-/**
- * Dump the content of the PCI bus.
- *
- * @param f
- *   A pointer to a file for output
- */
-void rte_pci_dump(FILE *f);
-
-/**
- * Register a PCI driver.
- *
- * @param driver
- *   A pointer to a rte_pci_driver structure describing the driver
- *   to be registered.
- */
-void rte_pci_register(struct rte_pci_driver *driver);
-
-/** Helper for PCI device registration from driver (eth, crypto) instance */
-#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
-RTE_INIT(pciinitfn_ ##nm); \
-static void pciinitfn_ ##nm(void) \
-{\
-	(pci_drv).driver.name = RTE_STR(nm);\
-	rte_pci_register(&pci_drv); \
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-/**
- * Unregister a PCI driver.
- *
- * @param driver
- *   A pointer to a rte_pci_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_pci_unregister(struct rte_pci_driver *driver);
-
-/**
- * Read PCI config space.
- *
- * @param device
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- * @param buf
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into PCI config space
- */
-int rte_pci_read_config(const struct rte_pci_device *device,
-		void *buf, size_t len, off_t offset);
-
-/**
- * Write PCI config space.
- *
- * @param device
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- * @param buf
- *   A data buffer containing the bytes should be written
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into PCI config space
- */
-int rte_pci_write_config(const struct rte_pci_device *device,
-		const void *buf, size_t len, off_t offset);
-
-/**
- * A structure used to access io resources for a pci device.
- * rte_pci_ioport is arch, os, driver specific, and should not be used outside
- * of pci ioport api.
- */
-struct rte_pci_ioport {
-	struct rte_pci_device *dev;
-	uint64_t base;
-	uint64_t len; /* only filled for memory mapped ports */
-};
-
-/**
- * Initialize a rte_pci_ioport object for a pci device io resource.
- *
- * This object is then used to gain access to those io resources (see below).
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use.
- * @param bar
- *   Index of the io pci resource we want to access.
- * @param p
- *   The rte_pci_ioport object to be initialized.
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p);
-
-/**
- * Release any resources used in a rte_pci_ioport object.
- *
- * @param p
- *   The rte_pci_ioport object to be uninitialized.
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_ioport_unmap(struct rte_pci_ioport *p);
-
-/**
- * Read from a io pci resource.
- *
- * @param p
- *   The rte_pci_ioport object from which we want to read.
- * @param data
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into the pci io resource.
- */
-void rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset);
-
-/**
- * Write to a io pci resource.
- *
- * @param p
- *   The rte_pci_ioport object to which we want to write.
- * @param data
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into the pci io resource.
- */
-void rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RTE_PCI_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 965da6e..cbe844c 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -62,9 +62,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
@@ -78,8 +75,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_errno.c
@@ -132,9 +127,6 @@ CFLAGS_eal_thread.o := -D_GNU_SOURCE
 CFLAGS_eal_log.o := -D_GNU_SOURCE
 CFLAGS_eal_common_log.o := -D_GNU_SOURCE
 CFLAGS_eal_hugepage_info.o := -D_GNU_SOURCE
-CFLAGS_eal_pci.o := -D_GNU_SOURCE
-CFLAGS_eal_pci_uio.o := -D_GNU_SOURCE
-CFLAGS_eal_pci_vfio.o := -D_GNU_SOURCE
 CFLAGS_eal_common_whitelist.o := -D_GNU_SOURCE
 CFLAGS_eal_common_options.o := -D_GNU_SOURCE
 CFLAGS_eal_common_thread.o := -D_GNU_SOURCE
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 91c3712..017c402 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -71,7 +71,6 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_bus.h>
-#include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_version.h>
diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
index 6df63d4..cdd74ee 100644
--- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
@@ -60,7 +60,6 @@
 #include <rte_branch_prediction.h>
 #include <rte_debug.h>
 #include <rte_log.h>
-#include <rte_pci.h>
 #include <rte_malloc.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
deleted file mode 100644
index cee4b94..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ /dev/null
@@ -1,823 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <dirent.h>
-
-#include <rte_log.h>
-#include <rte_bus.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-#include <rte_devargs.h>
-#include <rte_memcpy.h>
-#include <rte_vfio.h>
-
-#include "eal_filesystem.h"
-#include "eal_private.h"
-#include "eal_pci_init.h"
-
-/**
- * @file
- * PCI probing under linux
- *
- * This code is used to simulate a PCI probe by parsing information in sysfs.
- * When a registered device matches a driver, it is then initialized with
- * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
- */
-
-extern struct rte_pci_bus rte_pci_bus;
-
-static int
-pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
-{
-	int count;
-	char path[PATH_MAX];
-	char *name;
-
-	if (!filename || !dri_name)
-		return -1;
-
-	count = readlink(filename, path, PATH_MAX);
-	if (count >= PATH_MAX)
-		return -1;
-
-	/* For device does not have a driver */
-	if (count < 0)
-		return 1;
-
-	path[count] = '\0';
-
-	name = strrchr(path, '/');
-	if (name) {
-		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
-		return 0;
-	}
-
-	return -1;
-}
-
-/* Map pci device */
-int
-rte_pci_map_device(struct rte_pci_device *dev)
-{
-	int ret = -1;
-
-	/* try mapping the NIC resources using VFIO if it exists */
-	switch (dev->kdrv) {
-	case RTE_KDRV_VFIO:
-#ifdef VFIO_PRESENT
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_map_resource(dev);
-#endif
-		break;
-	case RTE_KDRV_IGB_UIO:
-	case RTE_KDRV_UIO_GENERIC:
-		if (rte_eal_using_phys_addrs()) {
-			/* map resources for devices that use uio */
-			ret = pci_uio_map_resource(dev);
-		}
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		ret = 1;
-		break;
-	}
-
-	return ret;
-}
-
-/* Unmap pci device */
-void
-rte_pci_unmap_device(struct rte_pci_device *dev)
-{
-	/* try unmapping the NIC resources using VFIO if it exists */
-	switch (dev->kdrv) {
-	case RTE_KDRV_VFIO:
-#ifdef VFIO_PRESENT
-		if (pci_vfio_is_enabled())
-			pci_vfio_unmap_resource(dev);
-#endif
-		break;
-	case RTE_KDRV_IGB_UIO:
-	case RTE_KDRV_UIO_GENERIC:
-		/* unmap resources for devices that use uio */
-		pci_uio_unmap_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		break;
-	}
-}
-
-void *
-pci_find_max_end_va(void)
-{
-	const struct rte_memseg *seg = rte_eal_get_physmem_layout();
-	const struct rte_memseg *last = seg;
-	unsigned i = 0;
-
-	for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
-		if (seg->addr == NULL)
-			break;
-
-		if (seg->addr > last->addr)
-			last = seg;
-
-	}
-	return RTE_PTR_ADD(last->addr, last->len);
-}
-
-/* parse one line of the "resource" sysfs file (note that the 'line'
- * string is modified)
- */
-int
-pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
-	uint64_t *end_addr, uint64_t *flags)
-{
-	union pci_resource_info {
-		struct {
-			char *phys_addr;
-			char *end_addr;
-			char *flags;
-		};
-		char *ptrs[PCI_RESOURCE_FMT_NVAL];
-	} res_info;
-
-	if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
-		RTE_LOG(ERR, EAL,
-			"%s(): bad resource format\n", __func__);
-		return -1;
-	}
-	errno = 0;
-	*phys_addr = strtoull(res_info.phys_addr, NULL, 16);
-	*end_addr = strtoull(res_info.end_addr, NULL, 16);
-	*flags = strtoull(res_info.flags, NULL, 16);
-	if (errno != 0) {
-		RTE_LOG(ERR, EAL,
-			"%s(): bad resource format\n", __func__);
-		return -1;
-	}
-
-	return 0;
-}
-
-/* parse the "resource" sysfs file */
-static int
-pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
-{
-	FILE *f;
-	char buf[BUFSIZ];
-	int i;
-	uint64_t phys_addr, end_addr, flags;
-
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
-		return -1;
-	}
-
-	for (i = 0; i<PCI_MAX_RESOURCE; i++) {
-
-		if (fgets(buf, sizeof(buf), f) == NULL) {
-			RTE_LOG(ERR, EAL,
-				"%s(): cannot read resource\n", __func__);
-			goto error;
-		}
-		if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
-				&end_addr, &flags) < 0)
-			goto error;
-
-		if (flags & IORESOURCE_MEM) {
-			dev->mem_resource[i].phys_addr = phys_addr;
-			dev->mem_resource[i].len = end_addr - phys_addr + 1;
-			/* not mapped for now */
-			dev->mem_resource[i].addr = NULL;
-		}
-	}
-	fclose(f);
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
-}
-
-/* Scan one pci sysfs entry, and fill the devices list from it. */
-static int
-pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
-{
-	char filename[PATH_MAX];
-	unsigned long tmp;
-	struct rte_pci_device *dev;
-	char driver[PATH_MAX];
-	int ret;
-
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL)
-		return -1;
-
-	memset(dev, 0, sizeof(*dev));
-	dev->addr = *addr;
-
-	/* get vendor id */
-	snprintf(filename, sizeof(filename), "%s/vendor", dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.vendor_id = (uint16_t)tmp;
-
-	/* get device id */
-	snprintf(filename, sizeof(filename), "%s/device", dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.device_id = (uint16_t)tmp;
-
-	/* get subsystem_vendor id */
-	snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.subsystem_vendor_id = (uint16_t)tmp;
-
-	/* get subsystem_device id */
-	snprintf(filename, sizeof(filename), "%s/subsystem_device",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.subsystem_device_id = (uint16_t)tmp;
-
-	/* get class_id */
-	snprintf(filename, sizeof(filename), "%s/class",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	/* the least 24 bits are valid: class, subclass, program interface */
-	dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
-
-	/* get max_vfs */
-	dev->max_vfs = 0;
-	snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
-	if (!access(filename, F_OK) &&
-	    eal_parse_sysfs_value(filename, &tmp) == 0)
-		dev->max_vfs = (uint16_t)tmp;
-	else {
-		/* for non igb_uio driver, need kernel version >= 3.8 */
-		snprintf(filename, sizeof(filename),
-			 "%s/sriov_numvfs", dirname);
-		if (!access(filename, F_OK) &&
-		    eal_parse_sysfs_value(filename, &tmp) == 0)
-			dev->max_vfs = (uint16_t)tmp;
-	}
-
-	/* get numa node, default to 0 if not present */
-	snprintf(filename, sizeof(filename), "%s/numa_node",
-		 dirname);
-
-	if (access(filename, F_OK) != -1) {
-		if (eal_parse_sysfs_value(filename, &tmp) == 0)
-			dev->device.numa_node = tmp;
-		else
-			dev->device.numa_node = -1;
-	} else {
-		dev->device.numa_node = 0;
-	}
-
-	pci_name_set(dev);
-
-	/* parse resources */
-	snprintf(filename, sizeof(filename), "%s/resource", dirname);
-	if (pci_parse_sysfs_resource(filename, dev) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
-		free(dev);
-		return -1;
-	}
-
-	/* parse driver */
-	snprintf(filename, sizeof(filename), "%s/driver", dirname);
-	ret = pci_get_kernel_driver_by_path(filename, driver);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
-		free(dev);
-		return -1;
-	}
-
-	if (!ret) {
-		if (!strcmp(driver, "vfio-pci"))
-			dev->kdrv = RTE_KDRV_VFIO;
-		else if (!strcmp(driver, "igb_uio"))
-			dev->kdrv = RTE_KDRV_IGB_UIO;
-		else if (!strcmp(driver, "uio_pci_generic"))
-			dev->kdrv = RTE_KDRV_UIO_GENERIC;
-		else
-			dev->kdrv = RTE_KDRV_UNKNOWN;
-	} else
-		dev->kdrv = RTE_KDRV_NONE;
-
-	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-		rte_pci_add_device(dev);
-	} else {
-		struct rte_pci_device *dev2;
-		int ret;
-
-		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr);
-			if (ret > 0)
-				continue;
-
-			if (ret < 0) {
-				rte_pci_insert_device(dev2, dev);
-			} else { /* already registered */
-				dev2->kdrv = dev->kdrv;
-				dev2->max_vfs = dev->max_vfs;
-				pci_name_set(dev2);
-				memmove(dev2->mem_resource, dev->mem_resource,
-					sizeof(dev->mem_resource));
-				free(dev);
-			}
-			return 0;
-		}
-
-		rte_pci_add_device(dev);
-	}
-
-	return 0;
-}
-
-int
-pci_update_device(const struct rte_pci_addr *addr)
-{
-	char filename[PATH_MAX];
-
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
-		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
-		 addr->function);
-
-	return pci_scan_one(filename, addr);
-}
-
-/*
- * split up a pci address into its constituent parts.
- */
-static int
-parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
-{
-	/* first split on ':' */
-	union splitaddr {
-		struct {
-			char *domain;
-			char *bus;
-			char *devid;
-			char *function;
-		};
-		char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
-	} splitaddr;
-
-	char *buf_copy = strndup(buf, bufsize);
-	if (buf_copy == NULL)
-		return -1;
-
-	if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
-			!= PCI_FMT_NVAL - 1)
-		goto error;
-	/* final split is on '.' between devid and function */
-	splitaddr.function = strchr(splitaddr.devid,'.');
-	if (splitaddr.function == NULL)
-		goto error;
-	*splitaddr.function++ = '\0';
-
-	/* now convert to int values */
-	errno = 0;
-	addr->domain = strtoul(splitaddr.domain, NULL, 16);
-	addr->bus = strtoul(splitaddr.bus, NULL, 16);
-	addr->devid = strtoul(splitaddr.devid, NULL, 16);
-	addr->function = strtoul(splitaddr.function, NULL, 10);
-	if (errno != 0)
-		goto error;
-
-	free(buf_copy); /* free the copy made with strdup */
-	return 0;
-error:
-	free(buf_copy);
-	return -1;
-}
-
-/*
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- */
-int
-rte_pci_scan(void)
-{
-	struct dirent *e;
-	DIR *dir;
-	char dirname[PATH_MAX];
-	struct rte_pci_addr addr;
-
-	/* for debug purposes, PCI can be disabled */
-	if (!rte_eal_has_pci())
-		return 0;
-
-#ifdef VFIO_PRESENT
-	if (!pci_vfio_is_enabled())
-		RTE_LOG(DEBUG, EAL, "VFIO PCI modules not loaded\n");
-#endif
-
-	dir = opendir(pci_get_sysfs_path());
-	if (dir == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
-			__func__, strerror(errno));
-		return -1;
-	}
-
-	while ((e = readdir(dir)) != NULL) {
-		if (e->d_name[0] == '.')
-			continue;
-
-		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
-			continue;
-
-		snprintf(dirname, sizeof(dirname), "%s/%s",
-				pci_get_sysfs_path(), e->d_name);
-
-		if (pci_scan_one(dirname, &addr) < 0)
-			goto error;
-	}
-	closedir(dir);
-	return 0;
-
-error:
-	closedir(dir);
-	return -1;
-}
-
-/*
- * Is pci device bound to any kdrv
- */
-static inline int
-pci_one_device_is_bound(void)
-{
-	struct rte_pci_device *dev = NULL;
-	int ret = 0;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (dev->kdrv == RTE_KDRV_UNKNOWN ||
-		    dev->kdrv == RTE_KDRV_NONE) {
-			continue;
-		} else {
-			ret = 1;
-			break;
-		}
-	}
-	return ret;
-}
-
-/*
- * Any one of the device bound to uio
- */
-static inline int
-pci_one_device_bound_uio(void)
-{
-	struct rte_pci_device *dev = NULL;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (dev->kdrv == RTE_KDRV_IGB_UIO ||
-		   dev->kdrv == RTE_KDRV_UIO_GENERIC) {
-			return 1;
-		}
-	}
-	return 0;
-}
-
-/*
- * Any one of the device has iova as va
- */
-static inline int
-pci_one_device_has_iova_va(void)
-{
-	struct rte_pci_device *dev = NULL;
-	struct rte_pci_driver *drv = NULL;
-
-	FOREACH_DRIVER_ON_PCIBUS(drv) {
-		if (drv && drv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) {
-			FOREACH_DEVICE_ON_PCIBUS(dev) {
-				if (dev->kdrv == RTE_KDRV_VFIO &&
-				    rte_pci_match(drv, dev))
-					return 1;
-			}
-		}
-	}
-	return 0;
-}
-
-/*
- * Get iommu class of PCI devices on the bus.
- */
-enum rte_iova_mode
-rte_pci_get_iommu_class(void)
-{
-	bool is_bound;
-	bool is_vfio_noiommu_enabled = true;
-	bool has_iova_va;
-	bool is_bound_uio;
-
-	is_bound = pci_one_device_is_bound();
-	if (!is_bound)
-		return RTE_IOVA_DC;
-
-	has_iova_va = pci_one_device_has_iova_va();
-	is_bound_uio = pci_one_device_bound_uio();
-#ifdef VFIO_PRESENT
-	is_vfio_noiommu_enabled = vfio_noiommu_is_enabled() == true ?
-					true : false;
-#endif
-
-	if (has_iova_va && !is_bound_uio && !is_vfio_noiommu_enabled)
-		return RTE_IOVA_VA;
-
-	if (has_iova_va) {
-		RTE_LOG(WARNING, EAL, "Some devices want iova as va but pa will be used because.. ");
-		if (is_vfio_noiommu_enabled)
-			RTE_LOG(WARNING, EAL, "vfio-noiommu mode configured\n");
-		if (is_bound_uio)
-			RTE_LOG(WARNING, EAL, "few device bound to UIO\n");
-	}
-
-	return RTE_IOVA_PA;
-}
-
-/* Read PCI config space. */
-int rte_pci_read_config(const struct rte_pci_device *device,
-		void *buf, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &device->intr_handle;
-
-	switch (intr_handle->type) {
-	case RTE_INTR_HANDLE_UIO:
-	case RTE_INTR_HANDLE_UIO_INTX:
-		return pci_uio_read_config(intr_handle, buf, len, offset);
-
-#ifdef VFIO_PRESENT
-	case RTE_INTR_HANDLE_VFIO_MSIX:
-	case RTE_INTR_HANDLE_VFIO_MSI:
-	case RTE_INTR_HANDLE_VFIO_LEGACY:
-		return pci_vfio_read_config(intr_handle, buf, len, offset);
-#endif
-	default:
-		RTE_LOG(ERR, EAL,
-			"Unknown handle type of fd %d\n",
-					intr_handle->fd);
-		return -1;
-	}
-}
-
-/* Write PCI config space. */
-int rte_pci_write_config(const struct rte_pci_device *device,
-		const void *buf, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &device->intr_handle;
-
-	switch (intr_handle->type) {
-	case RTE_INTR_HANDLE_UIO:
-	case RTE_INTR_HANDLE_UIO_INTX:
-		return pci_uio_write_config(intr_handle, buf, len, offset);
-
-#ifdef VFIO_PRESENT
-	case RTE_INTR_HANDLE_VFIO_MSIX:
-	case RTE_INTR_HANDLE_VFIO_MSI:
-	case RTE_INTR_HANDLE_VFIO_LEGACY:
-		return pci_vfio_write_config(intr_handle, buf, len, offset);
-#endif
-	default:
-		RTE_LOG(ERR, EAL,
-			"Unknown handle type of fd %d\n",
-					intr_handle->fd);
-		return -1;
-	}
-}
-
-#if defined(RTE_ARCH_X86)
-static int
-pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
-		struct rte_pci_ioport *p)
-{
-	uint16_t start, end;
-	FILE *fp;
-	char *line = NULL;
-	char pci_id[16];
-	int found = 0;
-	size_t linesz;
-
-	snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
-		 dev->addr.domain, dev->addr.bus,
-		 dev->addr.devid, dev->addr.function);
-
-	fp = fopen("/proc/ioports", "r");
-	if (fp == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);
-		return -1;
-	}
-
-	while (getdelim(&line, &linesz, '\n', fp) > 0) {
-		char *ptr = line;
-		char *left;
-		int n;
-
-		n = strcspn(ptr, ":");
-		ptr[n] = 0;
-		left = &ptr[n + 1];
-
-		while (*left && isspace(*left))
-			left++;
-
-		if (!strncmp(left, pci_id, strlen(pci_id))) {
-			found = 1;
-
-			while (*ptr && isspace(*ptr))
-				ptr++;
-
-			sscanf(ptr, "%04hx-%04hx", &start, &end);
-
-			break;
-		}
-	}
-
-	free(line);
-	fclose(fp);
-
-	if (!found)
-		return -1;
-
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	p->base = start;
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
-
-	return 0;
-}
-#endif
-
-int
-rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p)
-{
-	int ret = -1;
-
-	switch (dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_ioport_map(dev, bar, p);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		ret = pci_uio_ioport_map(dev, bar, p);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-#if defined(RTE_ARCH_X86)
-		ret = pci_ioport_map(dev, bar, p);
-#else
-		ret = pci_uio_ioport_map(dev, bar, p);
-#endif
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		ret = pci_ioport_map(dev, bar, p);
-#endif
-		break;
-	default:
-		break;
-	}
-
-	if (!ret)
-		p->dev = dev;
-
-	return ret;
-}
-
-void
-rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		pci_vfio_ioport_read(p, data, len, offset);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		pci_uio_ioport_read(p, data, len, offset);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-void
-rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		pci_vfio_ioport_write(p, data, len, offset);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		pci_uio_ioport_write(p, data, len, offset);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-int
-rte_pci_ioport_unmap(struct rte_pci_ioport *p)
-{
-	int ret = -1;
-
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_ioport_unmap(p);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		ret = pci_uio_ioport_unmap(p);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-#if defined(RTE_ARCH_X86)
-		ret = 0;
-#else
-		ret = pci_uio_ioport_unmap(p);
-#endif
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		ret = 0;
-#endif
-		break;
-	default:
-		break;
-	}
-
-	return ret;
-}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
deleted file mode 100644
index c94ba19..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_init.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef EAL_PCI_INIT_H_
-#define EAL_PCI_INIT_H_
-
-#include <rte_vfio.h>
-
-/** IO resource type: */
-#define IORESOURCE_IO         0x00000100
-#define IORESOURCE_MEM        0x00000200
-
-/*
- * Helper function to map PCI resources right after hugepages in virtual memory
- */
-extern void *pci_map_addr;
-void *pci_find_max_end_va(void);
-
-/* parse one line of the "resource" sysfs file (note that the 'line'
- * string is modified)
- */
-int pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
-	uint64_t *end_addr, uint64_t *flags);
-
-int pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res);
-void pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res);
-int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx);
-
-int pci_uio_read_config(const struct rte_intr_handle *intr_handle,
-			void *buf, size_t len, off_t offs);
-int pci_uio_write_config(const struct rte_intr_handle *intr_handle,
-			 const void *buf, size_t len, off_t offs);
-
-int pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		       struct rte_pci_ioport *p);
-void pci_uio_ioport_read(struct rte_pci_ioport *p,
-			 void *data, size_t len, off_t offset);
-void pci_uio_ioport_write(struct rte_pci_ioport *p,
-			  const void *data, size_t len, off_t offset);
-int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
-
-#ifdef RTE_EAL_VFIO
-
-/* access config space */
-int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
-			 void *buf, size_t len, off_t offs);
-int pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
-			  const void *buf, size_t len, off_t offs);
-
-int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
-		        struct rte_pci_ioport *p);
-void pci_vfio_ioport_read(struct rte_pci_ioport *p,
-			  void *data, size_t len, off_t offset);
-void pci_vfio_ioport_write(struct rte_pci_ioport *p,
-			   const void *data, size_t len, off_t offset);
-int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
-
-/* map/unmap VFIO resource prototype */
-int pci_vfio_map_resource(struct rte_pci_device *dev);
-int pci_vfio_unmap_resource(struct rte_pci_device *dev);
-
-int pci_vfio_is_enabled(void);
-
-#endif
-
-#endif /* EAL_PCI_INIT_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
deleted file mode 100644
index d17837a..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/sysmacros.h>
-#include <linux/pci_regs.h>
-
-#if defined(RTE_ARCH_X86)
-#include <sys/io.h>
-#endif
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-
-void *pci_map_addr = NULL;
-
-#define OFF_MAX              ((uint64_t)(off_t)-1)
-
-int
-pci_uio_read_config(const struct rte_intr_handle *intr_handle,
-		    void *buf, size_t len, off_t offset)
-{
-	return pread(intr_handle->uio_cfg_fd, buf, len, offset);
-}
-
-int
-pci_uio_write_config(const struct rte_intr_handle *intr_handle,
-		     const void *buf, size_t len, off_t offset)
-{
-	return pwrite(intr_handle->uio_cfg_fd, buf, len, offset);
-}
-
-static int
-pci_uio_set_bus_master(int dev_fd)
-{
-	uint16_t reg;
-	int ret;
-
-	ret = pread(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL,
-			"Cannot read command from PCI config space!\n");
-		return -1;
-	}
-
-	/* return if bus mastering is already on */
-	if (reg & PCI_COMMAND_MASTER)
-		return 0;
-
-	reg |= PCI_COMMAND_MASTER;
-
-	ret = pwrite(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL,
-			"Cannot write command to PCI config space!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-static int
-pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
-{
-	FILE *f;
-	char filename[PATH_MAX];
-	int ret;
-	unsigned major, minor;
-	dev_t dev;
-
-	/* get the name of the sysfs file that contains the major and minor
-	 * of the uio device and read its content */
-	snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path);
-
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n",
-			__func__);
-		return -1;
-	}
-
-	ret = fscanf(f, "%u:%u", &major, &minor);
-	if (ret != 2) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n",
-			__func__);
-		fclose(f);
-		return -1;
-	}
-	fclose(f);
-
-	/* create the char device "mknod /dev/uioX c major minor" */
-	snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
-	dev = makedev(major, minor);
-	ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
-	if (ret != 0) {
-		RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
-			__func__, strerror(errno));
-		return -1;
-	}
-
-	return ret;
-}
-
-/*
- * Return the uioX char device used for a pci device. On success, return
- * the UIO number and fill dstbuf string with the path of the device in
- * sysfs. On error, return a negative value. In this case dstbuf is
- * invalid.
- */
-static int
-pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
-			   unsigned int buflen, int create)
-{
-	struct rte_pci_addr *loc = &dev->addr;
-	int uio_num = -1;
-	struct dirent *e;
-	DIR *dir;
-	char dirname[PATH_MAX];
-
-	/* depending on kernel version, uio can be located in uio/uioX
-	 * or uio:uioX */
-
-	snprintf(dirname, sizeof(dirname),
-			"%s/" PCI_PRI_FMT "/uio", pci_get_sysfs_path(),
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	dir = opendir(dirname);
-	if (dir == NULL) {
-		/* retry with the parent directory */
-		snprintf(dirname, sizeof(dirname),
-				"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
-				loc->domain, loc->bus, loc->devid, loc->function);
-		dir = opendir(dirname);
-
-		if (dir == NULL) {
-			RTE_LOG(ERR, EAL, "Cannot opendir %s\n", dirname);
-			return -1;
-		}
-	}
-
-	/* take the first file starting with "uio" */
-	while ((e = readdir(dir)) != NULL) {
-		/* format could be uio%d ...*/
-		int shortprefix_len = sizeof("uio") - 1;
-		/* ... or uio:uio%d */
-		int longprefix_len = sizeof("uio:uio") - 1;
-		char *endptr;
-
-		if (strncmp(e->d_name, "uio", 3) != 0)
-			continue;
-
-		/* first try uio%d */
-		errno = 0;
-		uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
-		if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
-			snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
-			break;
-		}
-
-		/* then try uio:uio%d */
-		errno = 0;
-		uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
-		if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
-			snprintf(dstbuf, buflen, "%s/uio:uio%u", dirname, uio_num);
-			break;
-		}
-	}
-	closedir(dir);
-
-	/* No uio resource found */
-	if (e == NULL)
-		return -1;
-
-	/* create uio device if we've been asked to */
-	if (rte_eal_create_uio_dev() && create &&
-			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
-		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
-
-	return uio_num;
-}
-
-void
-pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res)
-{
-	rte_free(uio_res);
-
-	if (dev->intr_handle.uio_cfg_fd >= 0) {
-		close(dev->intr_handle.uio_cfg_fd);
-		dev->intr_handle.uio_cfg_fd = -1;
-	}
-	if (dev->intr_handle.fd >= 0) {
-		close(dev->intr_handle.fd);
-		dev->intr_handle.fd = -1;
-		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	}
-}
-
-int
-pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res)
-{
-	char dirname[PATH_MAX];
-	char cfgname[PATH_MAX];
-	char devname[PATH_MAX]; /* contains the /dev/uioX */
-	int uio_num;
-	struct rte_pci_addr *loc;
-
-	loc = &dev->addr;
-
-	/* find uio resource */
-	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 1);
-	if (uio_num < 0) {
-		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
-				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
-		return 1;
-	}
-	snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
-
-	/* save fd if in primary process */
-	dev->intr_handle.fd = open(devname, O_RDWR);
-	if (dev->intr_handle.fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			devname, strerror(errno));
-		goto error;
-	}
-
-	snprintf(cfgname, sizeof(cfgname),
-			"/sys/class/uio/uio%u/device/config", uio_num);
-	dev->intr_handle.uio_cfg_fd = open(cfgname, O_RDWR);
-	if (dev->intr_handle.uio_cfg_fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			cfgname, strerror(errno));
-		goto error;
-	}
-
-	if (dev->kdrv == RTE_KDRV_IGB_UIO)
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-	else {
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
-
-		/* set bus master that is not done by uio_pci_generic */
-		if (pci_uio_set_bus_master(dev->intr_handle.uio_cfg_fd)) {
-			RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
-			goto error;
-		}
-	}
-
-	/* allocate the mapping details for secondary processes*/
-	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
-	if (*uio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto error;
-	}
-
-	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
-	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
-
-	return 0;
-
-error:
-	pci_uio_free_resource(dev, *uio_res);
-	return -1;
-}
-
-int
-pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx)
-{
-	int fd;
-	char devname[PATH_MAX];
-	void *mapaddr;
-	struct rte_pci_addr *loc;
-	struct pci_map *maps;
-
-	loc = &dev->addr;
-	maps = uio_res->maps;
-
-	/* update devname for mmap  */
-	snprintf(devname, sizeof(devname),
-			"%s/" PCI_PRI_FMT "/resource%d",
-			pci_get_sysfs_path(),
-			loc->domain, loc->bus, loc->devid,
-			loc->function, res_idx);
-
-	/* allocate memory to keep path */
-	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
-	if (maps[map_idx].path == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
-				strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * open resource file, to mmap it
-	 */
-	fd = open(devname, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				devname, strerror(errno));
-		goto error;
-	}
-
-	/* try mapping somewhere close to the end of hugepages */
-	if (pci_map_addr == NULL)
-		pci_map_addr = pci_find_max_end_va();
-
-	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
-			(size_t)dev->mem_resource[res_idx].len, 0);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		goto error;
-
-	pci_map_addr = RTE_PTR_ADD(mapaddr,
-			(size_t)dev->mem_resource[res_idx].len);
-
-	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
-	maps[map_idx].size = dev->mem_resource[res_idx].len;
-	maps[map_idx].addr = mapaddr;
-	maps[map_idx].offset = 0;
-	strcpy(maps[map_idx].path, devname);
-	dev->mem_resource[res_idx].addr = mapaddr;
-
-	return 0;
-
-error:
-	rte_free(maps[map_idx].path);
-	return -1;
-}
-
-#if defined(RTE_ARCH_X86)
-int
-pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		   struct rte_pci_ioport *p)
-{
-	char dirname[PATH_MAX];
-	char filename[PATH_MAX];
-	int uio_num;
-	unsigned long start;
-
-	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 0);
-	if (uio_num < 0)
-		return -1;
-
-	/* get portio start */
-	snprintf(filename, sizeof(filename),
-		 "%s/portio/port%d/start", dirname, bar);
-	if (eal_parse_sysfs_value(filename, &start) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
-			__func__);
-		return -1;
-	}
-	/* ensure we don't get anything funny here, read/write will cast to
-	 * uin16_t */
-	if (start > UINT16_MAX)
-		return -1;
-
-	/* FIXME only for primary process ? */
-	if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {
-
-		snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
-		dev->intr_handle.fd = open(filename, O_RDWR);
-		if (dev->intr_handle.fd < 0) {
-			RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				filename, strerror(errno));
-			return -1;
-		}
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-	}
-
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);
-
-	p->base = start;
-	p->len = 0;
-	return 0;
-}
-#else
-int
-pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		   struct rte_pci_ioport *p)
-{
-	FILE *f;
-	char buf[BUFSIZ];
-	char filename[PATH_MAX];
-	uint64_t phys_addr, end_addr, flags;
-	int fd, i;
-	void *addr;
-
-	/* open and read addresses of the corresponding resource in sysfs */
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
-		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
-		dev->addr.devid, dev->addr.function);
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",
-			strerror(errno));
-		return -1;
-	}
-	for (i = 0; i < bar + 1; i++) {
-		if (fgets(buf, sizeof(buf), f) == NULL) {
-			RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");
-			goto error;
-		}
-	}
-	if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
-			&end_addr, &flags) < 0)
-		goto error;
-	if ((flags & IORESOURCE_IO) == 0) {
-		RTE_LOG(ERR, EAL, "BAR %d is not an IO resource\n", bar);
-		goto error;
-	}
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
-		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
-		dev->addr.devid, dev->addr.function, bar);
-
-	/* mmap the pci resource */
-	fd = open(filename, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
-			strerror(errno));
-		goto error;
-	}
-	addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
-		MAP_SHARED, fd, 0);
-	close(fd);
-	if (addr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s\n",
-			strerror(errno));
-		goto error;
-	}
-
-	/* strangely, the base address is mmap addr + phys_addr */
-	p->base = (uintptr_t)addr + phys_addr;
-	p->len = end_addr + 1;
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"\n", p->base);
-	fclose(f);
-
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
-}
-#endif
-
-void
-pci_uio_ioport_read(struct rte_pci_ioport *p,
-		    void *data, size_t len, off_t offset)
-{
-	uint8_t *d;
-	int size;
-	uintptr_t reg = p->base + offset;
-
-	for (d = data; len > 0; d += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-#if defined(RTE_ARCH_X86)
-			*(uint32_t *)d = inl(reg);
-#else
-			*(uint32_t *)d = *(volatile uint32_t *)reg;
-#endif
-		} else if (len >= 2) {
-			size = 2;
-#if defined(RTE_ARCH_X86)
-			*(uint16_t *)d = inw(reg);
-#else
-			*(uint16_t *)d = *(volatile uint16_t *)reg;
-#endif
-		} else {
-			size = 1;
-#if defined(RTE_ARCH_X86)
-			*d = inb(reg);
-#else
-			*d = *(volatile uint8_t *)reg;
-#endif
-		}
-	}
-}
-
-void
-pci_uio_ioport_write(struct rte_pci_ioport *p,
-		     const void *data, size_t len, off_t offset)
-{
-	const uint8_t *s;
-	int size;
-	uintptr_t reg = p->base + offset;
-
-	for (s = data; len > 0; s += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-#if defined(RTE_ARCH_X86)
-			outl_p(*(const uint32_t *)s, reg);
-#else
-			*(volatile uint32_t *)reg = *(const uint32_t *)s;
-#endif
-		} else if (len >= 2) {
-			size = 2;
-#if defined(RTE_ARCH_X86)
-			outw_p(*(const uint16_t *)s, reg);
-#else
-			*(volatile uint16_t *)reg = *(const uint16_t *)s;
-#endif
-		} else {
-			size = 1;
-#if defined(RTE_ARCH_X86)
-			outb_p(*s, reg);
-#else
-			*(volatile uint8_t *)reg = *s;
-#endif
-		}
-	}
-}
-
-int
-pci_uio_ioport_unmap(struct rte_pci_ioport *p)
-{
-#if defined(RTE_ARCH_X86)
-	RTE_SET_USED(p);
-	/* FIXME close intr fd ? */
-	return 0;
-#else
-	return munmap((void *)(uintptr_t)p->base, p->len);
-#endif
-}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
deleted file mode 100644
index 4e2b6c9..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ /dev/null
@@ -1,754 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <fcntl.h>
-#include <linux/pci_regs.h>
-#include <sys/eventfd.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <stdbool.h>
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-#include <rte_vfio.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-#include "eal_private.h"
-
-/**
- * @file
- * PCI probing under linux (VFIO version)
- *
- * This code tries to determine if the PCI device is bound to VFIO driver,
- * and initialize it (map BARs, set up interrupts) if that's the case.
- *
- * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
- */
-
-#ifdef VFIO_PRESENT
-
-#define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
-#define PAGE_MASK   (~(PAGE_SIZE - 1))
-
-static struct rte_tailq_elem rte_vfio_tailq = {
-	.name = "VFIO_RESOURCE_LIST",
-};
-EAL_REGISTER_TAILQ(rte_vfio_tailq)
-
-int
-pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
-		    void *buf, size_t len, off_t offs)
-{
-	return pread64(intr_handle->vfio_dev_fd, buf, len,
-	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
-}
-
-int
-pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
-		    const void *buf, size_t len, off_t offs)
-{
-	return pwrite64(intr_handle->vfio_dev_fd, buf, len,
-	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
-}
-
-/* get PCI BAR number where MSI-X interrupts are */
-static int
-pci_vfio_get_msix_bar(int fd, struct pci_msix_table *msix_table)
-{
-	int ret;
-	uint32_t reg;
-	uint16_t flags;
-	uint8_t cap_id, cap_offset;
-
-	/* read PCI capability pointer from config space */
-	ret = pread64(fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_CAPABILITY_LIST);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
-				"config space!\n");
-		return -1;
-	}
-
-	/* we need first byte */
-	cap_offset = reg & 0xFF;
-
-	while (cap_offset) {
-
-		/* read PCI capability ID */
-		ret = pread64(fd, &reg, sizeof(reg),
-				VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-				cap_offset);
-		if (ret != sizeof(reg)) {
-			RTE_LOG(ERR, EAL, "Cannot read capability ID from PCI "
-					"config space!\n");
-			return -1;
-		}
-
-		/* we need first byte */
-		cap_id = reg & 0xFF;
-
-		/* if we haven't reached MSI-X, check next capability */
-		if (cap_id != PCI_CAP_ID_MSIX) {
-			ret = pread64(fd, &reg, sizeof(reg),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset);
-			if (ret != sizeof(reg)) {
-				RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
-						"config space!\n");
-				return -1;
-			}
-
-			/* we need second byte */
-			cap_offset = (reg & 0xFF00) >> 8;
-
-			continue;
-		}
-		/* else, read table offset */
-		else {
-			/* table offset resides in the next 4 bytes */
-			ret = pread64(fd, &reg, sizeof(reg),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset + 4);
-			if (ret != sizeof(reg)) {
-				RTE_LOG(ERR, EAL, "Cannot read table offset from PCI config "
-						"space!\n");
-				return -1;
-			}
-
-			ret = pread64(fd, &flags, sizeof(flags),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset + 2);
-			if (ret != sizeof(flags)) {
-				RTE_LOG(ERR, EAL, "Cannot read table flags from PCI config "
-						"space!\n");
-				return -1;
-			}
-
-			msix_table->bar_index = reg & RTE_PCI_MSIX_TABLE_BIR;
-			msix_table->offset = reg & RTE_PCI_MSIX_TABLE_OFFSET;
-			msix_table->size =
-				16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE));
-
-			return 0;
-		}
-	}
-	return 0;
-}
-
-/* set PCI bus mastering */
-static int
-pci_vfio_set_bus_master(int dev_fd, bool op)
-{
-	uint16_t reg;
-	int ret;
-
-	ret = pread64(dev_fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n");
-		return -1;
-	}
-
-	if (op)
-		/* set the master bit */
-		reg |= PCI_COMMAND_MASTER;
-	else
-		reg &= ~(PCI_COMMAND_MASTER);
-
-	ret = pwrite64(dev_fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_COMMAND);
-
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-/* set up interrupt support (but not enable interrupts) */
-static int
-pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
-{
-	int i, ret, intr_idx;
-	enum rte_intr_mode intr_mode;
-
-	/* default to invalid index */
-	intr_idx = VFIO_PCI_NUM_IRQS;
-
-	/* Get default / configured intr_mode */
-	intr_mode = rte_eal_vfio_intr_mode();
-
-	/* get interrupt type from internal config (MSI-X by default, can be
-	 * overridden from the command line
-	 */
-	switch (intr_mode) {
-	case RTE_INTR_MODE_MSIX:
-		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
-		break;
-	case RTE_INTR_MODE_MSI:
-		intr_idx = VFIO_PCI_MSI_IRQ_INDEX;
-		break;
-	case RTE_INTR_MODE_LEGACY:
-		intr_idx = VFIO_PCI_INTX_IRQ_INDEX;
-		break;
-	/* don't do anything if we want to automatically determine interrupt type */
-	case RTE_INTR_MODE_NONE:
-		break;
-	default:
-		RTE_LOG(ERR, EAL, "  unknown default interrupt type!\n");
-		return -1;
-	}
-
-	/* start from MSI-X interrupt type */
-	for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) {
-		struct vfio_irq_info irq = { .argsz = sizeof(irq) };
-		int fd = -1;
-
-		/* skip interrupt modes we don't want */
-		if (intr_mode != RTE_INTR_MODE_NONE &&
-				i != intr_idx)
-			continue;
-
-		irq.index = i;
-
-		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  cannot get IRQ info, "
-					"error %i (%s)\n", errno, strerror(errno));
-			return -1;
-		}
-
-		/* if this vector cannot be used with eventfd, fail if we explicitly
-		 * specified interrupt type, otherwise continue */
-		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
-			if (intr_mode != RTE_INTR_MODE_NONE) {
-				RTE_LOG(ERR, EAL,
-						"  interrupt vector does not support eventfd!\n");
-				return -1;
-			} else
-				continue;
-		}
-
-		/* set up an eventfd for interrupts */
-		fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
-		if (fd < 0) {
-			RTE_LOG(ERR, EAL, "  cannot set up eventfd, "
-					"error %i (%s)\n", errno, strerror(errno));
-			return -1;
-		}
-
-		dev->intr_handle.fd = fd;
-		dev->intr_handle.vfio_dev_fd = vfio_dev_fd;
-
-		switch (i) {
-		case VFIO_PCI_MSIX_IRQ_INDEX:
-			intr_mode = RTE_INTR_MODE_MSIX;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
-			break;
-		case VFIO_PCI_MSI_IRQ_INDEX:
-			intr_mode = RTE_INTR_MODE_MSI;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
-			break;
-		case VFIO_PCI_INTX_IRQ_INDEX:
-			intr_mode = RTE_INTR_MODE_LEGACY;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
-			break;
-		default:
-			RTE_LOG(ERR, EAL, "  unknown interrupt type!\n");
-			return -1;
-		}
-
-		return 0;
-	}
-
-	/* if we're here, we haven't found a suitable interrupt vector */
-	return -1;
-}
-
-static int
-pci_vfio_is_ioport_bar(int vfio_dev_fd, int bar_index)
-{
-	uint32_t ioport_bar;
-	int ret;
-
-	ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar),
-			  VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX)
-			  + PCI_BASE_ADDRESS_0 + bar_index*4);
-	if (ret != sizeof(ioport_bar)) {
-		RTE_LOG(ERR, EAL, "Cannot read command (%x) from config space!\n",
-			PCI_BASE_ADDRESS_0 + bar_index*4);
-		return -1;
-	}
-
-	return (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) != 0;
-}
-
-static int
-pci_vfio_setup_device(struct rte_pci_device *dev, int vfio_dev_fd)
-{
-	if (pci_vfio_setup_interrupts(dev, vfio_dev_fd) != 0) {
-		RTE_LOG(ERR, EAL, "Error setting up interrupts!\n");
-		return -1;
-	}
-
-	/* set bus mastering for the device */
-	if (pci_vfio_set_bus_master(vfio_dev_fd, true)) {
-		RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
-		return -1;
-	}
-
-	/* Reset the device */
-	ioctl(vfio_dev_fd, VFIO_DEVICE_RESET);
-
-	return 0;
-}
-
-static int
-pci_vfio_mmap_bar(int vfio_dev_fd, struct mapped_pci_resource *vfio_res,
-		int bar_index, int additional_flags)
-{
-	struct memreg {
-		unsigned long offset, size;
-	} memreg[2] = {};
-	void *bar_addr;
-	struct pci_msix_table *msix_table = &vfio_res->msix_table;
-	struct pci_map *bar = &vfio_res->maps[bar_index];
-
-	if (bar->size == 0)
-		/* Skip this BAR */
-		return 0;
-
-	if (msix_table->bar_index == bar_index) {
-		/*
-		 * VFIO will not let us map the MSI-X table,
-		 * but we can map around it.
-		 */
-		uint32_t table_start = msix_table->offset;
-		uint32_t table_end = table_start + msix_table->size;
-		table_end = (table_end + ~PAGE_MASK) & PAGE_MASK;
-		table_start &= PAGE_MASK;
-
-		if (table_start == 0 && table_end >= bar->size) {
-			/* Cannot map this BAR */
-			RTE_LOG(DEBUG, EAL, "Skipping BAR%d\n", bar_index);
-			bar->size = 0;
-			bar->addr = 0;
-			return 0;
-		}
-
-		memreg[0].offset = bar->offset;
-		memreg[0].size = table_start;
-		memreg[1].offset = bar->offset + table_end;
-		memreg[1].size = bar->size - table_end;
-
-		RTE_LOG(DEBUG, EAL,
-			"Trying to map BAR%d that contains the MSI-X "
-			"table. Trying offsets: "
-			"0x%04lx:0x%04lx, 0x%04lx:0x%04lx\n", bar_index,
-			memreg[0].offset, memreg[0].size,
-			memreg[1].offset, memreg[1].size);
-	} else {
-		memreg[0].offset = bar->offset;
-		memreg[0].size = bar->size;
-	}
-
-	/* reserve the address using an inaccessible mapping */
-	bar_addr = mmap(bar->addr, bar->size, 0, MAP_PRIVATE |
-			MAP_ANONYMOUS | additional_flags, -1, 0);
-	if (bar_addr != MAP_FAILED) {
-		void *map_addr = NULL;
-		if (memreg[0].size) {
-			/* actual map of first part */
-			map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
-							memreg[0].offset,
-							memreg[0].size,
-							MAP_FIXED);
-		}
-
-		/* if there's a second part, try to map it */
-		if (map_addr != MAP_FAILED
-			&& memreg[1].offset && memreg[1].size) {
-			void *second_addr = RTE_PTR_ADD(bar_addr,
-							memreg[1].offset -
-							(uintptr_t)bar->offset);
-			map_addr = pci_map_resource(second_addr,
-							vfio_dev_fd,
-							memreg[1].offset,
-							memreg[1].size,
-							MAP_FIXED);
-		}
-
-		if (map_addr == MAP_FAILED || !map_addr) {
-			munmap(bar_addr, bar->size);
-			bar_addr = MAP_FAILED;
-			RTE_LOG(ERR, EAL, "Failed to map pci BAR%d\n",
-					bar_index);
-			return -1;
-		}
-	} else {
-		RTE_LOG(ERR, EAL,
-				"Failed to create inaccessible mapping for BAR%d\n",
-				bar_index);
-		return -1;
-	}
-
-	bar->addr = bar_addr;
-	return 0;
-}
-
-static int
-pci_vfio_map_resource_primary(struct rte_pci_device *dev)
-{
-	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
-	char pci_addr[PATH_MAX] = {0};
-	int vfio_dev_fd;
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list =
-		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-
-	struct pci_map *maps;
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
-					&vfio_dev_fd, &device_info);
-	if (ret)
-		return ret;
-
-	/* allocate vfio_res and get region info */
-	vfio_res = rte_zmalloc("VFIO_RES", sizeof(*vfio_res), 0);
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto err_vfio_dev_fd;
-	}
-	memcpy(&vfio_res->pci_addr, &dev->addr, sizeof(vfio_res->pci_addr));
-
-	/* get number of registers (up to BAR5) */
-	vfio_res->nb_maps = RTE_MIN((int) device_info.num_regions,
-			VFIO_PCI_BAR5_REGION_INDEX + 1);
-
-	/* map BARs */
-	maps = vfio_res->maps;
-
-	vfio_res->msix_table.bar_index = -1;
-	/* get MSI-X BAR, if any (we have to know where it is because we can't
-	 * easily mmap it when using VFIO)
-	 */
-	ret = pci_vfio_get_msix_bar(vfio_dev_fd, &vfio_res->msix_table);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "  %s cannot get MSI-X BAR number!\n",
-				pci_addr);
-		goto err_vfio_dev_fd;
-	}
-
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-		struct vfio_region_info reg = { .argsz = sizeof(reg) };
-		void *bar_addr;
-
-		reg.index = i;
-
-		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg);
-		if (ret) {
-			RTE_LOG(ERR, EAL, "  %s cannot get device region info "
-					"error %i (%s)\n", pci_addr, errno, strerror(errno));
-			goto err_vfio_res;
-		}
-
-		/* chk for io port region */
-		ret = pci_vfio_is_ioport_bar(vfio_dev_fd, i);
-		if (ret < 0)
-			goto err_vfio_res;
-		else if (ret) {
-			RTE_LOG(INFO, EAL, "Ignore mapping IO port bar(%d)\n",
-					i);
-			continue;
-		}
-
-		/* skip non-mmapable BARs */
-		if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0)
-			continue;
-
-		/* try mapping somewhere close to the end of hugepages */
-		if (pci_map_addr == NULL)
-			pci_map_addr = pci_find_max_end_va();
-
-		bar_addr = pci_map_addr;
-		pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
-
-		maps[i].addr = bar_addr;
-		maps[i].offset = reg.offset;
-		maps[i].size = reg.size;
-		maps[i].path = NULL; /* vfio doesn't have per-resource paths */
-
-		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, 0);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
-					pci_addr, i, strerror(errno));
-			goto err_vfio_res;
-		}
-
-		dev->mem_resource[i].addr = maps[i].addr;
-	}
-
-	if (pci_vfio_setup_device(dev, vfio_dev_fd) < 0) {
-		RTE_LOG(ERR, EAL, "  %s setup device failed\n", pci_addr);
-		goto err_vfio_res;
-	}
-
-	TAILQ_INSERT_TAIL(vfio_res_list, vfio_res, next);
-
-	return 0;
-err_vfio_res:
-	rte_free(vfio_res);
-err_vfio_dev_fd:
-	close(vfio_dev_fd);
-	return -1;
-}
-
-static int
-pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
-{
-	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
-	char pci_addr[PATH_MAX] = {0};
-	int vfio_dev_fd;
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list =
-		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-
-	struct pci_map *maps;
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
-					&vfio_dev_fd, &device_info);
-	if (ret)
-		return ret;
-
-	/* if we're in a secondary process, just find our tailq entry */
-	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-		if (rte_pci_addr_cmp(&vfio_res->pci_addr,
-				     &dev->addr))
-			continue;
-		break;
-	}
-	/* if we haven't found our tailq entry, something's wrong */
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
-				pci_addr);
-		goto err_vfio_dev_fd;
-	}
-
-	/* map BARs */
-	maps = vfio_res->maps;
-
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, MAP_FIXED);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
-					pci_addr, i, strerror(errno));
-			goto err_vfio_dev_fd;
-		}
-
-		dev->mem_resource[i].addr = maps[i].addr;
-	}
-
-	return 0;
-err_vfio_dev_fd:
-	close(vfio_dev_fd);
-	return -1;
-}
-
-/*
- * map the PCI resources of a PCI device in virtual memory (VFIO version).
- * primary and secondary processes follow almost exactly the same path
- */
-int
-pci_vfio_map_resource(struct rte_pci_device *dev)
-{
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-		return pci_vfio_map_resource_primary(dev);
-	else
-		return pci_vfio_map_resource_secondary(dev);
-}
-
-int
-pci_vfio_unmap_resource(struct rte_pci_device *dev)
-{
-	char pci_addr[PATH_MAX] = {0};
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list;
-
-	struct pci_map *maps;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-
-	if (close(dev->intr_handle.fd) < 0) {
-		RTE_LOG(INFO, EAL, "Error when closing eventfd file descriptor for %s\n",
-			pci_addr);
-		return -1;
-	}
-
-	if (pci_vfio_set_bus_master(dev->intr_handle.vfio_dev_fd, false)) {
-		RTE_LOG(ERR, EAL, "  %s cannot unset bus mastering for PCI device!\n",
-				pci_addr);
-		return -1;
-	}
-
-	ret = vfio_release_device(pci_get_sysfs_path(), pci_addr,
-				  dev->intr_handle.vfio_dev_fd);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot release device\n", __func__);
-		return ret;
-	}
-
-	vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-	/* Get vfio_res */
-	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-		if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
-			continue;
-		break;
-	}
-	/* if we haven't found our tailq entry, something's wrong */
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
-				pci_addr);
-		return -1;
-	}
-
-	/* unmap BARs */
-	maps = vfio_res->maps;
-
-	RTE_LOG(INFO, EAL, "Releasing pci mapped resource for %s\n",
-		pci_addr);
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-
-		/*
-		 * We do not need to be aware of MSI-X table BAR mappings as
-		 * when mapping. Just using current maps array is enough
-		 */
-		if (maps[i].addr) {
-			RTE_LOG(INFO, EAL, "Calling pci_unmap_resource for %s at %p\n",
-				pci_addr, maps[i].addr);
-			pci_unmap_resource(maps[i].addr, maps[i].size);
-		}
-	}
-
-	TAILQ_REMOVE(vfio_res_list, vfio_res, next);
-
-	return 0;
-}
-
-int
-pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
-		    struct rte_pci_ioport *p)
-{
-	if (bar < VFIO_PCI_BAR0_REGION_INDEX ||
-	    bar > VFIO_PCI_BAR5_REGION_INDEX) {
-		RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar);
-		return -1;
-	}
-
-	p->dev = dev;
-	p->base = VFIO_GET_REGION_ADDR(bar);
-	return 0;
-}
-
-void
-pci_vfio_ioport_read(struct rte_pci_ioport *p,
-		     void *data, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
-
-	if (pread64(intr_handle->vfio_dev_fd, data,
-		    len, p->base + offset) <= 0)
-		RTE_LOG(ERR, EAL,
-			"Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n",
-			VFIO_GET_REGION_IDX(p->base), (int)offset);
-}
-
-void
-pci_vfio_ioport_write(struct rte_pci_ioport *p,
-		      const void *data, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
-
-	if (pwrite64(intr_handle->vfio_dev_fd, data,
-		     len, p->base + offset) <= 0)
-		RTE_LOG(ERR, EAL,
-			"Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n",
-			VFIO_GET_REGION_IDX(p->base), (int)offset);
-}
-
-int
-pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
-{
-	RTE_SET_USED(p);
-	return -1;
-}
-
-int
-pci_vfio_is_enabled(void)
-{
-	return vfio_is_enabled("vfio_pci");
-}
-#endif
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 8d67b67..d2a4ff9 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -166,17 +166,6 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_pci_dump;
-	rte_pci_ioport_map;
-	rte_pci_ioport_read;
-	rte_pci_ioport_unmap;
-	rte_pci_ioport_write;
-	rte_pci_map_device;
-	rte_pci_read_config;
-	rte_pci_register;
-	rte_pci_unmap_device;
-	rte_pci_unregister;
-	rte_pci_write_config;
 	rte_vdev_init;
 	rte_vdev_register;
 	rte_vdev_uninit;
@@ -237,11 +226,8 @@ EXPERIMENTAL {
 DPDK_17.11 {
 	global:
 
-	eal_parse_pci_BDF;
-	eal_parse_pci_DomBDF;
 	rte_eal_create_uio_dev;
 	rte_bus_get_iommu_class;
-	rte_eal_compare_pci_addr;
 	rte_eal_has_pci;
 	rte_eal_iova_mode;
 	rte_eal_mbuf_default_mempool_ops;
@@ -249,9 +235,6 @@ DPDK_17.11 {
 	rte_eal_vfio_intr_mode;
 	rte_lcore_has_role;
 	rte_memcpy_ptr;
-	rte_pci_addr_cmp;
-	rte_pci_addr_parse;
-	rte_pci_device_name;
 	vfio_enable;
 	vfio_is_enabled;
 	vfio_noiommu_is_enabled;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index b773589..3c68ae2 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1151,8 +1151,6 @@ TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
 	} \
 } while (0)
 
-#define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
-
 /**
  * l2 tunnel configuration.
  */
diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h
index 56b1072..722075e 100644
--- a/lib/librte_ether/rte_ethdev_pci.h
+++ b/lib/librte_ether/rte_ethdev_pci.h
@@ -36,6 +36,7 @@
 
 #include <rte_malloc.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 
 /**
diff --git a/lib/librte_eventdev/rte_eventdev_pmd_pci.h b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
index b6bd731..ade32b5 100644
--- a/lib/librte_eventdev/rte_eventdev_pmd_pci.h
+++ b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
@@ -50,6 +50,7 @@ extern "C" {
 #include <rte_eal.h>
 #include <rte_lcore.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "rte_eventdev_pmd.h"
 
diff --git a/lib/librte_pci/Makefile b/lib/librte_pci/Makefile
new file mode 100644
index 0000000..82a16e2
--- /dev/null
+++ b/lib/librte_pci/Makefile
@@ -0,0 +1,49 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_pci.a
+
+CFLAGS := -I$(SRCDIR)/include -I$(SRCDIR) $(CFLAGS)
+CFLAGS += $(WERROR_FLAGS) -O3
+LDLIBS += -lrte_eal
+
+EXPORT_MAP := rte_pci_version.map
+
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_PCI) += rte_pci.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI)-include += include/rte_pci.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
new file mode 100644
index 0000000..ea0897c
--- /dev/null
+++ b/lib/librte_pci/include/rte_pci.h
@@ -0,0 +1,279 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_PCI_H_
+#define _RTE_PCI_H_
+
+/**
+ * @file
+ *
+ * RTE PCI Library
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+
+/** Formatting string for PCI device identifier: Ex: 0000:00:01.0 */
+#define PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+#define PCI_PRI_STR_SIZE sizeof("XXXXXXXX:XX:XX.X")
+
+/** Short formatting string, without domain, for PCI device: Ex: 00:01.0 */
+#define PCI_SHORT_PRI_FMT "%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+
+/** Nb. of values in PCI device identifier format string. */
+#define PCI_FMT_NVAL 4
+
+/** Nb. of values in PCI resource format. */
+#define PCI_RESOURCE_FMT_NVAL 3
+
+/** Maximum number of PCI resources. */
+#define PCI_MAX_RESOURCE 6
+
+/**
+ * A structure describing an ID for a PCI driver. Each driver provides a
+ * table of these IDs for each device that it supports.
+ */
+struct rte_pci_id {
+	uint32_t class_id;            /**< Class ID or RTE_CLASS_ANY_ID. */
+	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
+	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
+	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
+	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
+};
+
+/**
+ * A structure describing the location of a PCI device.
+ */
+struct rte_pci_addr {
+	uint32_t domain;                /**< Device domain */
+	uint8_t bus;                    /**< Device bus */
+	uint8_t devid;                  /**< Device ID */
+	uint8_t function;               /**< Device function. */
+};
+
+/** Any PCI device identifier (vendor, device, ...) */
+#define PCI_ANY_ID (0xffff)
+#define RTE_CLASS_ANY_ID (0xffffff)
+
+/**
+ * A structure describing a PCI mapping.
+ */
+struct pci_map {
+	void *addr;
+	char *path;
+	uint64_t offset;
+	uint64_t size;
+	uint64_t phaddr;
+};
+
+struct pci_msix_table {
+	int bar_index;
+	uint32_t offset;
+	uint32_t size;
+};
+
+/**
+ * A structure describing a mapped PCI resource.
+ * For multi-process we need to reproduce all PCI mappings in secondary
+ * processes, so save them in a tailq.
+ */
+struct mapped_pci_resource {
+	TAILQ_ENTRY(mapped_pci_resource) next;
+
+	struct rte_pci_addr pci_addr;
+	char path[PATH_MAX];
+	int nb_maps;
+	struct pci_map maps[PCI_MAX_RESOURCE];
+	struct pci_msix_table msix_table;
+};
+
+
+/** mapped pci device list */
+TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
+
+/**
+ * @deprecated
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided without
+ * a domain prefix (i.e. domain returned is always 0)
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned.
+ *	Domain will always be returned as 0
+ * @return
+ *  0 on success, negative on error.
+ */
+int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided including
+ * a domain prefix.
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XXXX:XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned
+ * @return
+ *  0 on success, negative on error.
+ */
+int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
+ * Utility function to write a pci device name, this device name can later be
+ * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
+ * BDF helpers.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ */
+void rte_pci_device_name(const struct rte_pci_addr *addr,
+			 char *output, size_t size);
+
+/**
+ * Utility function to write a pci device name, this device name can later be
+ * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
+ * BDF helpers.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ */
+void pci_device_name(const struct rte_pci_addr *addr,
+		     char *output, size_t size);
+
+/**
+ * @deprecated
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
+int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			     const struct rte_pci_addr *addr2);
+
+/**
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
+int pci_addr_cmp(const struct rte_pci_addr *addr,
+		 const struct rte_pci_addr *addr2);
+
+
+/**
+ * Utility function to parse a string into a PCI location.
+ *
+ * @param str
+ *	The string to parse
+ * @param addr
+ *	The reference to the structure where the location
+ *	is stored.
+ * @return
+ *	0 on success
+ *	<0 otherwise
+ */
+int pci_addr_parse(const char *str, struct rte_pci_addr *addr);
+
+/**
+ * Map a particular resource from a file.
+ *
+ * @param requested_addr
+ *      The starting address for the new mapping range.
+ * @param fd
+ *      The file descriptor.
+ * @param offset
+ *      The offset for the mapping range.
+ * @param size
+ *      The size for the mapping range.
+ * @param additional_flags
+ *      The additional flags for the mapping range.
+ * @return
+ *   - On success, the function returns a pointer to the mapped area.
+ *   - On error, the value MAP_FAILED is returned.
+ */
+void *pci_map_resource(void *requested_addr, int fd, off_t offset,
+		size_t size, int additional_flags);
+
+/**
+ * Unmap a particular resource.
+ *
+ * @param requested_addr
+ *      The address for the unmapping range.
+ * @param size
+ *      The size for the unmapping range.
+ */
+void pci_unmap_resource(void *requested_addr, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PCI_H_ */
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
new file mode 100644
index 0000000..1307a18
--- /dev/null
+++ b/lib/librte_pci/rte_pci.c
@@ -0,0 +1,220 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+
+#include "rte_pci.h"
+
+static inline const char *
+get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
+{
+	unsigned long val;
+	uint8_t *u8 = _u8;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != dlm || val > UINT8_MAX) {
+		errno = errno ? errno : EINVAL;
+		return NULL;
+	}
+	*u8 = (uint8_t)val;
+	return end + 1;
+}
+
+static int
+pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
+{
+	const char *in = input;
+
+	dev_addr->domain = 0;
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
+	return 0;
+}
+
+static int
+pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
+{
+	const char *in = input;
+	unsigned long val;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != ':' || val > UINT16_MAX)
+		return -EINVAL;
+	dev_addr->domain = (uint16_t)val;
+	in = end + 1;
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
+	return 0;
+}
+
+int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	return pci_bdf_parse(input, dev_addr);
+}
+
+int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	return pci_dbdf_parse(input, dev_addr);
+}
+
+void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+		    char *output, size_t size)
+{
+	pci_device_name(addr, output, size);
+}
+
+void
+pci_device_name(const struct rte_pci_addr *addr,
+		char *output, size_t size)
+{
+	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+			    addr->domain, addr->bus,
+			    addr->devid, addr->function) >= 0);
+}
+
+int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			 const struct rte_pci_addr *addr2)
+{
+	return pci_addr_cmp(addr, addr2);
+}
+
+int
+pci_addr_cmp(const struct rte_pci_addr *addr,
+	     const struct rte_pci_addr *addr2)
+{
+	uint64_t dev_addr, dev_addr2;
+
+	if ((addr == NULL) || (addr2 == NULL))
+		return -1;
+
+	dev_addr = ((uint64_t)addr->domain << 24) |
+		(addr->bus << 16) | (addr->devid << 8) | addr->function;
+	dev_addr2 = ((uint64_t)addr2->domain << 24) |
+		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+	if (dev_addr > dev_addr2)
+		return 1;
+	else if (dev_addr < dev_addr2)
+		return -1;
+	else
+		return 0;
+}
+
+int
+pci_addr_parse(const char *str, struct rte_pci_addr *addr)
+{
+	if (pci_bdf_parse(str, addr) == 0 ||
+	    pci_dbdf_parse(str, addr) == 0)
+		return 0;
+	return -1;
+}
+
+
+/* map a particular resource from a file */
+void *
+pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+		 int additional_flags)
+{
+	void *mapaddr;
+
+	/* Map the PCI memory resource of device */
+	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+			MAP_SHARED | additional_flags, fd, offset);
+	if (mapaddr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
+			__func__, fd, requested_addr,
+			(unsigned long)size, (unsigned long)offset,
+			strerror(errno), mapaddr);
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
+
+	return mapaddr;
+}
+
+/* unmap a particular resource */
+void
+pci_unmap_resource(void *requested_addr, size_t size)
+{
+	if (requested_addr == NULL)
+		return;
+
+	/* Unmap the PCI memory resource of device */
+	if (munmap(requested_addr, size)) {
+		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+			__func__, requested_addr, (unsigned long)size,
+			strerror(errno));
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
+				requested_addr);
+}
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
new file mode 100644
index 0000000..b5c9ec2
--- /dev/null
+++ b/lib/librte_pci/rte_pci_version.map
@@ -0,0 +1,15 @@
+DPDK_17.11 {
+	global:
+
+	eal_parse_pci_BDF;
+	eal_parse_pci_DomBDF;
+	pci_addr_cmp;
+	pci_addr_parse;
+	pci_device_name;
+	pci_map_resource;
+	pci_unmap_resource;
+	rte_eal_compare_pci_addr;
+	rte_pci_device_name;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 482656c..69e3c72 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -98,6 +98,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI)            += -lrte_pci
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
@@ -107,6 +108,8 @@ ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
 endif
 
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI_BUS)        += -lrte_bus_pci
+
 ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
 # plugins (link only if static libraries)
 
diff --git a/test/test/test_kni.c b/test/test/test_kni.c
index 2450c9f..b956727 100644
--- a/test/test/test_kni.c
+++ b/test/test/test_kni.c
@@ -42,6 +42,7 @@
 #include <rte_string_fns.h>
 #include <rte_mempool.h>
 #include <rte_ethdev.h>
+#include <rte_bus_pci.h>
 #include <rte_cycles.h>
 #include <rte_kni.h>
 
diff --git a/test/test/virtual_pmd.c b/test/test/virtual_pmd.c
index 09daf6c..b57a949 100644
--- a/test/test/virtual_pmd.c
+++ b/test/test/virtual_pmd.c
@@ -34,6 +34,7 @@
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_memory.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 24/25] doc: add notes on EAL PCI API update
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (22 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 23/25] pci: introduce PCI lib and bus Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 25/25] maintainers: claim maintainership of PCI lib Gaetan Rivet
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Add a section related to EAL API changes to 17.11 release notes.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/rel_notes/release_17_11.rst | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 3298ef5..5aa0f4d 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -297,6 +297,34 @@ API Changes
   ``rte_log_get_global_level()``, ``rte_log_set_level()`` and
   ``rte_log_get_level()``.
 
+* **PCI bus API moved outside of the EAL**
+
+  The PCI bus previously implemented within the EAL has been moved.
+  A first part has been added as an RTE library providing PCI helpers to
+  parse device locations or other such utilities.
+  A second part consisting in the actual bus driver has been moved to its
+  proper subdirectory, without changing its functionalities.
+
+  As such, several PCI-related functions are not proposed by the EAL anymore:
+
+  * rte_pci_detach
+  * rte_pci_dump
+  * rte_pci_ioport_map
+  * rte_pci_ioport_read
+  * rte_pci_ioport_unmap
+  * rte_pci_ioport_write
+  * rte_pci_map_device
+  * rte_pci_probe
+  * rte_pci_probe_one
+  * rte_pci_read_config
+  * rte_pci_register
+  * rte_pci_scan
+  * rte_pci_unmap_device
+  * rte_pci_unregister
+  * rte_pci_write_config
+
+  These functions are made available either as part of ``librte_pci`` or
+  ``librte_bus_pci``.
 
 ABI Changes
 -----------
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v7 25/25] maintainers: claim maintainership of PCI lib
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (23 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 24/25] doc: add notes on EAL PCI API update Gaetan Rivet
@ 2017-10-25 22:38           ` Gaetan Rivet
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
  25 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-25 22:38 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 MAINTAINERS | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index c072d03..0fd6cab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -870,6 +870,10 @@ Latency statistics
 M: Reshma Pattan <reshma.pattan@intel.com>
 F: lib/librte_latencystats/
 
+PCI
+M: Gaetan Rivet <gaetan.rivet@6wind.com>
+F: lib/librte_pci/
+
 
 Test Applications
 -----------------
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL
  2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
                             ` (24 preceding siblings ...)
  2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 25/25] maintainers: claim maintainership of PCI lib Gaetan Rivet
@ 2017-10-26 10:05           ` Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 01/25] ethdev: remove useless PCI dependency Gaetan Rivet
                               ` (26 more replies)
  25 siblings, 27 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet, Anatoly Burakov

Hi all,

Here is a new version of the PCI bus move out of the EAL.

The EAL PCI implementation is divided in two parts:

  - librte_pci: library offering helpers to handle PCI objects
  - librte_bus_pci: bus driver for PCI devices

This allows other libraries / tools to use PCI elements (location, mappings,
parsing operations, etc) without forcing a dependency on a bus driver.

The latter should not have to export helpers that others might need. It
is focused on defining the rte_pci_device, rte_pci_driver objects and
their handling.

The cryptodev library has hard dependencies on rte_pci_devices (used by
generic probe function). Other similar libs (ether and eventdev) avoided
the issue by inlining such functions and expecting users to include the
relevant headers once the PCI bus has already been built.

After review from Declan, he proposed to submit a patch removing this dependency.
Once this patch is submitted, the relevant commit will be dropped from this
patchset.

v2:

  + Made rte_eal_using_phys_addrs common to both linux and bsd interfaces.
  + Added documentation of EAL API changes in release note.
  + Fixed a few rebase-related mistakes.
  + Fixed parallel build race condition reported by Luca Boccassi.
  + Grouped together commits breaking compilation:

    -> pci: introduce PCI lib and bus
    -> lib: include rte_bus_pci
    -> drivers: include rte_bus_pci
    -> test: include rte_bus_pci
    -> app/testpmd: include rte_bus_pci
    -> cryptodev: move PCI specific helpers to drivers/crypto

  Until all of them have been applied, compilation is broken.
  I am currently wondering whether merging some of them might
  be sensible.

  + Not included in this series:

    Several filesystem-related functions are currently
    private to the EAL and directly linked. This is not good,
    but the solution seems to be to have a new lib offering an FS abstraction.
    This seems an overreach for this patchset and should probably come in a
    second step.

v3:

  + Fixed .map versioning
  + merged one commit breaking the build into the main commit moving
    code around.

    Other such commits are still present, as they only break specific subsystems
    (lib, drivers, apps, cryptodev). Merging them all within the one main commit
    does not seem right.

    As such, build is still broken from

       * pci: introduce PCI lib and bus

    until

       * cryptodev: move PCI specific helpers to drivers/crypto

v4:

  + Rebased unto master, with new PCI functionalities integrated.
  + Removed the exposition of private EAL functions.
    While one commit did deal with this for one function, the issue is more
    widespread and should be fixed in a more generic way.
  + Introduced new PCI address parsing function,
    deprecating the old ones.
  + Fix conflict with bonding PMD regarding pci_addr_cmp function name.

v5:

  + Rebase unto master: fix a few compilation issues with the header change.
  + Make more PCI bus functions private.

v6: (Not sent publicly)

  + Made a mistake when formatting the patches.
  + fixed a rebase error in the commit

     bus/pci: do not expose IOVA mode getter

               ~*~

 Compilation is still broken from

    * pci: introduce PCI lib and bus

 until

    * net/bonding: use local prefix for local function

v7:

  + Fixed compilation issues with shared build
    This required exposing several private EAL symbols
    from VFIO and internal_config.

Cc: Anatoly Burakov <anatoly.burakov@intel.com>

    For VFIO

  + Squashed all commits breaking compilation into
    the single big move. compilation is stable throughout the series now.

  + Removed cryptodev commit, now based upon Declan's work (see patchset dependencies).

  + Moved PCI enhancement prior to moving code into the lib and bus.
    Thanks to Aaron Conole for the suggestion.

  + Fixed build on FreeBSD

  + Claimed ownership on librte_pci, for the time being.

v8:

  + Fix compilation issues between commits in EAL vfio related parts.
    Keep proper includes when necessary, moved a few VFIO_PCI specific
    symbols around.

  + Added drivers/bus/pci tree to MAINTAINERS file, with no owner.

This patchset depends on:

Break dependency on bus infrastructure
http://dpdk.org/ml/archives/dev/2017-October/079827.html

Gaetan Rivet (25):
  ethdev: remove useless PCI dependency
  eal: include debug header in bus source
  eal: include stdint in private header
  eal: include common header
  eal: expose rte_eal_using_phys_addrs
  eal: expose internal config elements
  eal: expose vfio symbols
  vfio: remove useless PCI headers
  vfio: check PCI dependency from within PCI code
  vfio: move PCI-related symbols out of vfio header
  pci: avoid inlining functions
  pci: avoid over-complicated macro
  pci: deprecate misnamed functions
  pci: introduce PCI address parsing function
  pci: make specialized parsing functions private
  pci: use new PCI addr comparison function
  pci: use new PCI addr parsing function
  pci: do not expose private functions
  pci: do not expose PCI match function
  pci: do not expose IOVA mode getter
  pci: use EAL exposed configuration
  net/bonding: use local prefix for local function
  pci: introduce PCI lib and bus
  doc: add notes on EAL PCI API update
  maintainers: claim maintainership of PCI lib

 MAINTAINERS                                    |   9 +
 app/test-pmd/testpmd.h                         |   1 +
 config/common_base                             |  10 +
 doc/guides/rel_notes/deprecation.rst           |   7 +
 doc/guides/rel_notes/release_17_11.rst         |  28 +
 drivers/bus/Makefile                           |   2 +
 drivers/bus/fslmc/fslmc_vfio.h                 |   2 +
 drivers/bus/pci/Makefile                       |  62 ++
 drivers/bus/pci/bsd/Makefile                   |  32 +
 drivers/bus/pci/bsd/pci.c                      | 681 ++++++++++++++++++++
 drivers/bus/pci/include/rte_bus_pci.h          | 340 ++++++++++
 drivers/bus/pci/linux/Makefile                 |  36 ++
 drivers/bus/pci/linux/pci.c                    | 826 +++++++++++++++++++++++++
 drivers/bus/pci/linux/pci_init.h               | 111 ++++
 drivers/bus/pci/linux/pci_uio.c                | 568 +++++++++++++++++
 drivers/bus/pci/linux/pci_vfio.c               | 756 ++++++++++++++++++++++
 drivers/bus/pci/pci_common.c                   | 541 ++++++++++++++++
 drivers/bus/pci/pci_common_uio.c               | 235 +++++++
 drivers/bus/pci/private.h                      | 248 ++++++++
 drivers/bus/pci/rte_bus_pci_version.map        |  17 +
 drivers/crypto/qat/Makefile                    |   1 +
 drivers/crypto/qat/qat_qp.c                    |   1 +
 drivers/crypto/qat/rte_qat_cryptodev.c         |   1 +
 drivers/event/octeontx/Makefile                |   1 +
 drivers/event/skeleton/Makefile                |   1 +
 drivers/mempool/octeontx/Makefile              |   1 +
 drivers/mempool/octeontx/octeontx_fpavf.c      |   2 +-
 drivers/mempool/octeontx/octeontx_ssovf.c      |   1 +
 drivers/net/ark/Makefile                       |   1 +
 drivers/net/ark/ark_ethdev.c                   |   1 +
 drivers/net/avp/Makefile                       |   1 +
 drivers/net/avp/avp_ethdev.c                   |   2 +
 drivers/net/bnx2x/Makefile                     |   1 +
 drivers/net/bnxt/Makefile                      |   1 +
 drivers/net/bnxt/bnxt.h                        |   1 +
 drivers/net/bonding/Makefile                   |   1 +
 drivers/net/bonding/rte_eth_bond_args.c        |   5 +-
 drivers/net/cxgbe/Makefile                     |   1 +
 drivers/net/cxgbe/base/adapter.h               |   1 +
 drivers/net/cxgbe/cxgbe_ethdev.c               |   1 +
 drivers/net/e1000/Makefile                     |   1 +
 drivers/net/e1000/em_ethdev.c                  |   1 +
 drivers/net/e1000/igb_ethdev.c                 |   1 +
 drivers/net/e1000/igb_pf.c                     |   1 +
 drivers/net/ena/Makefile                       |   1 +
 drivers/net/ena/ena_ethdev.h                   |   1 +
 drivers/net/enic/Makefile                      |   1 +
 drivers/net/enic/base/vnic_dev.h               |   4 +-
 drivers/net/enic/enic_ethdev.c                 |   1 +
 drivers/net/enic/enic_main.c                   |   1 +
 drivers/net/fm10k/Makefile                     |   1 +
 drivers/net/i40e/Makefile                      |   1 +
 drivers/net/i40e/i40e_ethdev.c                 |   1 +
 drivers/net/i40e/i40e_ethdev_vf.c              |   1 +
 drivers/net/ixgbe/Makefile                     |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c               |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.h               |   1 +
 drivers/net/liquidio/Makefile                  |   1 +
 drivers/net/mlx4/Makefile                      |   1 +
 drivers/net/mlx4/mlx4_ethdev.c                 |   1 +
 drivers/net/mlx5/Makefile                      |   1 +
 drivers/net/mlx5/mlx5.c                        |   1 +
 drivers/net/mlx5/mlx5_ethdev.c                 |   1 +
 drivers/net/nfp/Makefile                       |   1 +
 drivers/net/nfp/nfp_nfpu.c                     |   2 +-
 drivers/net/nfp/nfp_nfpu.h                     |   2 +-
 drivers/net/octeontx/Makefile                  |   1 +
 drivers/net/octeontx/base/octeontx_pkivf.c     |   2 +-
 drivers/net/octeontx/base/octeontx_pkovf.c     |   2 +-
 drivers/net/qede/Makefile                      |   1 +
 drivers/net/sfc/Makefile                       |   1 +
 drivers/net/sfc/sfc.h                          |   1 +
 drivers/net/sfc/sfc_ethdev.c                   |   1 +
 drivers/net/szedata2/Makefile                  |   1 +
 drivers/net/thunderx/Makefile                  |   1 +
 drivers/net/thunderx/nicvf_ethdev.c            |   1 +
 drivers/net/virtio/Makefile                    |   1 +
 drivers/net/virtio/virtio_ethdev.c             |   1 +
 drivers/net/virtio/virtio_pci.h                |   1 +
 drivers/net/vmxnet3/Makefile                   |   1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c           |   1 +
 lib/Makefile                                   |   2 +
 lib/librte_eal/bsdapp/eal/Makefile             |   3 -
 lib/librte_eal/bsdapp/eal/eal.c                |  58 +-
 lib/librte_eal/bsdapp/eal/eal_memory.c         |   6 +
 lib/librte_eal/bsdapp/eal/eal_pci.c            | 680 --------------------
 lib/librte_eal/common/Makefile                 |   4 +-
 lib/librte_eal/common/arch/x86/rte_cycles.c    |   2 +
 lib/librte_eal/common/eal_common_bus.c         |   1 +
 lib/librte_eal/common/eal_common_pci.c         | 579 -----------------
 lib/librte_eal/common/eal_common_pci_uio.c     | 233 -------
 lib/librte_eal/common/eal_private.h            | 144 +----
 lib/librte_eal/common/include/rte_eal.h        |  28 +
 lib/librte_eal/common/include/rte_memory.h     |  11 +
 lib/librte_eal/common/include/rte_pci.h        | 633 -------------------
 lib/librte_eal/common/include/rte_vfio.h       | 139 +++++
 lib/librte_eal/linuxapp/eal/Makefile           |   8 -
 lib/librte_eal/linuxapp/eal/eal.c              |  23 +-
 lib/librte_eal/linuxapp/eal/eal_interrupts.c   |   2 +-
 lib/librte_eal/linuxapp/eal/eal_memory.c       |   2 +-
 lib/librte_eal/linuxapp/eal/eal_pci.c          | 818 ------------------------
 lib/librte_eal/linuxapp/eal/eal_pci_init.h     |  97 ---
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c      | 567 -----------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c     | 750 ----------------------
 lib/librte_eal/linuxapp/eal/eal_vfio.c         |   1 +
 lib/librte_eal/linuxapp/eal/eal_vfio.h         |  38 --
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c |   4 +-
 lib/librte_eal/rte_eal_version.map             |  26 +-
 lib/librte_ether/rte_ethdev.c                  |   1 -
 lib/librte_ether/rte_ethdev.h                  |   2 -
 lib/librte_ether/rte_ethdev_pci.h              |   1 +
 lib/librte_eventdev/rte_eventdev_pmd_pci.h     |   1 +
 lib/librte_pci/Makefile                        |  49 ++
 lib/librte_pci/include/rte_pci.h               | 279 +++++++++
 lib/librte_pci/rte_pci.c                       | 220 +++++++
 lib/librte_pci/rte_pci_version.map             |  15 +
 mk/rte.app.mk                                  |   3 +
 test/test/test_kni.c                           |   1 +
 test/test/virtual_pmd.c                        |   1 +
 119 files changed, 5428 insertions(+), 4590 deletions(-)
 create mode 100644 drivers/bus/pci/Makefile
 create mode 100644 drivers/bus/pci/bsd/Makefile
 create mode 100644 drivers/bus/pci/bsd/pci.c
 create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
 create mode 100644 drivers/bus/pci/linux/Makefile
 create mode 100644 drivers/bus/pci/linux/pci.c
 create mode 100644 drivers/bus/pci/linux/pci_init.h
 create mode 100644 drivers/bus/pci/linux/pci_uio.c
 create mode 100644 drivers/bus/pci/linux/pci_vfio.c
 create mode 100644 drivers/bus/pci/pci_common.c
 create mode 100644 drivers/bus/pci/pci_common_uio.c
 create mode 100644 drivers/bus/pci/private.h
 create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
 delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
 delete mode 100644 lib/librte_eal/common/include/rte_pci.h
 create mode 100644 lib/librte_eal/common/include/rte_vfio.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
 create mode 100644 lib/librte_pci/Makefile
 create mode 100644 lib/librte_pci/include/rte_pci.h
 create mode 100644 lib/librte_pci/rte_pci.c
 create mode 100644 lib/librte_pci/rte_pci_version.map

-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 01/25] ethdev: remove useless PCI dependency
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
@ 2017-10-26 10:05             ` Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 02/25] eal: include debug header in bus source Gaetan Rivet
                               ` (25 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_ether/rte_ethdev.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index e0c3206..318af28 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -47,7 +47,6 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_interrupts.h>
-#include <rte_pci.h>
 #include <rte_memory.h>
 #include <rte_memcpy.h>
 #include <rte_memzone.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 02/25] eal: include debug header in bus source
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 01/25] ethdev: remove useless PCI dependency Gaetan Rivet
@ 2017-10-26 10:05             ` Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 03/25] eal: include stdint in private header Gaetan Rivet
                               ` (24 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

This header is included through rte_pci.h, which will be removed once
the PCI bus is moved out of the EAL.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_bus.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
index 5c63ced..3e022d5 100644
--- a/lib/librte_eal/common/eal_common_bus.c
+++ b/lib/librte_eal/common/eal_common_bus.c
@@ -35,6 +35,7 @@
 #include <sys/queue.h>
 
 #include <rte_bus.h>
+#include <rte_debug.h>
 
 #include "eal_private.h"
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 03/25] eal: include stdint in private header
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 01/25] ethdev: remove useless PCI dependency Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 02/25] eal: include debug header in bus source Gaetan Rivet
@ 2017-10-26 10:05             ` Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 04/25] eal: include common header Gaetan Rivet
                               ` (23 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_private.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 6e0f85d..9340b6e 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -35,6 +35,7 @@
 #define _EAL_PRIVATE_H_
 
 #include <stdbool.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <rte_pci.h>
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 04/25] eal: include common header
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (2 preceding siblings ...)
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 03/25] eal: include stdint in private header Gaetan Rivet
@ 2017-10-26 10:05             ` Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 05/25] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
                               ` (22 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

The macro RTE_SET_USED is defined in rte_common.h

This header is included through eal_private.h, which includes in turn
rte_pci.h

Once the PCI subsystem is out of the EAL, this will break the
compilation (seen on FreeBSD).

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/arch/x86/rte_cycles.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_eal/common/arch/x86/rte_cycles.c b/lib/librte_eal/common/arch/x86/rte_cycles.c
index b286d90..417850e 100644
--- a/lib/librte_eal/common/arch/x86/rte_cycles.c
+++ b/lib/librte_eal/common/arch/x86/rte_cycles.c
@@ -35,6 +35,8 @@
 #include <unistd.h>
 #include <cpuid.h>
 
+#include <rte_common.h>
+
 #include "eal_private.h"
 
 static unsigned int
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 05/25] eal: expose rte_eal_using_phys_addrs
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (3 preceding siblings ...)
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 04/25] eal: include common header Gaetan Rivet
@ 2017-10-26 10:05             ` Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 06/25] eal: expose internal config elements Gaetan Rivet
                               ` (21 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

This function was previously private to the EAL layer.
Other subsystems requires it, such as the PCI bus.

In order not to force other components to include stdbool, which is
incompatible with several NIC drivers, the return type has
been changed from bool to int.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/bsdapp/eal/eal_memory.c     |  6 ++++++
 lib/librte_eal/common/eal_private.h        | 11 -----------
 lib/librte_eal/common/include/rte_memory.h | 11 +++++++++++
 lib/librte_eal/linuxapp/eal/eal_memory.c   |  2 +-
 lib/librte_eal/rte_eal_version.map         |  1 +
 5 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal_memory.c b/lib/librte_eal/bsdapp/eal/eal_memory.c
index 3614da8..65c96b0 100644
--- a/lib/librte_eal/bsdapp/eal/eal_memory.c
+++ b/lib/librte_eal/bsdapp/eal/eal_memory.c
@@ -192,3 +192,9 @@ rte_eal_hugepage_attach(void)
 		close(fd_hugepage);
 	return -1;
 }
+
+int
+rte_eal_using_phys_addrs(void)
+{
+	return 0;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 9340b6e..80fea24 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -345,17 +345,6 @@ int rte_eal_hugepage_init(void);
 int rte_eal_hugepage_attach(void);
 
 /**
- * Returns true if the system is able to obtain
- * physical addresses. Return false if using DMA
- * addresses through an IOMMU.
- *
- * Drivers based on uio will not load unless physical
- * addresses are obtainable. It is only possible to get
- * physical addresses when running as a privileged user.
- */
-bool rte_eal_using_phys_addrs(void);
-
-/**
  * Find a bus capable of identifying a device.
  *
  * @param str
diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h
index c545963..271d2bb 100644
--- a/lib/librte_eal/common/include/rte_memory.h
+++ b/lib/librte_eal/common/include/rte_memory.h
@@ -187,6 +187,17 @@ unsigned rte_memory_get_nchannel(void);
  */
 unsigned rte_memory_get_nrank(void);
 
+/**
+ * Drivers based on uio will not load unless physical
+ * addresses are obtainable. It is only possible to get
+ * physical addresses when running as a privileged user.
+ *
+ * @return
+ *   1 if the system is able to obtain physical addresses.
+ *   0 if using DMA addresses through an IOMMU.
+ */
+int rte_eal_using_phys_addrs(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
index 187d338..ddf88c5 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -1494,7 +1494,7 @@ rte_eal_hugepage_attach(void)
 	return -1;
 }
 
-bool
+int
 rte_eal_using_phys_addrs(void)
 {
 	return phys_addrs_available;
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 8eb53ab..bcc594d 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -244,6 +244,7 @@ DPDK_17.11 {
 	rte_bus_get_iommu_class;
 	rte_eal_iova_mode;
 	rte_eal_mbuf_default_mempool_ops;
+	rte_eal_using_phys_addrs;
 	rte_lcore_has_role;
 	rte_memcpy_ptr;
 	rte_pci_get_iommu_class;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 06/25] eal: expose internal config elements
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (4 preceding siblings ...)
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 05/25] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
@ 2017-10-26 10:05             ` Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 07/25] eal: expose vfio symbols Gaetan Rivet
                               ` (20 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Some internal configuration elements set by the user on the command line
are necessary outside the EAL, when the PCI bus is detached.

Expose:
  + rte_eal_create_uio_dev
  + rte_eal_has_pci
  + rte_eal_vfio_intr_mode

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/bsdapp/eal/eal.c         | 16 ++++++++++++++++
 lib/librte_eal/common/include/rte_eal.h | 28 ++++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal.c       | 16 ++++++++++++++++
 lib/librte_eal/rte_eal_version.map      |  3 +++
 4 files changed, 63 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index e981721..d54a280 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -723,3 +723,19 @@ rte_eal_process_type(void)
 {
 	return rte_config.process_type;
 }
+
+int rte_eal_has_pci(void)
+{
+	return !internal_config.no_pci;
+}
+
+int rte_eal_create_uio_dev(void)
+{
+	return internal_config.create_uio_dev;
+}
+
+enum rte_intr_mode
+rte_eal_vfio_intr_mode(void)
+{
+	return RTE_INTR_MODE_NONE;
+}
diff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h
index 4ea2ff4..cc2636c 100644
--- a/lib/librte_eal/common/include/rte_eal.h
+++ b/lib/librte_eal/common/include/rte_eal.h
@@ -47,6 +47,8 @@
 #include <rte_config.h>
 #include <rte_bus.h>
 
+#include <rte_pci_dev_feature_defs.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -268,6 +270,32 @@ rte_set_application_usage_hook(rte_usage_hook_t usage_func);
 int rte_eal_has_hugepages(void);
 
 /**
+ * Whether EAL is using PCI bus.
+ * Disabled by --no-pci option.
+ *
+ * @return
+ *   Nonzero if the PCI bus is enabled.
+ */
+int rte_eal_has_pci(void);
+
+/**
+ * Whether the EAL was asked to create UIO device.
+ *
+ * @return
+ *   Nonzero if true.
+ */
+int rte_eal_create_uio_dev(void);
+
+/**
+ * The user-configured vfio interrupt mode.
+ *
+ * @return
+ *   Interrupt mode configured with the command line,
+ *   RTE_INTR_MODE_NONE by default.
+ */
+enum rte_intr_mode rte_eal_vfio_intr_mode(void);
+
+/**
  * A wrap API for syscall gettid.
  *
  * @return
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 02381d0..18a07b0 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -989,6 +989,22 @@ int rte_eal_has_hugepages(void)
 	return ! internal_config.no_hugetlbfs;
 }
 
+int rte_eal_has_pci(void)
+{
+	return !internal_config.no_pci;
+}
+
+int rte_eal_create_uio_dev(void)
+{
+	return internal_config.create_uio_dev;
+}
+
+enum rte_intr_mode
+rte_eal_vfio_intr_mode(void)
+{
+	return internal_config.vfio_intr_mode;
+}
+
 int
 rte_eal_check_module(const char *module_name)
 {
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index bcc594d..9f06d23 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -241,10 +241,13 @@ EXPERIMENTAL {
 DPDK_17.11 {
 	global:
 
+	rte_eal_create_uio_dev;
 	rte_bus_get_iommu_class;
+	rte_eal_has_pci;
 	rte_eal_iova_mode;
 	rte_eal_mbuf_default_mempool_ops;
 	rte_eal_using_phys_addrs;
+	rte_eal_vfio_intr_mode;
 	rte_lcore_has_role;
 	rte_memcpy_ptr;
 	rte_pci_get_iommu_class;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 07/25] eal: expose vfio symbols
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (5 preceding siblings ...)
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 06/25] eal: expose internal config elements Gaetan Rivet
@ 2017-10-26 10:05             ` Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 08/25] vfio: remove useless PCI headers Gaetan Rivet
                               ` (19 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

The following symbols are used by vfio implementations within the PCI bus.
They need to be publicly available for the PCI bus to be outside the
EAL.

  + vfio_enable;
  + vfio_is_enabled;
  + vfio_noiommu_is_enabled;
  + vfio_release_device;
  + vfio_setup_device;

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/bus/fslmc/fslmc_vfio.h                 |   2 +
 lib/librte_eal/bsdapp/eal/eal.c                |  41 ++++++++
 lib/librte_eal/common/Makefile                 |   2 +-
 lib/librte_eal/common/include/rte_vfio.h       | 139 +++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal.c              |   1 +
 lib/librte_eal/linuxapp/eal/eal_interrupts.c   |   1 +
 lib/librte_eal/linuxapp/eal/eal_pci.c          |   2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_init.h     |   4 +-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c     |   1 +
 lib/librte_eal/linuxapp/eal/eal_vfio.c         |   1 +
 lib/librte_eal/linuxapp/eal/eal_vfio.h         |  26 -----
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c |   2 +
 lib/librte_eal/rte_eal_version.map             |   5 +
 13 files changed, 197 insertions(+), 30 deletions(-)
 create mode 100644 lib/librte_eal/common/include/rte_vfio.h

diff --git a/drivers/bus/fslmc/fslmc_vfio.h b/drivers/bus/fslmc/fslmc_vfio.h
index 5470a41..b442dc0 100644
--- a/drivers/bus/fslmc/fslmc_vfio.h
+++ b/drivers/bus/fslmc/fslmc_vfio.h
@@ -34,6 +34,8 @@
 #ifndef _FSLMC_VFIO_H_
 #define _FSLMC_VFIO_H_
 
+#include <rte_vfio.h>
+
 #include "eal_vfio.h"
 
 #define DPAA2_MC_DPNI_DEVID	7
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index d54a280..af15812 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -739,3 +739,44 @@ rte_eal_vfio_intr_mode(void)
 {
 	return RTE_INTR_MODE_NONE;
 }
+
+/* dummy forward declaration. */
+struct vfio_device_info;
+
+/* dummy prototypes. */
+int vfio_setup_device(const char *sysfs_base, const char *dev_addr,
+		int *vfio_dev_fd, struct vfio_device_info *device_info);
+int vfio_release_device(const char *sysfs_base, const char *dev_addr, int fd);
+int vfio_enable(const char *modname);
+int vfio_is_enabled(const char *modname);
+int vfio_noiommu_is_enabled(void);
+
+int vfio_setup_device(__rte_unused const char *sysfs_base,
+		      __rte_unused const char *dev_addr,
+		      __rte_unused int *vfio_dev_fd,
+		      __rte_unused struct vfio_device_info *device_info)
+{
+	return -1;
+}
+
+int vfio_release_device(__rte_unused const char *sysfs_base,
+			__rte_unused const char *dev_addr,
+			__rte_unused int fd)
+{
+	return -1;
+}
+
+int vfio_enable(__rte_unused const char *modname)
+{
+	return -1;
+}
+
+int vfio_is_enabled(__rte_unused const char *modname)
+{
+	return 0;
+}
+
+int vfio_noiommu_is_enabled(void)
+{
+	return 0;
+}
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 6f5b3f3..64ff811 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -43,7 +43,7 @@ INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
-INC += rte_bitmap.h
+INC += rte_bitmap.h rte_vfio.h
 
 GENERIC_INC := rte_atomic.h rte_byteorder.h rte_cycles.h rte_prefetch.h
 GENERIC_INC += rte_spinlock.h rte_memcpy.h rte_cpuflags.h rte_rwlock.h
diff --git a/lib/librte_eal/common/include/rte_vfio.h b/lib/librte_eal/common/include/rte_vfio.h
new file mode 100644
index 0000000..a9b7057
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_vfio.h
@@ -0,0 +1,139 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND S.A. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_VFIO_H_
+#define _RTE_VFIO_H_
+
+#include <linux/vfio.h>
+
+#define VFIO_DIR "/dev/vfio"
+#define VFIO_CONTAINER_PATH "/dev/vfio/vfio"
+#define VFIO_GROUP_FMT "/dev/vfio/%u"
+#define VFIO_NOIOMMU_GROUP_FMT "/dev/vfio/noiommu-%u"
+#define VFIO_GET_REGION_ADDR(x) ((uint64_t) x << 40ULL)
+#define VFIO_GET_REGION_IDX(x) (x >> 40)
+#define VFIO_NOIOMMU_MODE      \
+	"/sys/module/vfio/parameters/enable_unsafe_noiommu_mode"
+
+/**
+ * Setup vfio_cfg for the device identified by its address.
+ * It discovers the configured I/O MMU groups or sets a new one for the device.
+ * If a new groups is assigned, the DMA mapping is performed.
+ *
+ * This function is only relevant to linux and will return
+ * an error on BSD.
+ *
+ * @param sysfs_base
+ *   sysfs path prefix.
+ *
+ * @param dev_addr
+ *   device location.
+ *
+ * @param vfio_dev_fd
+ *   VFIO fd.
+ *
+ * @param device_info
+ *   Device information.
+ *
+ * @return
+ *   0 on success.
+ *   <0 on failure.
+ *   >1 if the device cannot be managed this way.
+ */
+int vfio_setup_device(const char *sysfs_base, const char *dev_addr,
+		int *vfio_dev_fd, struct vfio_device_info *device_info);
+
+/**
+ * Release a device mapped to a VFIO-managed I/O MMU group.
+ *
+ * This function is only relevant to linux and will return
+ * an error on BSD.
+ *
+ * @param sysfs_base
+ *   sysfs path prefix.
+ *
+ * @param dev_addr
+ *   device location.
+ *
+ * @param fd
+ *   VFIO fd.
+ *
+ * @return
+ *   0 on success.
+ *   <0 on failure.
+ */
+int vfio_release_device(const char *sysfs_base, const char *dev_addr, int fd);
+
+/**
+ * Enable a VFIO-related kmod.
+ *
+ * This function is only relevant to linux and will return
+ * an error on BSD.
+ *
+ * @param modname
+ *   kernel module name.
+ *
+ * @return
+ *   0 on success.
+ *   <0 on failure.
+ */
+int vfio_enable(const char *modname);
+
+/**
+ * Check whether a VFIO-related kmod is enabled.
+ *
+ * This function is only relevant to linux and will return
+ * an error on BSD.
+ *
+ * @param modname
+ *   kernel module name.
+ *
+ * @return
+ *   !0 if true.
+ *   0 otherwise.
+ */
+int vfio_is_enabled(const char *modname);
+
+/**
+ * Whether VFIO NOIOMMU mode is enabled.
+ *
+ * This function is only relevant to linux and will return
+ * an error on BSD.
+ *
+ * @return
+ *   !0 if true.
+ *   0 otherwise.
+ */
+int vfio_noiommu_is_enabled(void);
+
+#endif /* _RTE_VFIO_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 18a07b0..bee3bbe 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -77,6 +77,7 @@
 #include <rte_version.h>
 #include <rte_atomic.h>
 #include <malloc_heap.h>
+#include <rte_vfio.h>
 
 #include "eal_private.h"
 #include "eal_thread.h"
diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
index 3e9ac41..6df63d4 100644
--- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
@@ -65,6 +65,7 @@
 #include <rte_errno.h>
 #include <rte_spinlock.h>
 #include <rte_pause.h>
+#include <rte_vfio.h>
 
 #include "eal_private.h"
 #include "eal_vfio.h"
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index b4dbf95..8682ee6 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -41,11 +41,11 @@
 #include <rte_malloc.h>
 #include <rte_devargs.h>
 #include <rte_memcpy.h>
+#include <rte_vfio.h>
 
 #include "eal_filesystem.h"
 #include "eal_private.h"
 #include "eal_pci_init.h"
-#include "eal_vfio.h"
 
 /**
  * @file
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
index ae2980d..a20783d 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_init.h
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
@@ -34,7 +34,7 @@
 #ifndef EAL_PCI_INIT_H_
 #define EAL_PCI_INIT_H_
 
-#include "eal_vfio.h"
+#include <rte_vfio.h>
 
 /** IO resource type: */
 #define IORESOURCE_IO         0x00000100
@@ -72,7 +72,7 @@ void pci_uio_ioport_write(struct rte_pci_ioport *p,
 			  const void *data, size_t len, off_t offset);
 int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
 
-#ifdef VFIO_PRESENT
+#ifdef RTE_EAL_VFIO
 
 /* access config space */
 int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
index d407c87..8fa101b 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
@@ -44,6 +44,7 @@
 #include <rte_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
+#include <rte_vfio.h>
 
 #include "eal_filesystem.h"
 #include "eal_pci_init.h"
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.c b/lib/librte_eal/linuxapp/eal/eal_vfio.c
index 3f56967..5bbcdf9 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.c
@@ -39,6 +39,7 @@
 #include <rte_log.h>
 #include <rte_memory.h>
 #include <rte_eal_memconfig.h>
+#include <rte_vfio.h>
 
 #include "eal_filesystem.h"
 #include "eal_vfio.h"
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.h b/lib/librte_eal/linuxapp/eal/eal_vfio.h
index 4bab363..8eb12db 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio.h
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.h
@@ -144,15 +144,6 @@ struct vfio_config {
 	struct vfio_group vfio_groups[VFIO_MAX_GROUPS];
 };
 
-#define VFIO_DIR "/dev/vfio"
-#define VFIO_CONTAINER_PATH "/dev/vfio/vfio"
-#define VFIO_GROUP_FMT "/dev/vfio/%u"
-#define VFIO_NOIOMMU_GROUP_FMT "/dev/vfio/noiommu-%u"
-#define VFIO_GET_REGION_ADDR(x) ((uint64_t) x << 40ULL)
-#define VFIO_GET_REGION_IDX(x) (x >> 40)
-#define VFIO_NOIOMMU_MODE      \
-	"/sys/module/vfio/parameters/enable_unsafe_noiommu_mode"
-
 /* DMA mapping function prototype.
  * Takes VFIO container fd as a parameter.
  * Returns 0 on success, -1 on error.
@@ -192,27 +183,10 @@ vfio_get_group_fd(int iommu_group_no);
 int
 clear_group(int vfio_group_fd);
 
-/**
- * Setup vfio_cfg for the device identified by its address. It discovers
- * the configured I/O MMU groups or sets a new one for the device. If a new
- * groups is assigned, the DMA mapping is performed.
- * Returns 0 on success, a negative value on failure and a positive value in
- * case the given device cannot be managed this way.
- */
-int vfio_setup_device(const char *sysfs_base, const char *dev_addr,
-		int *vfio_dev_fd, struct vfio_device_info *device_info);
-
-int vfio_release_device(const char *sysfs_base, const char *dev_addr, int fd);
-
-int vfio_enable(const char *modname);
-int vfio_is_enabled(const char *modname);
-
 int pci_vfio_is_enabled(void);
 
 int vfio_mp_sync_setup(void);
 
-int vfio_noiommu_is_enabled(void);
-
 #define SOCKET_REQ_CONTAINER 0x100
 #define SOCKET_REQ_GROUP 0x200
 #define SOCKET_CLR_GROUP 0x300
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
index 537beeb..05d63e8 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
@@ -52,9 +52,11 @@
 #include <rte_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
+#include <rte_vfio.h>
 
 #include "eal_filesystem.h"
 #include "eal_pci_init.h"
+#include "eal_vfio.h"
 #include "eal_thread.h"
 
 /**
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 9f06d23..262211a 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -252,5 +252,10 @@ DPDK_17.11 {
 	rte_memcpy_ptr;
 	rte_pci_get_iommu_class;
 	rte_pci_match;
+	vfio_enable;
+	vfio_is_enabled;
+	vfio_noiommu_is_enabled;
+	vfio_release_device;
+	vfio_setup_device;
 
 } DPDK_17.08;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 08/25] vfio: remove useless PCI headers
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (6 preceding siblings ...)
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 07/25] eal: expose vfio symbols Gaetan Rivet
@ 2017-10-26 10:05             ` Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 09/25] vfio: check PCI dependency from within PCI code Gaetan Rivet
                               ` (18 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

PCI headers are not necessary and are making this module dependent on
the PCI subsystem.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
index 05d63e8..b53ed7e 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
@@ -49,13 +49,11 @@
 #endif
 
 #include <rte_log.h>
-#include <rte_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 #include <rte_vfio.h>
 
 #include "eal_filesystem.h"
-#include "eal_pci_init.h"
 #include "eal_vfio.h"
 #include "eal_thread.h"
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 09/25] vfio: check PCI dependency from within PCI code
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (7 preceding siblings ...)
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 08/25] vfio: remove useless PCI headers Gaetan Rivet
@ 2017-10-26 10:05             ` Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 10/25] vfio: move PCI-related symbols out of vfio header Gaetan Rivet
                               ` (17 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

PCI sometimes requires vfio to be enabled.
Move the check from EAL init to PCI bus scan.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/linuxapp/eal/eal.c     | 5 -----
 lib/librte_eal/linuxapp/eal/eal_pci.c | 5 +++++
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index bee3bbe..91c3712 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -715,11 +715,6 @@ static int rte_eal_vfio_setup(void)
 		return -1;
 	vfio_enabled = vfio_is_enabled("vfio");
 
-	if (!internal_config.no_pci) {
-		if (!pci_vfio_is_enabled())
-			RTE_LOG(DEBUG, EAL, "VFIO PCI modules not loaded\n");
-	}
-
 	if (vfio_enabled) {
 
 		/* if we are primary process, create a thread to communicate with
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 8682ee6..dc65852 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -460,6 +460,11 @@ rte_pci_scan(void)
 	if (internal_config.no_pci)
 		return 0;
 
+#ifdef VFIO_PRESENT
+	if (!pci_vfio_is_enabled())
+		RTE_LOG(DEBUG, EAL, "VFIO PCI modules not loaded\n");
+#endif
+
 	dir = opendir(pci_get_sysfs_path());
 	if (dir == NULL) {
 		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 10/25] vfio: move PCI-related symbols out of vfio header
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (8 preceding siblings ...)
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 09/25] vfio: check PCI dependency from within PCI code Gaetan Rivet
@ 2017-10-26 10:05             ` Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 11/25] pci: avoid inlining functions Gaetan Rivet
                               ` (16 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

These symbols are only relevant to PCI operations.
Move them to a private PCI-related header, allowing to remove the
dependency of the PCI subsystem upon private eal_vfio.h.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/linuxapp/eal/eal_pci_init.h | 14 ++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c |  3 +--
 lib/librte_eal/linuxapp/eal/eal_vfio.h     | 12 ------------
 3 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
index a20783d..99d7a2e 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_init.h
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
@@ -34,6 +34,8 @@
 #ifndef EAL_PCI_INIT_H_
 #define EAL_PCI_INIT_H_
 
+#include <linux/version.h>
+
 #include <rte_vfio.h>
 
 /** IO resource type: */
@@ -74,6 +76,16 @@ int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
 
 #ifdef RTE_EAL_VFIO
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+#define RTE_PCI_MSIX_TABLE_BIR    0x7
+#define RTE_PCI_MSIX_TABLE_OFFSET 0xfffffff8
+#define RTE_PCI_MSIX_FLAGS_QSIZE  0x07ff
+#else
+#define RTE_PCI_MSIX_TABLE_BIR    PCI_MSIX_TABLE_BIR
+#define RTE_PCI_MSIX_TABLE_OFFSET PCI_MSIX_TABLE_OFFSET
+#define RTE_PCI_MSIX_FLAGS_QSIZE  PCI_MSIX_FLAGS_QSIZE
+#endif
+
 /* access config space */
 int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
 			 void *buf, size_t len, off_t offs);
@@ -92,6 +104,8 @@ int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
 int pci_vfio_map_resource(struct rte_pci_device *dev);
 int pci_vfio_unmap_resource(struct rte_pci_device *dev);
 
+int pci_vfio_is_enabled(void);
+
 #endif
 
 #endif /* EAL_PCI_INIT_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
index 8fa101b..19994c8 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
@@ -48,7 +48,6 @@
 
 #include "eal_filesystem.h"
 #include "eal_pci_init.h"
-#include "eal_vfio.h"
 #include "eal_private.h"
 
 /**
@@ -61,7 +60,7 @@
  * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
  */
 
-#ifdef VFIO_PRESENT
+#ifdef RTE_EAL_VFIO
 
 #define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
 #define PAGE_MASK   (~(PAGE_SIZE - 1))
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio.h b/lib/librte_eal/linuxapp/eal/eal_vfio.h
index 8eb12db..766d004 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio.h
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio.h
@@ -42,16 +42,6 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
 #include <linux/vfio.h>
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
-#define RTE_PCI_MSIX_TABLE_BIR    0x7
-#define RTE_PCI_MSIX_TABLE_OFFSET 0xfffffff8
-#define RTE_PCI_MSIX_FLAGS_QSIZE  0x07ff
-#else
-#define RTE_PCI_MSIX_TABLE_BIR    PCI_MSIX_TABLE_BIR
-#define RTE_PCI_MSIX_TABLE_OFFSET PCI_MSIX_TABLE_OFFSET
-#define RTE_PCI_MSIX_FLAGS_QSIZE  PCI_MSIX_FLAGS_QSIZE
-#endif
-
 #define RTE_VFIO_TYPE1 VFIO_TYPE1_IOMMU
 
 #ifndef VFIO_SPAPR_TCE_v2_IOMMU
@@ -183,8 +173,6 @@ vfio_get_group_fd(int iommu_group_no);
 int
 clear_group(int vfio_group_fd);
 
-int pci_vfio_is_enabled(void);
-
 int vfio_mp_sync_setup(void);
 
 #define SOCKET_REQ_CONTAINER 0x100
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 11/25] pci: avoid inlining functions
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (9 preceding siblings ...)
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 10/25] vfio: move PCI-related symbols out of vfio header Gaetan Rivet
@ 2017-10-26 10:05             ` Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 12/25] pci: avoid over-complicated macro Gaetan Rivet
                               ` (15 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Parsing operations should not happen in performance critical sections.
Headers should not propose implementations unless duly required.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_pci.c  | 68 ++++++++++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_pci.h | 69 +++------------------------------
 lib/librte_eal/rte_eal_version.map      |  4 ++
 3 files changed, 78 insertions(+), 63 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index fb92ee7..54931d1 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -87,6 +87,74 @@ static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
 	return NULL;
 }
 
+/* Macro used by pci addr parsing functions. **/
+#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                     \
+do {                                                            \
+	unsigned long val;                                      \
+	char *end;                                              \
+	errno = 0;                                              \
+	val = strtoul((in), &end, 16);                          \
+	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
+		return -EINVAL;                                 \
+	(fd) = (typeof (fd))val;                                \
+	(in) = end + 1;                                         \
+} while(0)
+
+
+int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	dev_addr->domain = 0;
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
+	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
+	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	return 0;
+}
+
+#undef GET_PCIADDR_FIELD
+
+void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+		     char *output, size_t size)
+{
+	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+			    addr->domain, addr->bus,
+			    addr->devid, addr->function) >= 0);
+}
+
+int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			   const struct rte_pci_addr *addr2)
+{
+	uint64_t dev_addr, dev_addr2;
+
+	if ((addr == NULL) || (addr2 == NULL))
+		 return -1;
+
+	dev_addr = ((uint64_t)addr->domain << 24) |
+		 (addr->bus << 16) | (addr->devid << 8) | addr->function;
+	dev_addr2 = ((uint64_t)addr2->domain << 24) |
+		 (addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+	if (dev_addr > dev_addr2)
+		 return 1;
+	else if (dev_addr < dev_addr2)
+		 return -1;
+	else
+		 return 0;
+}
+
 void
 pci_name_set(struct rte_pci_device *dev)
 {
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 1c5f469..a366f3f 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -240,19 +240,6 @@ struct mapped_pci_resource {
 /** mapped pci device list */
 TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 
-/**< Internal use only - Macro used by pci addr parsing functions **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                   \
-do {                                                               \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
-
 /**
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided without
@@ -266,15 +253,7 @@ do {                                                               \
  * @return
  *  0 on success, negative on error.
  */
-static inline int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
+int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to produce a PCI Bus-Device-Function value
@@ -288,16 +267,7 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
  * @return
  *  0 on success, negative on error.
  */
-static inline int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
-	return 0;
-}
-#undef GET_PCIADDR_FIELD
+int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
  * Utility function to write a pci device name, this device name can later be
@@ -311,17 +281,9 @@ eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
  * @param size
  *	The output buffer size
  */
-static inline void
-rte_pci_device_name(const struct rte_pci_addr *addr,
-		char *output, size_t size)
-{
-	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
-	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
-			    addr->domain, addr->bus,
-			    addr->devid, addr->function) >= 0);
-}
+void rte_pci_device_name(const struct rte_pci_addr *addr, char *output,
+			 size_t size);
 
-/* Compare two PCI device addresses. */
 /**
  * Utility function to compare two PCI device addresses.
  *
@@ -334,27 +296,8 @@ rte_pci_device_name(const struct rte_pci_addr *addr,
  *	Positive on addr is greater than addr2.
  *	Negative on addr is less than addr2, or error.
  */
-static inline int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			 const struct rte_pci_addr *addr2)
-{
-	uint64_t dev_addr, dev_addr2;
-
-	if ((addr == NULL) || (addr2 == NULL))
-		return -1;
-
-	dev_addr = ((uint64_t)addr->domain << 24) |
-		(addr->bus << 16) | (addr->devid << 8) | addr->function;
-	dev_addr2 = ((uint64_t)addr2->domain << 24) |
-		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
-
-	if (dev_addr > dev_addr2)
-		return 1;
-	else if (dev_addr < dev_addr2)
-		return -1;
-	else
-		return 0;
-}
+int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			     const struct rte_pci_addr *addr2);
 
 /**
  * Scan the content of the PCI bus, and the devices in the devices
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 262211a..f22869a 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -241,8 +241,11 @@ EXPERIMENTAL {
 DPDK_17.11 {
 	global:
 
+	eal_parse_pci_BDF;
+	eal_parse_pci_DomBDF;
 	rte_eal_create_uio_dev;
 	rte_bus_get_iommu_class;
+	rte_eal_compare_pci_addr;
 	rte_eal_has_pci;
 	rte_eal_iova_mode;
 	rte_eal_mbuf_default_mempool_ops;
@@ -250,6 +253,7 @@ DPDK_17.11 {
 	rte_eal_vfio_intr_mode;
 	rte_lcore_has_role;
 	rte_memcpy_ptr;
+	rte_pci_device_name;
 	rte_pci_get_iommu_class;
 	rte_pci_match;
 	vfio_enable;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 12/25] pci: avoid over-complicated macro
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (10 preceding siblings ...)
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 11/25] pci: avoid inlining functions Gaetan Rivet
@ 2017-10-26 10:05             ` Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 13/25] pci: deprecate misnamed functions Gaetan Rivet
                               ` (14 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Using a macro helps writing the code to the detriment of the reader
in this case. This is backward. Write once, read many.

The few LOCs gained is not worth the opacity of the implementation.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_pci.c | 67 +++++++++++++++++++++++-----------
 1 file changed, 46 insertions(+), 21 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 54931d1..f896289 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -87,42 +87,67 @@ static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
 	return NULL;
 }
 
-/* Macro used by pci addr parsing functions. **/
-#define GET_PCIADDR_FIELD(in, fd, lim, dlm)                     \
-do {                                                            \
-	unsigned long val;                                      \
-	char *end;                                              \
-	errno = 0;                                              \
-	val = strtoul((in), &end, 16);                          \
-	if (errno != 0 || end[0] != (dlm) || val > (lim))       \
-		return -EINVAL;                                 \
-	(fd) = (typeof (fd))val;                                \
-	(in) = end + 1;                                         \
-} while(0)
+static inline const char *
+get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
+{
+	unsigned long val;
+	uint8_t *u8 = _u8;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != dlm || val > UINT8_MAX) {
+		errno = errno ? errno : EINVAL;
+		return NULL;
+	}
+	*u8 = (uint8_t)val;
+	return end + 1;
+}
 
 
 int
 eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 {
+	const char *in = input;
+
 	dev_addr->domain = 0;
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
 	return 0;
 }
 
 int
 eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
 {
-	GET_PCIADDR_FIELD(input, dev_addr->domain, UINT16_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->bus, UINT8_MAX, ':');
-	GET_PCIADDR_FIELD(input, dev_addr->devid, UINT8_MAX, '.');
-	GET_PCIADDR_FIELD(input, dev_addr->function, UINT8_MAX, 0);
+	const char *in = input;
+	unsigned long val;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != ':' || val > UINT16_MAX)
+		return -EINVAL;
+	dev_addr->domain = (uint16_t)val;
+	in = end + 1;
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
 	return 0;
 }
 
-#undef GET_PCIADDR_FIELD
-
 void
 rte_pci_device_name(const struct rte_pci_addr *addr,
 		     char *output, size_t size)
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 13/25] pci: deprecate misnamed functions
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (11 preceding siblings ...)
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 12/25] pci: avoid over-complicated macro Gaetan Rivet
@ 2017-10-26 10:05             ` Gaetan Rivet
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 14/25] pci: introduce PCI address parsing function Gaetan Rivet
                               ` (13 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Rename misnamed functions and describe the change in a deprecation
notice.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst    |  9 +++++++
 lib/librte_eal/common/eal_common_pci.c  | 27 ++++++++++++++++---
 lib/librte_eal/common/include/rte_pci.h | 47 +++++++++++++++++++++++++++++++++
 lib/librte_eal/rte_eal_version.map      |  3 +++
 4 files changed, 82 insertions(+), 4 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index d07f38c..277c78d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -60,3 +60,12 @@ Deprecation Notices
 
 * librte_meter: The API will change to accommodate configuration profiles.
   Most of the API functions will have an additional opaque parameter.
+
+* pci: Several exposed functions are misnamed.
+  The following functions are deprecated starting from v17.11 and are replaced:
+
+  - ``eal_parse_pci_BDF`` replaced by ``rte_pci_bdf_parse``
+  - ``eal_parse_pci_DomBDF`` replaced by ``rte_pci_dbdf_parse``
+  - ``rte_eal_compare_pci_addr`` replaced by ``rte_pci_addr_cmp``
+
+  The functions are only renamed. Their behavior is not affected.
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index f896289..2230e09 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -106,7 +106,7 @@ get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
 
 
 int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+rte_pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 {
 	const char *in = input;
 
@@ -124,7 +124,13 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 }
 
 int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	return rte_pci_bdf_parse(input, dev_addr);
+}
+
+int
+rte_pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 {
 	const char *in = input;
 	unsigned long val;
@@ -148,6 +154,12 @@ eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
 	return 0;
 }
 
+int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	return rte_pci_dbdf_parse(input, dev_addr);
+}
+
 void
 rte_pci_device_name(const struct rte_pci_addr *addr,
 		     char *output, size_t size)
@@ -159,8 +171,8 @@ rte_pci_device_name(const struct rte_pci_addr *addr,
 }
 
 int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			   const struct rte_pci_addr *addr2)
+rte_pci_addr_cmp(const struct rte_pci_addr *addr,
+		 const struct rte_pci_addr *addr2)
 {
 	uint64_t dev_addr, dev_addr2;
 
@@ -180,6 +192,13 @@ rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 		 return 0;
 }
 
+int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			   const struct rte_pci_addr *addr2)
+{
+	return rte_pci_addr_cmp(addr, addr2);
+}
+
 void
 pci_name_set(struct rte_pci_device *dev)
 {
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index a366f3f..9ac19d5 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -253,6 +253,22 @@ TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
  * @return
  *  0 on success, negative on error.
  */
+int rte_pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided without
+ * a domain prefix (i.e. domain returned is always 0)
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned. Domain will always be
+ *	returned as 0
+ * @return
+ *  0 on success, negative on error.
+ */
 int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
@@ -267,6 +283,21 @@ int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
  * @return
  *  0 on success, negative on error.
  */
+int rte_pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided including
+ * a domain prefix.
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XXXX:XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned
+ * @return
+ *  0 on success, negative on error.
+ */
 int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
@@ -296,6 +327,22 @@ void rte_pci_device_name(const struct rte_pci_addr *addr, char *output,
  *	Positive on addr is greater than addr2.
  *	Negative on addr is less than addr2, or error.
  */
+int rte_pci_addr_cmp(const struct rte_pci_addr *addr,
+		     const struct rte_pci_addr *addr2);
+
+/**
+ * @deprecated
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
 int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 			     const struct rte_pci_addr *addr2);
 
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index f22869a..5cad972 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -253,6 +253,9 @@ DPDK_17.11 {
 	rte_eal_vfio_intr_mode;
 	rte_lcore_has_role;
 	rte_memcpy_ptr;
+	rte_pci_addr_cmp;
+	rte_pci_bdf_parse;
+	rte_pci_dbdf_parse;
 	rte_pci_device_name;
 	rte_pci_get_iommu_class;
 	rte_pci_match;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 14/25] pci: introduce PCI address parsing function
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (12 preceding siblings ...)
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 13/25] pci: deprecate misnamed functions Gaetan Rivet
@ 2017-10-26 10:05             ` Gaetan Rivet
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 15/25] pci: make specialized parsing functions private Gaetan Rivet
                               ` (12 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:05 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

A new single function that is able to parse all currently supported
format:

   * Domain-Bus-Device-Function
   *        Bus-Device-Function

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_pci.c  |  9 +++++++++
 lib/librte_eal/common/include/rte_pci.h | 14 ++++++++++++++
 lib/librte_eal/rte_eal_version.map      |  1 +
 3 files changed, 24 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 2230e09..d01b0f9 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -199,6 +199,15 @@ rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 	return rte_pci_addr_cmp(addr, addr2);
 }
 
+int
+rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr)
+{
+	if (rte_pci_bdf_parse(str, addr) == 0 ||
+	    rte_pci_dbdf_parse(str, addr) == 0)
+		return 0;
+	return -1;
+}
+
 void
 pci_name_set(struct rte_pci_device *dev)
 {
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 9ac19d5..11ba442 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -347,6 +347,20 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 			     const struct rte_pci_addr *addr2);
 
 /**
+ * Utility function to parse a string into a PCI location.
+ *
+ * @param str
+ *     The string to parse
+ * @param addr
+ *     The reference to the structure where the location
+ *     is stored.
+ * @return
+ *     0 on success
+ *     <0 otherwise
+ */
+int rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr);
+
+/**
  * Scan the content of the PCI bus, and the devices in the devices
  * list
  *
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 5cad972..3568694 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -254,6 +254,7 @@ DPDK_17.11 {
 	rte_lcore_has_role;
 	rte_memcpy_ptr;
 	rte_pci_addr_cmp;
+	rte_pci_addr_parse;
 	rte_pci_bdf_parse;
 	rte_pci_dbdf_parse;
 	rte_pci_device_name;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 15/25] pci: make specialized parsing functions private
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (13 preceding siblings ...)
  2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 14/25] pci: introduce PCI address parsing function Gaetan Rivet
@ 2017-10-26 10:06             ` Gaetan Rivet
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 16/25] pci: use new PCI addr comparison function Gaetan Rivet
                               ` (11 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:06 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Do not expose the minute implementations of PCI parsing.
This leaves only the all-purpose rte_pci_addr_parse, which is simpler to
use.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 doc/guides/rel_notes/deprecation.rst    |  6 ++----
 lib/librte_eal/common/eal_common_pci.c  |  4 ++--
 lib/librte_eal/common/include/rte_pci.h | 29 -----------------------------
 lib/librte_eal/rte_eal_version.map      |  2 --
 4 files changed, 4 insertions(+), 37 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 277c78d..d995346 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -64,8 +64,6 @@ Deprecation Notices
 * pci: Several exposed functions are misnamed.
   The following functions are deprecated starting from v17.11 and are replaced:
 
-  - ``eal_parse_pci_BDF`` replaced by ``rte_pci_bdf_parse``
-  - ``eal_parse_pci_DomBDF`` replaced by ``rte_pci_dbdf_parse``
+  - ``eal_parse_pci_BDF`` replaced by ``rte_pci_addr_parse``
+  - ``eal_parse_pci_DomBDF`` replaced by ``rte_pci_addr_parse``
   - ``rte_eal_compare_pci_addr`` replaced by ``rte_pci_addr_cmp``
-
-  The functions are only renamed. Their behavior is not affected.
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index d01b0f9..70729d2 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -105,7 +105,7 @@ get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
 }
 
 
-int
+static int
 rte_pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 {
 	const char *in = input;
@@ -129,7 +129,7 @@ eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
 	return rte_pci_bdf_parse(input, dev_addr);
 }
 
-int
+static int
 rte_pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
 {
 	const char *in = input;
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 11ba442..11ade4d 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -241,21 +241,6 @@ struct mapped_pci_resource {
 TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
 
 /**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided without
- * a domain prefix (i.e. domain returned is always 0)
- *
- * @param input
- *	The input string to be parsed. Should have the format XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned. Domain will always be
- *	returned as 0
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr);
-
-/**
  * @deprecated
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided without
@@ -272,20 +257,6 @@ int rte_pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr);
 int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
 
 /**
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided including
- * a domain prefix.
- *
- * @param input
- *	The input string to be parsed. Should have the format XXXX:XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr);
-
-/**
  * @deprecated
  * Utility function to produce a PCI Bus-Device-Function value
  * given a string representation. Assumes that the BDF is provided including
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 3568694..180eee8 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -255,8 +255,6 @@ DPDK_17.11 {
 	rte_memcpy_ptr;
 	rte_pci_addr_cmp;
 	rte_pci_addr_parse;
-	rte_pci_bdf_parse;
-	rte_pci_dbdf_parse;
 	rte_pci_device_name;
 	rte_pci_get_iommu_class;
 	rte_pci_match;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 16/25] pci: use new PCI addr comparison function
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (14 preceding siblings ...)
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 15/25] pci: make specialized parsing functions private Gaetan Rivet
@ 2017-10-26 10:06             ` Gaetan Rivet
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 17/25] pci: use new PCI addr parsing function Gaetan Rivet
                               ` (10 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:06 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/bsdapp/eal/eal_pci.c        | 2 +-
 lib/librte_eal/common/eal_common_pci.c     | 8 ++++----
 lib/librte_eal/common/eal_common_pci_uio.c | 4 ++--
 lib/librte_eal/linuxapp/eal/eal_pci.c      | 2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c | 4 ++--
 5 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 1595988..7d82195 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -323,7 +323,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
 		int ret;
 
 		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+			ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr);
 			if (ret > 0)
 				continue;
 			else if (ret < 0) {
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 70729d2..e4e42f5 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -81,7 +81,7 @@ static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
 		if (devargs->bus != pbus)
 			continue;
 		devargs->bus->parse(devargs->name, &addr);
-		if (!rte_eal_compare_pci_addr(&dev->addr, &addr))
+		if (!rte_pci_addr_cmp(&dev->addr, &addr))
 			return devargs;
 	}
 	return NULL;
@@ -194,7 +194,7 @@ rte_pci_addr_cmp(const struct rte_pci_addr *addr,
 
 int
 rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			   const struct rte_pci_addr *addr2)
+			 const struct rte_pci_addr *addr2)
 {
 	return rte_pci_addr_cmp(addr, addr2);
 }
@@ -467,7 +467,7 @@ rte_pci_probe_one(const struct rte_pci_addr *addr)
 		goto err_return;
 
 	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_eal_compare_pci_addr(&dev->addr, addr))
+		if (rte_pci_addr_cmp(&dev->addr, addr))
 			continue;
 
 		ret = pci_probe_all_drivers(dev);
@@ -497,7 +497,7 @@ rte_pci_detach(const struct rte_pci_addr *addr)
 		return -1;
 
 	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_eal_compare_pci_addr(&dev->addr, addr))
+		if (rte_pci_addr_cmp(&dev->addr, addr))
 			continue;
 
 		ret = rte_pci_detach_dev(dev);
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
index 367a681..9df3833 100644
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ b/lib/librte_eal/common/eal_common_pci_uio.c
@@ -61,7 +61,7 @@ pci_uio_map_secondary(struct rte_pci_device *dev)
 	TAILQ_FOREACH(uio_res, uio_res_list, next) {
 
 		/* skip this element if it doesn't match our PCI address */
-		if (rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+		if (rte_pci_addr_cmp(&uio_res->pci_addr, &dev->addr))
 			continue;
 
 		for (i = 0; i != uio_res->nb_maps; i++) {
@@ -187,7 +187,7 @@ pci_uio_find_resource(struct rte_pci_device *dev)
 	TAILQ_FOREACH(uio_res, uio_res_list, next) {
 
 		/* skip this element if it doesn't match our PCI address */
-		if (!rte_eal_compare_pci_addr(&uio_res->pci_addr, &dev->addr))
+		if (!rte_pci_addr_cmp(&uio_res->pci_addr, &dev->addr))
 			return uio_res;
 	}
 	return NULL;
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index dc65852..3a853a6 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -363,7 +363,7 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
 		int ret;
 
 		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+			ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr);
 			if (ret > 0)
 				continue;
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
index 19994c8..3331b13 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
@@ -576,8 +576,8 @@ pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
 
 	/* if we're in a secondary process, just find our tailq entry */
 	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-		if (rte_eal_compare_pci_addr(&vfio_res->pci_addr,
-						 &dev->addr))
+		if (rte_pci_addr_cmp(&vfio_res->pci_addr,
+				     &dev->addr))
 			continue;
 		break;
 	}
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 17/25] pci: use new PCI addr parsing function
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (15 preceding siblings ...)
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 16/25] pci: use new PCI addr comparison function Gaetan Rivet
@ 2017-10-26 10:06             ` Gaetan Rivet
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 18/25] pci: do not expose private functions Gaetan Rivet
                               ` (9 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:06 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_common_pci.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index e4e42f5..99e1765 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -599,8 +599,7 @@ pci_parse(const char *name, void *addr)
 	struct rte_pci_addr pci_addr;
 	bool parse;
 
-	parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
-		 eal_parse_pci_DomBDF(name, &pci_addr) == 0);
+	parse = (rte_pci_addr_parse(name, &pci_addr) == 0);
 	if (parse && addr != NULL)
 		*out = pci_addr;
 	return parse == false;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 18/25] pci: do not expose private functions
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (16 preceding siblings ...)
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 17/25] pci: use new PCI addr parsing function Gaetan Rivet
@ 2017-10-26 10:06             ` Gaetan Rivet
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 19/25] pci: do not expose PCI match function Gaetan Rivet
                               ` (8 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:06 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

make the functions

   + rte_pci_detach
   + rte_pci_probe
   + rte_pci_probe_one
   + rte_pci_scan

private as there is no point in using them outside of the rte_bus
framework.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_private.h     | 49 +++++++++++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_pci.h | 49 ---------------------------------
 lib/librte_eal/rte_eal_version.map      |  4 ---
 3 files changed, 49 insertions(+), 53 deletions(-)

diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 80fea24..8f949fb 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -114,6 +114,55 @@ struct rte_pci_driver;
 struct rte_pci_device;
 
 /**
+ * Probe the PCI bus
+ *
+ * @return
+ *   - 0 on success.
+ *   - !0 on error.
+ */
+int
+rte_pci_probe(void);
+
+/**
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ *
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_pci_scan(void);
+
+/**
+ * Probe the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the probe() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *     The PCI Bus-Device-Function address to probe.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_probe_one(const struct rte_pci_addr *addr);
+
+/**
+ * Close the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the remove() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *     The PCI Bus-Device-Function address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_detach(const struct rte_pci_addr *addr);
+
+/**
  * Find the name of a PCI device.
  */
 void pci_name_set(struct rte_pci_device *dev);
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 11ade4d..ca753b5 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -331,25 +331,6 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
  */
 int rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr);
 
-/**
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- *
- * @return
- *  0 on success, negative on error
- */
-int rte_pci_scan(void);
-
-/**
- * Probe the PCI bus
- *
- * @return
- *   - 0 on success.
- *   - !0 on error.
- */
-int
-rte_pci_probe(void);
-
 /*
  * Match the PCI Driver and Device using the ID Table
  *
@@ -435,36 +416,6 @@ void *pci_map_resource(void *requested_addr, int fd, off_t offset,
 void pci_unmap_resource(void *requested_addr, size_t size);
 
 /**
- * Probe the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the probe() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to probe.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_probe_one(const struct rte_pci_addr *addr);
-
-/**
- * Close the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the remove() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to close.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_detach(const struct rte_pci_addr *addr);
-
-/**
  * Dump the content of the PCI bus.
  *
  * @param f
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 180eee8..754c6c3 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -166,18 +166,14 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_pci_detach;
 	rte_pci_dump;
 	rte_pci_ioport_map;
 	rte_pci_ioport_read;
 	rte_pci_ioport_unmap;
 	rte_pci_ioport_write;
 	rte_pci_map_device;
-	rte_pci_probe;
-	rte_pci_probe_one;
 	rte_pci_read_config;
 	rte_pci_register;
-	rte_pci_scan;
 	rte_pci_unmap_device;
 	rte_pci_unregister;
 	rte_pci_write_config;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 19/25] pci: do not expose PCI match function
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (17 preceding siblings ...)
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 18/25] pci: do not expose private functions Gaetan Rivet
@ 2017-10-26 10:06             ` Gaetan Rivet
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 20/25] pci: do not expose IOVA mode getter Gaetan Rivet
                               ` (7 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:06 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

This function is private to the PCI bus.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_private.h     | 15 +++++++++++++++
 lib/librte_eal/common/include/rte_pci.h | 16 ----------------
 lib/librte_eal/rte_eal_version.map      |  1 -
 3 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 8f949fb..ea1a5be 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -290,6 +290,21 @@ void pci_uio_free_resource(struct rte_pci_device *dev,
 int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
 		struct mapped_pci_resource *uio_res, int map_idx);
 
+/*
+ * Match the PCI Driver and Device using the ID Table
+ *
+ * @param pci_drv
+ *      PCI driver from which ID table would be extracted
+ * @param pci_dev
+ *      PCI device to match against the driver
+ * @return
+ *      1 for successful match
+ *      0 for unsuccessful match
+ */
+int
+rte_pci_match(const struct rte_pci_driver *pci_drv,
+	      const struct rte_pci_device *pci_dev);
+
 /**
  * Init tail queues for non-EAL library structures. This is to allow
  * the rings, mempools, etc. lists to be shared among multiple processes
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index ca753b5..de213cc 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -331,22 +331,6 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
  */
 int rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr);
 
-/*
- * Match the PCI Driver and Device using the ID Table
- *
- * @param pci_drv
- *      PCI driver from which ID table would be extracted
- * @param pci_dev
- *      PCI device to match against the driver
- * @return
- *      1 for successful match
- *      0 for unsuccessful match
- */
-int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev);
-
-
 /**
  * Get iommu class of PCI devices on the bus.
  * And return their preferred iova mapping mode.
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 754c6c3..f2b4147 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -253,7 +253,6 @@ DPDK_17.11 {
 	rte_pci_addr_parse;
 	rte_pci_device_name;
 	rte_pci_get_iommu_class;
-	rte_pci_match;
 	vfio_enable;
 	vfio_is_enabled;
 	vfio_noiommu_is_enabled;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 20/25] pci: do not expose IOVA mode getter
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (18 preceding siblings ...)
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 19/25] pci: do not expose PCI match function Gaetan Rivet
@ 2017-10-26 10:06             ` Gaetan Rivet
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 21/25] pci: use EAL exposed configuration Gaetan Rivet
                               ` (6 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:06 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/common/eal_private.h     | 10 ++++++++++
 lib/librte_eal/common/include/rte_pci.h | 10 ----------
 lib/librte_eal/rte_eal_version.map      |  1 -
 3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index ea1a5be..4eb1bd2 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -306,6 +306,16 @@ rte_pci_match(const struct rte_pci_driver *pci_drv,
 	      const struct rte_pci_device *pci_dev);
 
 /**
+ * Get iommu class of PCI devices on the bus.
+ * And return their preferred iova mapping mode.
+ *
+ * @return
+ *   - enum rte_iova_mode.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void);
+
+/**
  * Init tail queues for non-EAL library structures. This is to allow
  * the rings, mempools, etc. lists to be shared among multiple processes
  *
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index de213cc..3c8cbd8 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -332,16 +332,6 @@ int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 int rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr);
 
 /**
- * Get iommu class of PCI devices on the bus.
- * And return their preferred iova mapping mode.
- *
- * @return
- *   - enum rte_iova_mode.
- */
-enum rte_iova_mode
-rte_pci_get_iommu_class(void);
-
-/**
  * Map the PCI device resources in user space virtual memory address
  *
  * Note that driver should not call this function when flag
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index f2b4147..8d67b67 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -252,7 +252,6 @@ DPDK_17.11 {
 	rte_pci_addr_cmp;
 	rte_pci_addr_parse;
 	rte_pci_device_name;
-	rte_pci_get_iommu_class;
 	vfio_enable;
 	vfio_is_enabled;
 	vfio_noiommu_is_enabled;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 21/25] pci: use EAL exposed configuration
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (19 preceding siblings ...)
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 20/25] pci: do not expose IOVA mode getter Gaetan Rivet
@ 2017-10-26 10:06             ` Gaetan Rivet
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 22/25] net/bonding: use local prefix for local function Gaetan Rivet
                               ` (5 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:06 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 lib/librte_eal/bsdapp/eal/eal_pci.c        |  2 +-
 lib/librte_eal/linuxapp/eal/eal_pci.c      |  2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c  |  2 +-
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c | 18 +++++++++++-------
 4 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 7d82195..e73b7cd 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -368,7 +368,7 @@ rte_pci_scan(void)
 	};
 
 	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
+	if (!rte_eal_has_pci())
 		return 0;
 
 	fd = open("/dev/pci", O_RDONLY);
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 3a853a6..cee4b94 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -457,7 +457,7 @@ rte_pci_scan(void)
 	struct rte_pci_addr addr;
 
 	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
+	if (!rte_eal_has_pci())
 		return 0;
 
 #ifdef VFIO_PRESENT
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
index b639ab9..d17837a 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
@@ -214,7 +214,7 @@ pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
 		return -1;
 
 	/* create uio device if we've been asked to */
-	if (internal_config.create_uio_dev && create &&
+	if (rte_eal_create_uio_dev() && create &&
 			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
 		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
index 3331b13..7006a1d 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
@@ -209,14 +209,18 @@ static int
 pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
 {
 	int i, ret, intr_idx;
+	enum rte_intr_mode intr_mode;
 
 	/* default to invalid index */
 	intr_idx = VFIO_PCI_NUM_IRQS;
 
+	/* Get default / configured intr_mode */
+	intr_mode = rte_eal_vfio_intr_mode();
+
 	/* get interrupt type from internal config (MSI-X by default, can be
 	 * overridden from the command line
 	 */
-	switch (internal_config.vfio_intr_mode) {
+	switch (intr_mode) {
 	case RTE_INTR_MODE_MSIX:
 		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
 		break;
@@ -240,7 +244,7 @@ pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
 		int fd = -1;
 
 		/* skip interrupt modes we don't want */
-		if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE &&
+		if (intr_mode != RTE_INTR_MODE_NONE &&
 				i != intr_idx)
 			continue;
 
@@ -256,7 +260,7 @@ pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
 		/* if this vector cannot be used with eventfd, fail if we explicitly
 		 * specified interrupt type, otherwise continue */
 		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
-			if (internal_config.vfio_intr_mode != RTE_INTR_MODE_NONE) {
+			if (intr_mode != RTE_INTR_MODE_NONE) {
 				RTE_LOG(ERR, EAL,
 						"  interrupt vector does not support eventfd!\n");
 				return -1;
@@ -277,15 +281,15 @@ pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
 
 		switch (i) {
 		case VFIO_PCI_MSIX_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSIX;
+			intr_mode = RTE_INTR_MODE_MSIX;
 			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
 			break;
 		case VFIO_PCI_MSI_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_MSI;
+			intr_mode = RTE_INTR_MODE_MSI;
 			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
 			break;
 		case VFIO_PCI_INTX_IRQ_INDEX:
-			internal_config.vfio_intr_mode = RTE_INTR_MODE_LEGACY;
+			intr_mode = RTE_INTR_MODE_LEGACY;
 			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
 			break;
 		default:
@@ -615,7 +619,7 @@ pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
 int
 pci_vfio_map_resource(struct rte_pci_device *dev)
 {
-	if (internal_config.process_type == RTE_PROC_PRIMARY)
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
 		return pci_vfio_map_resource_primary(dev);
 	else
 		return pci_vfio_map_resource_secondary(dev);
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 22/25] net/bonding: use local prefix for local function
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (20 preceding siblings ...)
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 21/25] pci: use EAL exposed configuration Gaetan Rivet
@ 2017-10-26 10:06             ` Gaetan Rivet
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 23/25] pci: introduce PCI lib and bus Gaetan Rivet
                               ` (4 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:06 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

The current name conflicts with the librte_pci naming convention.
Additionally, it is easier to use gdb when having prefixed even private
functions.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 drivers/net/bonding/rte_eth_bond_args.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index c4dcefa..ebbcc5b 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -89,7 +89,7 @@ find_port_id_by_dev_name(const char *name)
 }
 
 static inline int
-pci_addr_cmp(const struct rte_device *dev, const void *_pci_addr)
+bond_pci_addr_cmp(const struct rte_device *dev, const void *_pci_addr)
 {
 	struct rte_pci_device *pdev;
 	const struct rte_pci_addr *paddr = _pci_addr;
@@ -118,7 +118,7 @@ parse_port_id(const char *port_str)
 
 	/* try parsing as pci address, physical devices */
 	if (pci_bus->parse(port_str, &dev_addr) == 0) {
-		dev = pci_bus->find_device(NULL, pci_addr_cmp, &dev_addr);
+		dev = pci_bus->find_device(NULL, bond_pci_addr_cmp, &dev_addr);
 		if (dev == NULL) {
 			RTE_LOG(ERR, PMD, "unable to find PCI device\n");
 			return -1;
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 23/25] pci: introduce PCI lib and bus
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (21 preceding siblings ...)
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 22/25] net/bonding: use local prefix for local function Gaetan Rivet
@ 2017-10-26 10:06             ` Gaetan Rivet
  2017-10-26 15:56               ` Thomas Monjalon
  2017-10-26 17:44               ` Thomas Monjalon
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 24/25] doc: add notes on EAL PCI API update Gaetan Rivet
                               ` (3 subsequent siblings)
  26 siblings, 2 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:06 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

The PCI lib defines the types and methods allowing to use PCI elements.

The PCI bus implements a bus driver for PCI devices by constructing
rte_bus elements using the PCI lib.

Move the relevant code out of the EAL to its expected place.

Libraries, drivers, unit tests and applications are updated to use the
new rte_bus_pci.h header when necessary.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 app/test-pmd/testpmd.h                       |   1 +
 config/common_base                           |  10 +
 drivers/bus/Makefile                         |   2 +
 drivers/bus/pci/Makefile                     |  62 ++
 drivers/bus/pci/bsd/Makefile                 |  32 ++
 drivers/bus/pci/bsd/pci.c                    | 681 ++++++++++++++++++++++
 drivers/bus/pci/include/rte_bus_pci.h        | 340 +++++++++++
 drivers/bus/pci/linux/Makefile               |  36 ++
 drivers/bus/pci/linux/pci.c                  | 826 +++++++++++++++++++++++++++
 drivers/bus/pci/linux/pci_init.h             | 111 ++++
 drivers/bus/pci/linux/pci_uio.c              | 568 ++++++++++++++++++
 drivers/bus/pci/linux/pci_vfio.c             | 756 ++++++++++++++++++++++++
 drivers/bus/pci/pci_common.c                 | 541 ++++++++++++++++++
 drivers/bus/pci/pci_common_uio.c             | 235 ++++++++
 drivers/bus/pci/private.h                    | 248 ++++++++
 drivers/bus/pci/rte_bus_pci_version.map      |  17 +
 drivers/crypto/qat/Makefile                  |   1 +
 drivers/crypto/qat/qat_qp.c                  |   1 +
 drivers/crypto/qat/rte_qat_cryptodev.c       |   1 +
 drivers/event/octeontx/Makefile              |   1 +
 drivers/event/skeleton/Makefile              |   1 +
 drivers/mempool/octeontx/Makefile            |   1 +
 drivers/mempool/octeontx/octeontx_fpavf.c    |   2 +-
 drivers/mempool/octeontx/octeontx_ssovf.c    |   1 +
 drivers/net/ark/Makefile                     |   1 +
 drivers/net/ark/ark_ethdev.c                 |   1 +
 drivers/net/avp/Makefile                     |   1 +
 drivers/net/avp/avp_ethdev.c                 |   2 +
 drivers/net/bnx2x/Makefile                   |   1 +
 drivers/net/bnxt/Makefile                    |   1 +
 drivers/net/bnxt/bnxt.h                      |   1 +
 drivers/net/bonding/Makefile                 |   1 +
 drivers/net/bonding/rte_eth_bond_args.c      |   1 +
 drivers/net/cxgbe/Makefile                   |   1 +
 drivers/net/cxgbe/base/adapter.h             |   1 +
 drivers/net/cxgbe/cxgbe_ethdev.c             |   1 +
 drivers/net/e1000/Makefile                   |   1 +
 drivers/net/e1000/em_ethdev.c                |   1 +
 drivers/net/e1000/igb_ethdev.c               |   1 +
 drivers/net/e1000/igb_pf.c                   |   1 +
 drivers/net/ena/Makefile                     |   1 +
 drivers/net/ena/ena_ethdev.h                 |   1 +
 drivers/net/enic/Makefile                    |   1 +
 drivers/net/enic/base/vnic_dev.h             |   4 +-
 drivers/net/enic/enic_ethdev.c               |   1 +
 drivers/net/enic/enic_main.c                 |   1 +
 drivers/net/fm10k/Makefile                   |   1 +
 drivers/net/i40e/Makefile                    |   1 +
 drivers/net/i40e/i40e_ethdev.c               |   1 +
 drivers/net/i40e/i40e_ethdev_vf.c            |   1 +
 drivers/net/ixgbe/Makefile                   |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c             |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.h             |   1 +
 drivers/net/liquidio/Makefile                |   1 +
 drivers/net/mlx4/Makefile                    |   1 +
 drivers/net/mlx4/mlx4_ethdev.c               |   1 +
 drivers/net/mlx5/Makefile                    |   1 +
 drivers/net/mlx5/mlx5.c                      |   1 +
 drivers/net/mlx5/mlx5_ethdev.c               |   1 +
 drivers/net/nfp/Makefile                     |   1 +
 drivers/net/nfp/nfp_nfpu.c                   |   2 +-
 drivers/net/nfp/nfp_nfpu.h                   |   2 +-
 drivers/net/octeontx/Makefile                |   1 +
 drivers/net/octeontx/base/octeontx_pkivf.c   |   2 +-
 drivers/net/octeontx/base/octeontx_pkovf.c   |   2 +-
 drivers/net/qede/Makefile                    |   1 +
 drivers/net/sfc/Makefile                     |   1 +
 drivers/net/sfc/sfc.h                        |   1 +
 drivers/net/sfc/sfc_ethdev.c                 |   1 +
 drivers/net/szedata2/Makefile                |   1 +
 drivers/net/thunderx/Makefile                |   1 +
 drivers/net/thunderx/nicvf_ethdev.c          |   1 +
 drivers/net/virtio/Makefile                  |   1 +
 drivers/net/virtio/virtio_ethdev.c           |   1 +
 drivers/net/virtio/virtio_pci.h              |   1 +
 drivers/net/vmxnet3/Makefile                 |   1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c         |   1 +
 lib/Makefile                                 |   2 +
 lib/librte_eal/bsdapp/eal/Makefile           |   3 -
 lib/librte_eal/bsdapp/eal/eal.c              |   1 -
 lib/librte_eal/bsdapp/eal/eal_pci.c          | 680 ----------------------
 lib/librte_eal/common/Makefile               |   2 +-
 lib/librte_eal/common/eal_common_pci.c       | 699 -----------------------
 lib/librte_eal/common/eal_common_pci_uio.c   | 233 --------
 lib/librte_eal/common/eal_private.h          | 206 -------
 lib/librte_eal/common/include/rte_pci.h      | 533 -----------------
 lib/librte_eal/linuxapp/eal/Makefile         |   8 -
 lib/librte_eal/linuxapp/eal/eal.c            |   1 -
 lib/librte_eal/linuxapp/eal/eal_interrupts.c |   1 -
 lib/librte_eal/linuxapp/eal/eal_pci.c        | 823 --------------------------
 lib/librte_eal/linuxapp/eal/eal_pci_init.h   | 111 ----
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c    | 567 ------------------
 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c   | 754 ------------------------
 lib/librte_eal/rte_eal_version.map           |  17 -
 lib/librte_ether/rte_ethdev.h                |   2 -
 lib/librte_ether/rte_ethdev_pci.h            |   1 +
 lib/librte_eventdev/rte_eventdev_pmd_pci.h   |   1 +
 lib/librte_pci/Makefile                      |  49 ++
 lib/librte_pci/include/rte_pci.h             | 279 +++++++++
 lib/librte_pci/rte_pci.c                     | 220 +++++++
 lib/librte_pci/rte_pci_version.map           |  15 +
 mk/rte.app.mk                                |   3 +
 test/test/test_kni.c                         |   1 +
 test/test/virtual_pmd.c                      |   1 +
 104 files changed, 5103 insertions(+), 4646 deletions(-)
 create mode 100644 drivers/bus/pci/Makefile
 create mode 100644 drivers/bus/pci/bsd/Makefile
 create mode 100644 drivers/bus/pci/bsd/pci.c
 create mode 100644 drivers/bus/pci/include/rte_bus_pci.h
 create mode 100644 drivers/bus/pci/linux/Makefile
 create mode 100644 drivers/bus/pci/linux/pci.c
 create mode 100644 drivers/bus/pci/linux/pci_init.h
 create mode 100644 drivers/bus/pci/linux/pci_uio.c
 create mode 100644 drivers/bus/pci/linux/pci_vfio.c
 create mode 100644 drivers/bus/pci/pci_common.c
 create mode 100644 drivers/bus/pci/pci_common_uio.c
 create mode 100644 drivers/bus/pci/private.h
 create mode 100644 drivers/bus/pci/rte_bus_pci_version.map
 delete mode 100644 lib/librte_eal/bsdapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci.c
 delete mode 100644 lib/librte_eal/common/eal_common_pci_uio.c
 delete mode 100644 lib/librte_eal/common/include/rte_pci.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_init.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_uio.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
 create mode 100644 lib/librte_pci/Makefile
 create mode 100644 lib/librte_pci/include/rte_pci.h
 create mode 100644 lib/librte_pci/rte_pci.c
 create mode 100644 lib/librte_pci/rte_pci_version.map

diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 1e26a88..1639d27 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -35,6 +35,7 @@
 #define _TESTPMD_H_
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_gro.h>
 #include <rte_gso.h>
 
diff --git a/config/common_base b/config/common_base
index f842399..82ee754 100644
--- a/config/common_base
+++ b/config/common_base
@@ -123,6 +123,11 @@ CONFIG_RTE_EAL_PMD_PATH=""
 CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
 
 #
+# Compile the PCI library
+#
+CONFIG_RTE_LIBRTE_PCI=y
+
+#
 # Compile the argument parser library
 #
 CONFIG_RTE_LIBRTE_KVARGS=y
@@ -148,6 +153,11 @@ CONFIG_RTE_ETHDEV_PROFILE_ITT_WASTED_RX_ITERATIONS=n
 CONFIG_RTE_ETHDEV_TX_PREPARE_NOOP=n
 
 #
+# Compile PCI bus driver
+#
+CONFIG_RTE_LIBRTE_PCI_BUS=y
+
+#
 # Compile burst-oriented Amazon ENA PMD driver
 #
 CONFIG_RTE_LIBRTE_ENA_PMD=y
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 4b29e3d..a220d27 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -36,4 +36,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += dpaa
 
 DIRS-$(CONFIG_RTE_LIBRTE_FSLMC_BUS) += fslmc
 
+DIRS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/bus/pci/Makefile b/drivers/bus/pci/Makefile
new file mode 100644
index 0000000..23aad5e
--- /dev/null
+++ b/drivers/bus/pci/Makefile
@@ -0,0 +1,62 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+LIB = librte_bus_pci.a
+LIBABIVER := 1
+EXPORT_MAP := rte_bus_pci_version.map
+
+CFLAGS := -I$(SRCDIR)/include -I$(SRCDIR) $(CFLAGS)
+CFLAGS += -O3 $(WERROR_FLAGS)
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),)
+SYSTEM := linux
+endif
+ifneq ($(CONFIG_RTE_EXEC_ENV_BSDAPP),)
+SYSTEM := bsd
+endif
+
+CFLAGS += -I$(RTE_SDK)/drivers/bus/pci/$(SYSTEM)
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/$(SYSTEM)app/eal
+
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
+LDLIBS += -lrte_ethdev -lrte_pci
+
+include $(RTE_SDK)/drivers/bus/pci/$(SYSTEM)/Makefile
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) := $(addprefix $(SYSTEM)/,$(SRCS))
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci_common.c
+SRCS-$(CONFIG_RTE_LIBRTE_PCI_BUS) += pci_common_uio.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI_BUS)-include += include/rte_bus_pci.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/bus/pci/bsd/Makefile b/drivers/bus/pci/bsd/Makefile
new file mode 100644
index 0000000..4450913
--- /dev/null
+++ b/drivers/bus/pci/bsd/Makefile
@@ -0,0 +1,32 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += pci.c
diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
new file mode 100644
index 0000000..39d65c6
--- /dev/null
+++ b/drivers/bus/pci/bsd/pci.c
@@ -0,0 +1,681 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/pciio.h>
+#include <dev/pci/pcireg.h>
+
+#if defined(RTE_ARCH_X86)
+#include <machine/cpufunc.h>
+#endif
+
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_common.h>
+#include <rte_launch.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+#include <rte_debug.h>
+#include <rte_devargs.h>
+
+#include "eal_filesystem.h"
+#include "private.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in
+ * sysfs. Moreover, when a registered driver matches a device, the
+ * kernel driver currently using it is unloaded and replaced by
+ * igb_uio module, which is a very minimal userland driver for Intel
+ * network card, only providing access to PCI BAR to applications, and
+ * enabling bus master.
+ */
+
+extern struct rte_pci_bus rte_pci_bus;
+
+/* Map pci device */
+int
+rte_pci_map_device(struct rte_pci_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources */
+	switch (dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		/* map resources for devices that use uio */
+		ret = pci_uio_map_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+/* Unmap pci device */
+void
+rte_pci_unmap_device(struct rte_pci_device *dev)
+{
+	/* try unmapping the NIC resources */
+	switch (dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		/* unmap resources for devices that use uio */
+		pci_uio_unmap_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+void
+pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res)
+{
+	rte_free(uio_res);
+
+	if (dev->intr_handle.fd) {
+		close(dev->intr_handle.fd);
+		dev->intr_handle.fd = -1;
+		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	}
+}
+
+int
+pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res)
+{
+	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+
+	snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
+			dev->addr.bus, dev->addr.devid, dev->addr.function);
+
+	if (access(devname, O_RDWR) < 0) {
+		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+		return 1;
+	}
+
+	/* save fd if in primary process */
+	dev->intr_handle.fd = open(devname, O_RDWR);
+	if (dev->intr_handle.fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			devname, strerror(errno));
+		goto error;
+	}
+	dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+
+	/* allocate the mapping details for secondary processes*/
+	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
+	if (*uio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto error;
+	}
+
+	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
+	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
+
+	return 0;
+
+error:
+	pci_uio_free_resource(dev, *uio_res);
+	return -1;
+}
+
+int
+pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx)
+{
+	int fd;
+	char *devname;
+	void *mapaddr;
+	uint64_t offset;
+	uint64_t pagesz;
+	struct pci_map *maps;
+
+	maps = uio_res->maps;
+	devname = uio_res->path;
+	pagesz = sysconf(_SC_PAGESIZE);
+
+	/* allocate memory to keep path */
+	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+	if (maps[map_idx].path == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+				strerror(errno));
+		return -1;
+	}
+
+	/*
+	 * open resource file, to mmap it
+	 */
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				devname, strerror(errno));
+		goto error;
+	}
+
+	/* if matching map is found, then use it */
+	offset = res_idx * pagesz;
+	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
+			(size_t)dev->mem_resource[res_idx].len, 0);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		goto error;
+
+	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+	maps[map_idx].size = dev->mem_resource[res_idx].len;
+	maps[map_idx].addr = mapaddr;
+	maps[map_idx].offset = offset;
+	strcpy(maps[map_idx].path, devname);
+	dev->mem_resource[res_idx].addr = mapaddr;
+
+	return 0;
+
+error:
+	rte_free(maps[map_idx].path);
+	return -1;
+}
+
+static int
+pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
+{
+	struct rte_pci_device *dev;
+	struct pci_bar_io bar;
+	unsigned i, max;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL) {
+		return -1;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr.domain = conf->pc_sel.pc_domain;
+	dev->addr.bus = conf->pc_sel.pc_bus;
+	dev->addr.devid = conf->pc_sel.pc_dev;
+	dev->addr.function = conf->pc_sel.pc_func;
+
+	/* get vendor id */
+	dev->id.vendor_id = conf->pc_vendor;
+
+	/* get device id */
+	dev->id.device_id = conf->pc_device;
+
+	/* get subsystem_vendor id */
+	dev->id.subsystem_vendor_id = conf->pc_subvendor;
+
+	/* get subsystem_device id */
+	dev->id.subsystem_device_id = conf->pc_subdevice;
+
+	/* get class id */
+	dev->id.class_id = (conf->pc_class << 16) |
+			   (conf->pc_subclass << 8) |
+			   (conf->pc_progif);
+
+	/* TODO: get max_vfs */
+	dev->max_vfs = 0;
+
+	/* FreeBSD has no NUMA support (yet) */
+	dev->device.numa_node = 0;
+
+	pci_name_set(dev);
+
+	/* FreeBSD has only one pass through driver */
+	dev->kdrv = RTE_KDRV_NIC_UIO;
+
+	/* parse resources */
+	switch (conf->pc_hdr & PCIM_HDRTYPE) {
+	case PCIM_HDRTYPE_NORMAL:
+		max = PCIR_MAX_BAR_0;
+		break;
+	case PCIM_HDRTYPE_BRIDGE:
+		max = PCIR_MAX_BAR_1;
+		break;
+	case PCIM_HDRTYPE_CARDBUS:
+		max = PCIR_MAX_BAR_2;
+		break;
+	default:
+		goto skipdev;
+	}
+
+	for (i = 0; i <= max; i++) {
+		bar.pbi_sel = conf->pc_sel;
+		bar.pbi_reg = PCIR_BAR(i);
+		if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
+			continue;
+
+		dev->mem_resource[i].len = bar.pbi_length;
+		if (PCI_BAR_IO(bar.pbi_base)) {
+			dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
+			continue;
+		}
+		dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
+	}
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
+		rte_pci_add_device(dev);
+	}
+	else {
+		struct rte_pci_device *dev2 = NULL;
+		int ret;
+
+		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
+			ret = pci_addr_cmp(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+			else if (ret < 0) {
+				rte_pci_insert_device(dev2, dev);
+			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->max_vfs = dev->max_vfs;
+				pci_name_set(dev2);
+				memmove(dev2->mem_resource,
+					dev->mem_resource,
+					sizeof(dev->mem_resource));
+				free(dev);
+			}
+			return 0;
+		}
+		rte_pci_add_device(dev);
+	}
+
+	return 0;
+
+skipdev:
+	free(dev);
+	return 0;
+}
+
+/*
+ * Scan the content of the PCI bus, and add the devices in the devices
+ * list. Call pci_scan_one() for each pci entry found.
+ */
+int
+rte_pci_scan(void)
+{
+	int fd;
+	unsigned dev_count = 0;
+	struct pci_conf matches[16];
+	struct pci_conf_io conf_io = {
+			.pat_buf_len = 0,
+			.num_patterns = 0,
+			.patterns = NULL,
+			.match_buf_len = sizeof(matches),
+			.matches = &matches[0],
+	};
+
+	/* for debug purposes, PCI can be disabled */
+	if (!rte_eal_has_pci())
+		return 0;
+
+	fd = open("/dev/pci", O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	do {
+		unsigned i;
+		if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+			RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+					__func__, strerror(errno));
+			goto error;
+		}
+
+		for (i = 0; i < conf_io.num_matches; i++)
+			if (pci_scan_one(fd, &matches[i]) < 0)
+				goto error;
+
+		dev_count += conf_io.num_matches;
+	} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
+
+	close(fd);
+
+	RTE_LOG(DEBUG, EAL, "PCI scan found %u devices\n", dev_count);
+	return 0;
+
+error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/*
+ * Get iommu class of PCI devices on the bus.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void)
+{
+	/* Supports only RTE_KDRV_NIC_UIO */
+	return RTE_IOVA_PA;
+}
+
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+	int fd;
+	struct pci_conf matches[2];
+	struct pci_match_conf match = {
+		.pc_sel = {
+			.pc_domain = addr->domain,
+			.pc_bus = addr->bus,
+			.pc_dev = addr->devid,
+			.pc_func = addr->function,
+		},
+	};
+	struct pci_conf_io conf_io = {
+		.pat_buf_len = 0,
+		.num_patterns = 1,
+		.patterns = &match,
+		.match_buf_len = sizeof(matches),
+		.matches = &matches[0],
+	};
+
+	fd = open("/dev/pci", O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
+				__func__, strerror(errno));
+		goto error;
+	}
+
+	if (conf_io.num_matches != 1)
+		goto error;
+
+	if (pci_scan_one(fd, &matches[0]) < 0)
+		goto error;
+
+	close(fd);
+
+	return 0;
+
+error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/* Read PCI config space. */
+int rte_pci_read_config(const struct rte_pci_device *dev,
+		void *buf, size_t len, off_t offset)
+{
+	int fd = -1;
+	int size;
+	struct pci_io pi = {
+		.pi_sel = {
+			.pc_domain = dev->addr.domain,
+			.pc_bus = dev->addr.bus,
+			.pc_dev = dev->addr.devid,
+			.pc_func = dev->addr.function,
+		},
+		.pi_reg = offset,
+	};
+
+	fd = open("/dev/pci", O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	while (len > 0) {
+		size = (len >= 4) ? 4 : ((len >= 2) ? 2 : 1);
+		pi.pi_width = size;
+
+		if (ioctl(fd, PCIOCREAD, &pi) < 0)
+			goto error;
+		memcpy(buf, &pi.pi_data, size);
+
+		buf = (char *)buf + size;
+		pi.pi_reg += size;
+		len -= size;
+	}
+	close(fd);
+
+	return 0;
+
+ error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+/* Write PCI config space. */
+int rte_pci_write_config(const struct rte_pci_device *dev,
+		const void *buf, size_t len, off_t offset)
+{
+	int fd = -1;
+
+	struct pci_io pi = {
+		.pi_sel = {
+			.pc_domain = dev->addr.domain,
+			.pc_bus = dev->addr.bus,
+			.pc_dev = dev->addr.devid,
+			.pc_func = dev->addr.function,
+		},
+		.pi_reg = offset,
+		.pi_data = *(const uint32_t *)buf,
+		.pi_width = len,
+	};
+
+	if (len == 3 || len > sizeof(pi.pi_data)) {
+		RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__);
+		goto error;
+	}
+
+	memcpy(&pi.pi_data, buf, len);
+
+	fd = open("/dev/pci", O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
+		goto error;
+	}
+
+	if (ioctl(fd, PCIOCWRITE, &pi) < 0)
+		goto error;
+
+	close(fd);
+	return 0;
+
+ error:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+int
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p)
+{
+	int ret;
+
+	switch (dev->kdrv) {
+#if defined(RTE_ARCH_X86)
+	case RTE_KDRV_NIC_UIO:
+		if ((uintptr_t) dev->mem_resource[bar].addr <= UINT16_MAX) {
+			p->base = (uintptr_t)dev->mem_resource[bar].addr;
+			ret = 0;
+		} else
+			ret = -1;
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	if (!ret)
+		p->dev = dev;
+
+	return ret;
+}
+
+static void
+pci_uio_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+#if defined(RTE_ARCH_X86)
+	uint8_t *d;
+	int size;
+	unsigned short reg = p->base + offset;
+
+	for (d = data; len > 0; d += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+			*(uint32_t *)d = inl(reg);
+		} else if (len >= 2) {
+			size = 2;
+			*(uint16_t *)d = inw(reg);
+		} else {
+			size = 1;
+			*d = inb(reg);
+		}
+	}
+#else
+	RTE_SET_USED(p);
+	RTE_SET_USED(data);
+	RTE_SET_USED(len);
+	RTE_SET_USED(offset);
+#endif
+}
+
+void
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+pci_uio_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+#if defined(RTE_ARCH_X86)
+	const uint8_t *s;
+	int size;
+	unsigned short reg = p->base + offset;
+
+	for (s = data; len > 0; s += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+			outl(reg, *(const uint32_t *)s);
+		} else if (len >= 2) {
+			size = 2;
+			outw(reg, *(const uint16_t *)s);
+		} else {
+			size = 1;
+			outb(reg, *s);
+		}
+	}
+#else
+	RTE_SET_USED(p);
+	RTE_SET_USED(data);
+	RTE_SET_USED(len);
+	RTE_SET_USED(offset);
+#endif
+}
+
+void
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+	case RTE_KDRV_NIC_UIO:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	default:
+		break;
+	}
+}
+
+int
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
+{
+	int ret;
+
+	switch (p->dev->kdrv) {
+#if defined(RTE_ARCH_X86)
+	case RTE_KDRV_NIC_UIO:
+		ret = 0;
+		break;
+#endif
+	default:
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/bus/pci/include/rte_bus_pci.h b/drivers/bus/pci/include/rte_bus_pci.h
new file mode 100644
index 0000000..c0b619f
--- /dev/null
+++ b/drivers/bus/pci/include/rte_bus_pci.h
@@ -0,0 +1,340 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_BUS_PCI_H_
+#define _RTE_BUS_PCI_H_
+
+/**
+ * @file
+ *
+ * RTE PCI Bus Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+#include <rte_dev.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+
+/** Pathname of PCI devices directory. */
+const char *pci_get_sysfs_path(void);
+
+/* Forward declarations */
+struct rte_pci_device;
+struct rte_pci_driver;
+
+/** List of PCI devices */
+TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
+/** List of PCI drivers */
+TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
+
+/* PCI Bus iterators */
+#define FOREACH_DEVICE_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
+
+#define FOREACH_DRIVER_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
+
+struct rte_devargs;
+
+/**
+ * A structure describing a PCI device.
+ */
+struct rte_pci_device {
+	TAILQ_ENTRY(rte_pci_device) next;   /**< Next probed PCI device. */
+	struct rte_device device;           /**< Inherit core device */
+	struct rte_pci_addr addr;           /**< PCI location. */
+	struct rte_pci_id id;               /**< PCI ID. */
+	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
+					    /**< PCI Memory Resource */
+	struct rte_intr_handle intr_handle; /**< Interrupt handle */
+	struct rte_pci_driver *driver;      /**< Associated driver */
+	uint16_t max_vfs;                   /**< sriov enable if not zero */
+	enum rte_kernel_driver kdrv;        /**< Kernel driver passthrough */
+	char name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */
+};
+
+/**
+ * @internal
+ * Helper macro for drivers that need to convert to struct rte_pci_device.
+ */
+#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
+
+#define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
+
+/** Any PCI device identifier (vendor, device, ...) */
+#define PCI_ANY_ID (0xffff)
+#define RTE_CLASS_ANY_ID (0xffffff)
+
+#ifdef __cplusplus
+/** C++ macro used to help building up tables of device IDs */
+#define RTE_PCI_DEVICE(vend, dev) \
+	RTE_CLASS_ANY_ID,         \
+	(vend),                   \
+	(dev),                    \
+	PCI_ANY_ID,               \
+	PCI_ANY_ID
+#else
+/** Macro used to help building up tables of device IDs */
+#define RTE_PCI_DEVICE(vend, dev)          \
+	.class_id = RTE_CLASS_ANY_ID,      \
+	.vendor_id = (vend),               \
+	.device_id = (dev),                \
+	.subsystem_vendor_id = PCI_ANY_ID, \
+	.subsystem_device_id = PCI_ANY_ID
+#endif
+
+/**
+ * Initialisation function for the driver called during PCI probing.
+ */
+typedef int (pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
+
+/**
+ * Uninitialisation function for the driver called during hotplugging.
+ */
+typedef int (pci_remove_t)(struct rte_pci_device *);
+
+/**
+ * A structure describing a PCI driver.
+ */
+struct rte_pci_driver {
+	TAILQ_ENTRY(rte_pci_driver) next;  /**< Next in list. */
+	struct rte_driver driver;          /**< Inherit core driver. */
+	struct rte_pci_bus *bus;           /**< PCI bus reference. */
+	pci_probe_t *probe;                /**< Device Probe function. */
+	pci_remove_t *remove;              /**< Device Remove function. */
+	const struct rte_pci_id *id_table; /**< ID table, NULL terminated. */
+	uint32_t drv_flags;                /**< Flags contolling handling of device. */
+};
+
+/**
+ * Structure describing the PCI bus
+ */
+struct rte_pci_bus {
+	struct rte_bus bus;               /**< Inherit the generic class */
+	struct rte_pci_device_list device_list;  /**< List of PCI devices */
+	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
+};
+
+/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
+#define RTE_PCI_DRV_NEED_MAPPING 0x0001
+/** Device driver supports link state interrupt */
+#define RTE_PCI_DRV_INTR_LSC	0x0008
+/** Device driver supports device removal interrupt */
+#define RTE_PCI_DRV_INTR_RMV 0x0010
+/** Device driver needs to keep mapped resources if unsupported dev detected */
+#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
+/** Device driver supports IOVA as VA */
+#define RTE_PCI_DRV_IOVA_AS_VA 0X0040
+
+/**
+ * Map the PCI device resources in user space virtual memory address
+ *
+ * Note that driver should not call this function when flag
+ * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for
+ * you when it's on.
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ *
+ * @return
+ *   0 on success, negative on error and positive if no driver
+ *   is found for the device.
+ */
+int rte_pci_map_device(struct rte_pci_device *dev);
+
+/**
+ * Unmap this device
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ */
+void rte_pci_unmap_device(struct rte_pci_device *dev);
+
+/**
+ * Dump the content of the PCI bus.
+ *
+ * @param f
+ *   A pointer to a file for output
+ */
+void rte_pci_dump(FILE *f);
+
+/**
+ * Register a PCI driver.
+ *
+ * @param driver
+ *   A pointer to a rte_pci_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_pci_register(struct rte_pci_driver *driver);
+
+/** Helper for PCI device registration from driver (eth, crypto) instance */
+#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
+RTE_INIT(pciinitfn_ ##nm); \
+static void pciinitfn_ ##nm(void) \
+{\
+	(pci_drv).driver.name = RTE_STR(nm);\
+	rte_pci_register(&pci_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a PCI driver.
+ *
+ * @param driver
+ *   A pointer to a rte_pci_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_pci_unregister(struct rte_pci_driver *driver);
+
+/**
+ * Read PCI config space.
+ *
+ * @param device
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ * @param buf
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into PCI config space
+ */
+int rte_pci_read_config(const struct rte_pci_device *device,
+		void *buf, size_t len, off_t offset);
+
+/**
+ * Write PCI config space.
+ *
+ * @param device
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use
+ * @param buf
+ *   A data buffer containing the bytes should be written
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into PCI config space
+ */
+int rte_pci_write_config(const struct rte_pci_device *device,
+		const void *buf, size_t len, off_t offset);
+
+/**
+ * A structure used to access io resources for a pci device.
+ * rte_pci_ioport is arch, os, driver specific, and should not be used outside
+ * of pci ioport api.
+ */
+struct rte_pci_ioport {
+	struct rte_pci_device *dev;
+	uint64_t base;
+	uint64_t len; /* only filled for memory mapped ports */
+};
+
+/**
+ * Initialize a rte_pci_ioport object for a pci device io resource.
+ *
+ * This object is then used to gain access to those io resources (see below).
+ *
+ * @param dev
+ *   A pointer to a rte_pci_device structure describing the device
+ *   to use.
+ * @param bar
+ *   Index of the io pci resource we want to access.
+ * @param p
+ *   The rte_pci_ioport object to be initialized.
+ * @return
+ *  0 on success, negative on error.
+ */
+int rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p);
+
+/**
+ * Release any resources used in a rte_pci_ioport object.
+ *
+ * @param p
+ *   The rte_pci_ioport object to be uninitialized.
+ * @return
+ *  0 on success, negative on error.
+ */
+int rte_pci_ioport_unmap(struct rte_pci_ioport *p);
+
+/**
+ * Read from a io pci resource.
+ *
+ * @param p
+ *   The rte_pci_ioport object from which we want to read.
+ * @param data
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into the pci io resource.
+ */
+void rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset);
+
+/**
+ * Write to a io pci resource.
+ *
+ * @param p
+ *   The rte_pci_ioport object to which we want to write.
+ * @param data
+ *   A data buffer where the bytes should be read into
+ * @param len
+ *   The length of the data buffer.
+ * @param offset
+ *   The offset into the pci io resource.
+ */
+void rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_BUS_PCI_H_ */
diff --git a/drivers/bus/pci/linux/Makefile b/drivers/bus/pci/linux/Makefile
new file mode 100644
index 0000000..77c5f97
--- /dev/null
+++ b/drivers/bus/pci/linux/Makefile
@@ -0,0 +1,36 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SRCS += pci.c
+SRCS += pci_uio.c
+SRCS += pci_vfio.c
+
+CFLAGS += -D_GNU_SOURCE
diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c
new file mode 100644
index 0000000..6faeace
--- /dev/null
+++ b/drivers/bus/pci/linux/pci.c
@@ -0,0 +1,826 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <dirent.h>
+
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+#include <rte_devargs.h>
+#include <rte_memcpy.h>
+#include <rte_vfio.h>
+
+#include "eal_private.h"
+#include "eal_filesystem.h"
+
+#include "private.h"
+#include "pci_init.h"
+
+/**
+ * @file
+ * PCI probing under linux
+ *
+ * This code is used to simulate a PCI probe by parsing information in sysfs.
+ * When a registered device matches a driver, it is then initialized with
+ * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
+ */
+
+extern struct rte_pci_bus rte_pci_bus;
+
+static int
+pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
+{
+	int count;
+	char path[PATH_MAX];
+	char *name;
+
+	if (!filename || !dri_name)
+		return -1;
+
+	count = readlink(filename, path, PATH_MAX);
+	if (count >= PATH_MAX)
+		return -1;
+
+	/* For device does not have a driver */
+	if (count < 0)
+		return 1;
+
+	path[count] = '\0';
+
+	name = strrchr(path, '/');
+	if (name) {
+		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
+		return 0;
+	}
+
+	return -1;
+}
+
+/* Map pci device */
+int
+rte_pci_map_device(struct rte_pci_device *dev)
+{
+	int ret = -1;
+
+	/* try mapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_map_resource(dev);
+#endif
+		break;
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+		if (rte_eal_using_phys_addrs()) {
+			/* map resources for devices that use uio */
+			ret = pci_uio_map_resource(dev);
+		}
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		ret = 1;
+		break;
+	}
+
+	return ret;
+}
+
+/* Unmap pci device */
+void
+rte_pci_unmap_device(struct rte_pci_device *dev)
+{
+	/* try unmapping the NIC resources using VFIO if it exists */
+	switch (dev->kdrv) {
+	case RTE_KDRV_VFIO:
+#ifdef VFIO_PRESENT
+		if (pci_vfio_is_enabled())
+			pci_vfio_unmap_resource(dev);
+#endif
+		break;
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+		/* unmap resources for devices that use uio */
+		pci_uio_unmap_resource(dev);
+		break;
+	default:
+		RTE_LOG(DEBUG, EAL,
+			"  Not managed by a supported kernel driver, skipped\n");
+		break;
+	}
+}
+
+void *
+pci_find_max_end_va(void)
+{
+	const struct rte_memseg *seg = rte_eal_get_physmem_layout();
+	const struct rte_memseg *last = seg;
+	unsigned i = 0;
+
+	for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
+		if (seg->addr == NULL)
+			break;
+
+		if (seg->addr > last->addr)
+			last = seg;
+
+	}
+	return RTE_PTR_ADD(last->addr, last->len);
+}
+
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int
+pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+	uint64_t *end_addr, uint64_t *flags)
+{
+	union pci_resource_info {
+		struct {
+			char *phys_addr;
+			char *end_addr;
+			char *flags;
+		};
+		char *ptrs[PCI_RESOURCE_FMT_NVAL];
+	} res_info;
+
+	if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
+		RTE_LOG(ERR, EAL,
+			"%s(): bad resource format\n", __func__);
+		return -1;
+	}
+	errno = 0;
+	*phys_addr = strtoull(res_info.phys_addr, NULL, 16);
+	*end_addr = strtoull(res_info.end_addr, NULL, 16);
+	*flags = strtoull(res_info.flags, NULL, 16);
+	if (errno != 0) {
+		RTE_LOG(ERR, EAL,
+			"%s(): bad resource format\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
+
+/* parse the "resource" sysfs file */
+static int
+pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
+{
+	FILE *f;
+	char buf[BUFSIZ];
+	int i;
+	uint64_t phys_addr, end_addr, flags;
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
+		return -1;
+	}
+
+	for (i = 0; i<PCI_MAX_RESOURCE; i++) {
+
+		if (fgets(buf, sizeof(buf), f) == NULL) {
+			RTE_LOG(ERR, EAL,
+				"%s(): cannot read resource\n", __func__);
+			goto error;
+		}
+		if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+				&end_addr, &flags) < 0)
+			goto error;
+
+		if (flags & IORESOURCE_MEM) {
+			dev->mem_resource[i].phys_addr = phys_addr;
+			dev->mem_resource[i].len = end_addr - phys_addr + 1;
+			/* not mapped for now */
+			dev->mem_resource[i].addr = NULL;
+		}
+	}
+	fclose(f);
+	return 0;
+
+error:
+	fclose(f);
+	return -1;
+}
+
+/* Scan one pci sysfs entry, and fill the devices list from it. */
+static int
+pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
+{
+	char filename[PATH_MAX];
+	unsigned long tmp;
+	struct rte_pci_device *dev;
+	char driver[PATH_MAX];
+	int ret;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL)
+		return -1;
+
+	memset(dev, 0, sizeof(*dev));
+	dev->addr = *addr;
+
+	/* get vendor id */
+	snprintf(filename, sizeof(filename), "%s/vendor", dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.vendor_id = (uint16_t)tmp;
+
+	/* get device id */
+	snprintf(filename, sizeof(filename), "%s/device", dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.device_id = (uint16_t)tmp;
+
+	/* get subsystem_vendor id */
+	snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.subsystem_vendor_id = (uint16_t)tmp;
+
+	/* get subsystem_device id */
+	snprintf(filename, sizeof(filename), "%s/subsystem_device",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	dev->id.subsystem_device_id = (uint16_t)tmp;
+
+	/* get class_id */
+	snprintf(filename, sizeof(filename), "%s/class",
+		 dirname);
+	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+		free(dev);
+		return -1;
+	}
+	/* the least 24 bits are valid: class, subclass, program interface */
+	dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
+
+	/* get max_vfs */
+	dev->max_vfs = 0;
+	snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
+	if (!access(filename, F_OK) &&
+	    eal_parse_sysfs_value(filename, &tmp) == 0)
+		dev->max_vfs = (uint16_t)tmp;
+	else {
+		/* for non igb_uio driver, need kernel version >= 3.8 */
+		snprintf(filename, sizeof(filename),
+			 "%s/sriov_numvfs", dirname);
+		if (!access(filename, F_OK) &&
+		    eal_parse_sysfs_value(filename, &tmp) == 0)
+			dev->max_vfs = (uint16_t)tmp;
+	}
+
+	/* get numa node, default to 0 if not present */
+	snprintf(filename, sizeof(filename), "%s/numa_node",
+		 dirname);
+
+	if (access(filename, F_OK) != -1) {
+		if (eal_parse_sysfs_value(filename, &tmp) == 0)
+			dev->device.numa_node = tmp;
+		else
+			dev->device.numa_node = -1;
+	} else {
+		dev->device.numa_node = 0;
+	}
+
+	pci_name_set(dev);
+
+	/* parse resources */
+	snprintf(filename, sizeof(filename), "%s/resource", dirname);
+	if (pci_parse_sysfs_resource(filename, dev) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
+		free(dev);
+		return -1;
+	}
+
+	/* parse driver */
+	snprintf(filename, sizeof(filename), "%s/driver", dirname);
+	ret = pci_get_kernel_driver_by_path(filename, driver);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
+		free(dev);
+		return -1;
+	}
+
+	if (!ret) {
+		if (!strcmp(driver, "vfio-pci"))
+			dev->kdrv = RTE_KDRV_VFIO;
+		else if (!strcmp(driver, "igb_uio"))
+			dev->kdrv = RTE_KDRV_IGB_UIO;
+		else if (!strcmp(driver, "uio_pci_generic"))
+			dev->kdrv = RTE_KDRV_UIO_GENERIC;
+		else
+			dev->kdrv = RTE_KDRV_UNKNOWN;
+	} else
+		dev->kdrv = RTE_KDRV_NONE;
+
+	/* device is valid, add in list (sorted) */
+	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
+		rte_pci_add_device(dev);
+	} else {
+		struct rte_pci_device *dev2;
+		int ret;
+
+		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
+			ret = pci_addr_cmp(&dev->addr, &dev2->addr);
+			if (ret > 0)
+				continue;
+
+			if (ret < 0) {
+				rte_pci_insert_device(dev2, dev);
+			} else { /* already registered */
+				dev2->kdrv = dev->kdrv;
+				dev2->max_vfs = dev->max_vfs;
+				pci_name_set(dev2);
+				memmove(dev2->mem_resource, dev->mem_resource,
+					sizeof(dev->mem_resource));
+				free(dev);
+			}
+			return 0;
+		}
+
+		rte_pci_add_device(dev);
+	}
+
+	return 0;
+}
+
+int
+pci_update_device(const struct rte_pci_addr *addr)
+{
+	char filename[PATH_MAX];
+
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
+		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
+		 addr->function);
+
+	return pci_scan_one(filename, addr);
+}
+
+/*
+ * split up a pci address into its constituent parts.
+ */
+static int
+parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
+{
+	/* first split on ':' */
+	union splitaddr {
+		struct {
+			char *domain;
+			char *bus;
+			char *devid;
+			char *function;
+		};
+		char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
+	} splitaddr;
+
+	char *buf_copy = strndup(buf, bufsize);
+	if (buf_copy == NULL)
+		return -1;
+
+	if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
+			!= PCI_FMT_NVAL - 1)
+		goto error;
+	/* final split is on '.' between devid and function */
+	splitaddr.function = strchr(splitaddr.devid,'.');
+	if (splitaddr.function == NULL)
+		goto error;
+	*splitaddr.function++ = '\0';
+
+	/* now convert to int values */
+	errno = 0;
+	addr->domain = strtoul(splitaddr.domain, NULL, 16);
+	addr->bus = strtoul(splitaddr.bus, NULL, 16);
+	addr->devid = strtoul(splitaddr.devid, NULL, 16);
+	addr->function = strtoul(splitaddr.function, NULL, 10);
+	if (errno != 0)
+		goto error;
+
+	free(buf_copy); /* free the copy made with strdup */
+	return 0;
+error:
+	free(buf_copy);
+	return -1;
+}
+
+/*
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ */
+int
+rte_pci_scan(void)
+{
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+	struct rte_pci_addr addr;
+
+	/* for debug purposes, PCI can be disabled */
+	if (!rte_eal_has_pci())
+		return 0;
+
+#ifdef VFIO_PRESENT
+	if (!pci_vfio_is_enabled())
+		RTE_LOG(DEBUG, EAL, "VFIO PCI modules not loaded\n");
+#endif
+
+	dir = opendir(pci_get_sysfs_path());
+	if (dir == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (e->d_name[0] == '.')
+			continue;
+
+		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
+			continue;
+
+		snprintf(dirname, sizeof(dirname), "%s/%s",
+				pci_get_sysfs_path(), e->d_name);
+
+		if (pci_scan_one(dirname, &addr) < 0)
+			goto error;
+	}
+	closedir(dir);
+	return 0;
+
+error:
+	closedir(dir);
+	return -1;
+}
+
+/*
+ * Is pci device bound to any kdrv
+ */
+static inline int
+pci_one_device_is_bound(void)
+{
+	struct rte_pci_device *dev = NULL;
+	int ret = 0;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (dev->kdrv == RTE_KDRV_UNKNOWN ||
+		    dev->kdrv == RTE_KDRV_NONE) {
+			continue;
+		} else {
+			ret = 1;
+			break;
+		}
+	}
+	return ret;
+}
+
+/*
+ * Any one of the device bound to uio
+ */
+static inline int
+pci_one_device_bound_uio(void)
+{
+	struct rte_pci_device *dev = NULL;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (dev->kdrv == RTE_KDRV_IGB_UIO ||
+		   dev->kdrv == RTE_KDRV_UIO_GENERIC) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * Any one of the device has iova as va
+ */
+static inline int
+pci_one_device_has_iova_va(void)
+{
+	struct rte_pci_device *dev = NULL;
+	struct rte_pci_driver *drv = NULL;
+
+	FOREACH_DRIVER_ON_PCIBUS(drv) {
+		if (drv && drv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) {
+			FOREACH_DEVICE_ON_PCIBUS(dev) {
+				if (dev->kdrv == RTE_KDRV_VFIO &&
+				    rte_pci_match(drv, dev))
+					return 1;
+			}
+		}
+	}
+	return 0;
+}
+
+/*
+ * Get iommu class of PCI devices on the bus.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void)
+{
+	bool is_bound;
+	bool is_vfio_noiommu_enabled = true;
+	bool has_iova_va;
+	bool is_bound_uio;
+
+	is_bound = pci_one_device_is_bound();
+	if (!is_bound)
+		return RTE_IOVA_DC;
+
+	has_iova_va = pci_one_device_has_iova_va();
+	is_bound_uio = pci_one_device_bound_uio();
+#ifdef VFIO_PRESENT
+	is_vfio_noiommu_enabled = vfio_noiommu_is_enabled() == true ?
+					true : false;
+#endif
+
+	if (has_iova_va && !is_bound_uio && !is_vfio_noiommu_enabled)
+		return RTE_IOVA_VA;
+
+	if (has_iova_va) {
+		RTE_LOG(WARNING, EAL, "Some devices want iova as va but pa will be used because.. ");
+		if (is_vfio_noiommu_enabled)
+			RTE_LOG(WARNING, EAL, "vfio-noiommu mode configured\n");
+		if (is_bound_uio)
+			RTE_LOG(WARNING, EAL, "few device bound to UIO\n");
+	}
+
+	return RTE_IOVA_PA;
+}
+
+/* Read PCI config space. */
+int rte_pci_read_config(const struct rte_pci_device *device,
+		void *buf, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &device->intr_handle;
+
+	switch (intr_handle->type) {
+	case RTE_INTR_HANDLE_UIO:
+	case RTE_INTR_HANDLE_UIO_INTX:
+		return pci_uio_read_config(intr_handle, buf, len, offset);
+
+#ifdef VFIO_PRESENT
+	case RTE_INTR_HANDLE_VFIO_MSIX:
+	case RTE_INTR_HANDLE_VFIO_MSI:
+	case RTE_INTR_HANDLE_VFIO_LEGACY:
+		return pci_vfio_read_config(intr_handle, buf, len, offset);
+#endif
+	default:
+		RTE_LOG(ERR, EAL,
+			"Unknown handle type of fd %d\n",
+					intr_handle->fd);
+		return -1;
+	}
+}
+
+/* Write PCI config space. */
+int rte_pci_write_config(const struct rte_pci_device *device,
+		const void *buf, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &device->intr_handle;
+
+	switch (intr_handle->type) {
+	case RTE_INTR_HANDLE_UIO:
+	case RTE_INTR_HANDLE_UIO_INTX:
+		return pci_uio_write_config(intr_handle, buf, len, offset);
+
+#ifdef VFIO_PRESENT
+	case RTE_INTR_HANDLE_VFIO_MSIX:
+	case RTE_INTR_HANDLE_VFIO_MSI:
+	case RTE_INTR_HANDLE_VFIO_LEGACY:
+		return pci_vfio_write_config(intr_handle, buf, len, offset);
+#endif
+	default:
+		RTE_LOG(ERR, EAL,
+			"Unknown handle type of fd %d\n",
+					intr_handle->fd);
+		return -1;
+	}
+}
+
+#if defined(RTE_ARCH_X86)
+static int
+pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
+		struct rte_pci_ioport *p)
+{
+	uint16_t start, end;
+	FILE *fp;
+	char *line = NULL;
+	char pci_id[16];
+	int found = 0;
+	size_t linesz;
+
+	snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
+		 dev->addr.domain, dev->addr.bus,
+		 dev->addr.devid, dev->addr.function);
+
+	fp = fopen("/proc/ioports", "r");
+	if (fp == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);
+		return -1;
+	}
+
+	while (getdelim(&line, &linesz, '\n', fp) > 0) {
+		char *ptr = line;
+		char *left;
+		int n;
+
+		n = strcspn(ptr, ":");
+		ptr[n] = 0;
+		left = &ptr[n + 1];
+
+		while (*left && isspace(*left))
+			left++;
+
+		if (!strncmp(left, pci_id, strlen(pci_id))) {
+			found = 1;
+
+			while (*ptr && isspace(*ptr))
+				ptr++;
+
+			sscanf(ptr, "%04hx-%04hx", &start, &end);
+
+			break;
+		}
+	}
+
+	free(line);
+	fclose(fp);
+
+	if (!found)
+		return -1;
+
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	p->base = start;
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
+
+	return 0;
+}
+#endif
+
+int
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+		struct rte_pci_ioport *p)
+{
+	int ret = -1;
+
+	switch (dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_ioport_map(dev, bar, p);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		ret = pci_uio_ioport_map(dev, bar, p);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+		ret = pci_ioport_map(dev, bar, p);
+#else
+		ret = pci_uio_ioport_map(dev, bar, p);
+#endif
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		ret = pci_ioport_map(dev, bar, p);
+#endif
+		break;
+	default:
+		break;
+	}
+
+	if (!ret)
+		p->dev = dev;
+
+	return ret;
+}
+
+void
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+		void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		pci_vfio_ioport_read(p, data, len, offset);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+		pci_uio_ioport_read(p, data, len, offset);
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		pci_uio_ioport_read(p, data, len, offset);
+#endif
+		break;
+	default:
+		break;
+	}
+}
+
+void
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+		const void *data, size_t len, off_t offset)
+{
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		pci_vfio_ioport_write(p, data, len, offset);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+		pci_uio_ioport_write(p, data, len, offset);
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		pci_uio_ioport_write(p, data, len, offset);
+#endif
+		break;
+	default:
+		break;
+	}
+}
+
+int
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
+{
+	int ret = -1;
+
+	switch (p->dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+		if (pci_vfio_is_enabled())
+			ret = pci_vfio_ioport_unmap(p);
+		break;
+#endif
+	case RTE_KDRV_IGB_UIO:
+		ret = pci_uio_ioport_unmap(p);
+		break;
+	case RTE_KDRV_UIO_GENERIC:
+#if defined(RTE_ARCH_X86)
+		ret = 0;
+#else
+		ret = pci_uio_ioport_unmap(p);
+#endif
+		break;
+	case RTE_KDRV_NONE:
+#if defined(RTE_ARCH_X86)
+		ret = 0;
+#endif
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/bus/pci/linux/pci_init.h b/drivers/bus/pci/linux/pci_init.h
new file mode 100644
index 0000000..99d7a2e
--- /dev/null
+++ b/drivers/bus/pci/linux/pci_init.h
@@ -0,0 +1,111 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EAL_PCI_INIT_H_
+#define EAL_PCI_INIT_H_
+
+#include <linux/version.h>
+
+#include <rte_vfio.h>
+
+/** IO resource type: */
+#define IORESOURCE_IO         0x00000100
+#define IORESOURCE_MEM        0x00000200
+
+/*
+ * Helper function to map PCI resources right after hugepages in virtual memory
+ */
+extern void *pci_map_addr;
+void *pci_find_max_end_va(void);
+
+/* parse one line of the "resource" sysfs file (note that the 'line'
+ * string is modified)
+ */
+int pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
+	uint64_t *end_addr, uint64_t *flags);
+
+int pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res);
+void pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res);
+int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx);
+
+int pci_uio_read_config(const struct rte_intr_handle *intr_handle,
+			void *buf, size_t len, off_t offs);
+int pci_uio_write_config(const struct rte_intr_handle *intr_handle,
+			 const void *buf, size_t len, off_t offs);
+
+int pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		       struct rte_pci_ioport *p);
+void pci_uio_ioport_read(struct rte_pci_ioport *p,
+			 void *data, size_t len, off_t offset);
+void pci_uio_ioport_write(struct rte_pci_ioport *p,
+			  const void *data, size_t len, off_t offset);
+int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
+
+#ifdef RTE_EAL_VFIO
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+#define RTE_PCI_MSIX_TABLE_BIR    0x7
+#define RTE_PCI_MSIX_TABLE_OFFSET 0xfffffff8
+#define RTE_PCI_MSIX_FLAGS_QSIZE  0x07ff
+#else
+#define RTE_PCI_MSIX_TABLE_BIR    PCI_MSIX_TABLE_BIR
+#define RTE_PCI_MSIX_TABLE_OFFSET PCI_MSIX_TABLE_OFFSET
+#define RTE_PCI_MSIX_FLAGS_QSIZE  PCI_MSIX_FLAGS_QSIZE
+#endif
+
+/* access config space */
+int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
+			 void *buf, size_t len, off_t offs);
+int pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
+			  const void *buf, size_t len, off_t offs);
+
+int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
+		        struct rte_pci_ioport *p);
+void pci_vfio_ioport_read(struct rte_pci_ioport *p,
+			  void *data, size_t len, off_t offset);
+void pci_vfio_ioport_write(struct rte_pci_ioport *p,
+			   const void *data, size_t len, off_t offset);
+int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
+
+/* map/unmap VFIO resource prototype */
+int pci_vfio_map_resource(struct rte_pci_device *dev);
+int pci_vfio_unmap_resource(struct rte_pci_device *dev);
+
+int pci_vfio_is_enabled(void);
+
+#endif
+
+#endif /* EAL_PCI_INIT_H_ */
diff --git a/drivers/bus/pci/linux/pci_uio.c b/drivers/bus/pci/linux/pci_uio.c
new file mode 100644
index 0000000..8cf6218
--- /dev/null
+++ b/drivers/bus/pci/linux/pci_uio.c
@@ -0,0 +1,568 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/sysmacros.h>
+#include <linux/pci_regs.h>
+
+#if defined(RTE_ARCH_X86)
+#include <sys/io.h>
+#endif
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_common.h>
+#include <rte_malloc.h>
+
+#include "eal_filesystem.h"
+#include "pci_init.h"
+
+void *pci_map_addr = NULL;
+
+#define OFF_MAX              ((uint64_t)(off_t)-1)
+
+int
+pci_uio_read_config(const struct rte_intr_handle *intr_handle,
+		    void *buf, size_t len, off_t offset)
+{
+	return pread(intr_handle->uio_cfg_fd, buf, len, offset);
+}
+
+int
+pci_uio_write_config(const struct rte_intr_handle *intr_handle,
+		     const void *buf, size_t len, off_t offset)
+{
+	return pwrite(intr_handle->uio_cfg_fd, buf, len, offset);
+}
+
+static int
+pci_uio_set_bus_master(int dev_fd)
+{
+	uint16_t reg;
+	int ret;
+
+	ret = pread(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL,
+			"Cannot read command from PCI config space!\n");
+		return -1;
+	}
+
+	/* return if bus mastering is already on */
+	if (reg & PCI_COMMAND_MASTER)
+		return 0;
+
+	reg |= PCI_COMMAND_MASTER;
+
+	ret = pwrite(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL,
+			"Cannot write command to PCI config space!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int
+pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
+{
+	FILE *f;
+	char filename[PATH_MAX];
+	int ret;
+	unsigned major, minor;
+	dev_t dev;
+
+	/* get the name of the sysfs file that contains the major and minor
+	 * of the uio device and read its content */
+	snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path);
+
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n",
+			__func__);
+		return -1;
+	}
+
+	ret = fscanf(f, "%u:%u", &major, &minor);
+	if (ret != 2) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n",
+			__func__);
+		fclose(f);
+		return -1;
+	}
+	fclose(f);
+
+	/* create the char device "mknod /dev/uioX c major minor" */
+	snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
+	dev = makedev(major, minor);
+	ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
+	if (ret != 0) {
+		RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
+			__func__, strerror(errno));
+		return -1;
+	}
+
+	return ret;
+}
+
+/*
+ * Return the uioX char device used for a pci device. On success, return
+ * the UIO number and fill dstbuf string with the path of the device in
+ * sysfs. On error, return a negative value. In this case dstbuf is
+ * invalid.
+ */
+static int
+pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
+			   unsigned int buflen, int create)
+{
+	struct rte_pci_addr *loc = &dev->addr;
+	int uio_num = -1;
+	struct dirent *e;
+	DIR *dir;
+	char dirname[PATH_MAX];
+
+	/* depending on kernel version, uio can be located in uio/uioX
+	 * or uio:uioX */
+
+	snprintf(dirname, sizeof(dirname),
+			"%s/" PCI_PRI_FMT "/uio", pci_get_sysfs_path(),
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	dir = opendir(dirname);
+	if (dir == NULL) {
+		/* retry with the parent directory */
+		snprintf(dirname, sizeof(dirname),
+				"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
+				loc->domain, loc->bus, loc->devid, loc->function);
+		dir = opendir(dirname);
+
+		if (dir == NULL) {
+			RTE_LOG(ERR, EAL, "Cannot opendir %s\n", dirname);
+			return -1;
+		}
+	}
+
+	/* take the first file starting with "uio" */
+	while ((e = readdir(dir)) != NULL) {
+		/* format could be uio%d ...*/
+		int shortprefix_len = sizeof("uio") - 1;
+		/* ... or uio:uio%d */
+		int longprefix_len = sizeof("uio:uio") - 1;
+		char *endptr;
+
+		if (strncmp(e->d_name, "uio", 3) != 0)
+			continue;
+
+		/* first try uio%d */
+		errno = 0;
+		uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
+		if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
+			snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
+			break;
+		}
+
+		/* then try uio:uio%d */
+		errno = 0;
+		uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
+		if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
+			snprintf(dstbuf, buflen, "%s/uio:uio%u", dirname, uio_num);
+			break;
+		}
+	}
+	closedir(dir);
+
+	/* No uio resource found */
+	if (e == NULL)
+		return -1;
+
+	/* create uio device if we've been asked to */
+	if (rte_eal_create_uio_dev() && create &&
+			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
+		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
+
+	return uio_num;
+}
+
+void
+pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res)
+{
+	rte_free(uio_res);
+
+	if (dev->intr_handle.uio_cfg_fd >= 0) {
+		close(dev->intr_handle.uio_cfg_fd);
+		dev->intr_handle.uio_cfg_fd = -1;
+	}
+	if (dev->intr_handle.fd >= 0) {
+		close(dev->intr_handle.fd);
+		dev->intr_handle.fd = -1;
+		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	}
+}
+
+int
+pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res)
+{
+	char dirname[PATH_MAX];
+	char cfgname[PATH_MAX];
+	char devname[PATH_MAX]; /* contains the /dev/uioX */
+	int uio_num;
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+
+	/* find uio resource */
+	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 1);
+	if (uio_num < 0) {
+		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
+				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
+		return 1;
+	}
+	snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
+
+	/* save fd if in primary process */
+	dev->intr_handle.fd = open(devname, O_RDWR);
+	if (dev->intr_handle.fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			devname, strerror(errno));
+		goto error;
+	}
+
+	snprintf(cfgname, sizeof(cfgname),
+			"/sys/class/uio/uio%u/device/config", uio_num);
+	dev->intr_handle.uio_cfg_fd = open(cfgname, O_RDWR);
+	if (dev->intr_handle.uio_cfg_fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+			cfgname, strerror(errno));
+		goto error;
+	}
+
+	if (dev->kdrv == RTE_KDRV_IGB_UIO)
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+	else {
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
+
+		/* set bus master that is not done by uio_pci_generic */
+		if (pci_uio_set_bus_master(dev->intr_handle.uio_cfg_fd)) {
+			RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
+			goto error;
+		}
+	}
+
+	/* allocate the mapping details for secondary processes*/
+	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
+	if (*uio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto error;
+	}
+
+	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
+	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
+
+	return 0;
+
+error:
+	pci_uio_free_resource(dev, *uio_res);
+	return -1;
+}
+
+int
+pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx)
+{
+	int fd;
+	char devname[PATH_MAX];
+	void *mapaddr;
+	struct rte_pci_addr *loc;
+	struct pci_map *maps;
+
+	loc = &dev->addr;
+	maps = uio_res->maps;
+
+	/* update devname for mmap  */
+	snprintf(devname, sizeof(devname),
+			"%s/" PCI_PRI_FMT "/resource%d",
+			pci_get_sysfs_path(),
+			loc->domain, loc->bus, loc->devid,
+			loc->function, res_idx);
+
+	/* allocate memory to keep path */
+	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+	if (maps[map_idx].path == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+				strerror(errno));
+		return -1;
+	}
+
+	/*
+	 * open resource file, to mmap it
+	 */
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				devname, strerror(errno));
+		goto error;
+	}
+
+	/* try mapping somewhere close to the end of hugepages */
+	if (pci_map_addr == NULL)
+		pci_map_addr = pci_find_max_end_va();
+
+	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
+			(size_t)dev->mem_resource[res_idx].len, 0);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		goto error;
+
+	pci_map_addr = RTE_PTR_ADD(mapaddr,
+			(size_t)dev->mem_resource[res_idx].len);
+
+	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+	maps[map_idx].size = dev->mem_resource[res_idx].len;
+	maps[map_idx].addr = mapaddr;
+	maps[map_idx].offset = 0;
+	strcpy(maps[map_idx].path, devname);
+	dev->mem_resource[res_idx].addr = mapaddr;
+
+	return 0;
+
+error:
+	rte_free(maps[map_idx].path);
+	return -1;
+}
+
+#if defined(RTE_ARCH_X86)
+int
+pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		   struct rte_pci_ioport *p)
+{
+	char dirname[PATH_MAX];
+	char filename[PATH_MAX];
+	int uio_num;
+	unsigned long start;
+
+	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 0);
+	if (uio_num < 0)
+		return -1;
+
+	/* get portio start */
+	snprintf(filename, sizeof(filename),
+		 "%s/portio/port%d/start", dirname, bar);
+	if (eal_parse_sysfs_value(filename, &start) < 0) {
+		RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
+			__func__);
+		return -1;
+	}
+	/* ensure we don't get anything funny here, read/write will cast to
+	 * uin16_t */
+	if (start > UINT16_MAX)
+		return -1;
+
+	/* FIXME only for primary process ? */
+	if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {
+
+		snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
+		dev->intr_handle.fd = open(filename, O_RDWR);
+		if (dev->intr_handle.fd < 0) {
+			RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+				filename, strerror(errno));
+			return -1;
+		}
+		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
+	}
+
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);
+
+	p->base = start;
+	p->len = 0;
+	return 0;
+}
+#else
+int
+pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
+		   struct rte_pci_ioport *p)
+{
+	FILE *f;
+	char buf[BUFSIZ];
+	char filename[PATH_MAX];
+	uint64_t phys_addr, end_addr, flags;
+	int fd, i;
+	void *addr;
+
+	/* open and read addresses of the corresponding resource in sysfs */
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
+		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function);
+	f = fopen(filename, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",
+			strerror(errno));
+		return -1;
+	}
+	for (i = 0; i < bar + 1; i++) {
+		if (fgets(buf, sizeof(buf), f) == NULL) {
+			RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");
+			goto error;
+		}
+	}
+	if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
+			&end_addr, &flags) < 0)
+		goto error;
+	if ((flags & IORESOURCE_IO) == 0) {
+		RTE_LOG(ERR, EAL, "BAR %d is not an IO resource\n", bar);
+		goto error;
+	}
+	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
+		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
+		dev->addr.devid, dev->addr.function, bar);
+
+	/* mmap the pci resource */
+	fd = open(filename, O_RDWR);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
+			strerror(errno));
+		goto error;
+	}
+	addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
+		MAP_SHARED, fd, 0);
+	close(fd);
+	if (addr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s\n",
+			strerror(errno));
+		goto error;
+	}
+
+	/* strangely, the base address is mmap addr + phys_addr */
+	p->base = (uintptr_t)addr + phys_addr;
+	p->len = end_addr + 1;
+	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"\n", p->base);
+	fclose(f);
+
+	return 0;
+
+error:
+	fclose(f);
+	return -1;
+}
+#endif
+
+void
+pci_uio_ioport_read(struct rte_pci_ioport *p,
+		    void *data, size_t len, off_t offset)
+{
+	uint8_t *d;
+	int size;
+	uintptr_t reg = p->base + offset;
+
+	for (d = data; len > 0; d += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+#if defined(RTE_ARCH_X86)
+			*(uint32_t *)d = inl(reg);
+#else
+			*(uint32_t *)d = *(volatile uint32_t *)reg;
+#endif
+		} else if (len >= 2) {
+			size = 2;
+#if defined(RTE_ARCH_X86)
+			*(uint16_t *)d = inw(reg);
+#else
+			*(uint16_t *)d = *(volatile uint16_t *)reg;
+#endif
+		} else {
+			size = 1;
+#if defined(RTE_ARCH_X86)
+			*d = inb(reg);
+#else
+			*d = *(volatile uint8_t *)reg;
+#endif
+		}
+	}
+}
+
+void
+pci_uio_ioport_write(struct rte_pci_ioport *p,
+		     const void *data, size_t len, off_t offset)
+{
+	const uint8_t *s;
+	int size;
+	uintptr_t reg = p->base + offset;
+
+	for (s = data; len > 0; s += size, reg += size, len -= size) {
+		if (len >= 4) {
+			size = 4;
+#if defined(RTE_ARCH_X86)
+			outl_p(*(const uint32_t *)s, reg);
+#else
+			*(volatile uint32_t *)reg = *(const uint32_t *)s;
+#endif
+		} else if (len >= 2) {
+			size = 2;
+#if defined(RTE_ARCH_X86)
+			outw_p(*(const uint16_t *)s, reg);
+#else
+			*(volatile uint16_t *)reg = *(const uint16_t *)s;
+#endif
+		} else {
+			size = 1;
+#if defined(RTE_ARCH_X86)
+			outb_p(*s, reg);
+#else
+			*(volatile uint8_t *)reg = *s;
+#endif
+		}
+	}
+}
+
+int
+pci_uio_ioport_unmap(struct rte_pci_ioport *p)
+{
+#if defined(RTE_ARCH_X86)
+	RTE_SET_USED(p);
+	/* FIXME close intr fd ? */
+	return 0;
+#else
+	return munmap((void *)(uintptr_t)p->base, p->len);
+#endif
+}
diff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c
new file mode 100644
index 0000000..1a3c308
--- /dev/null
+++ b/drivers/bus/pci/linux/pci_vfio.c
@@ -0,0 +1,756 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <fcntl.h>
+#include <linux/pci_regs.h>
+#include <sys/eventfd.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_eal_memconfig.h>
+#include <rte_malloc.h>
+#include <rte_vfio.h>
+
+#include "eal_filesystem.h"
+
+#include "pci_init.h"
+#include "private.h"
+
+/**
+ * @file
+ * PCI probing under linux (VFIO version)
+ *
+ * This code tries to determine if the PCI device is bound to VFIO driver,
+ * and initialize it (map BARs, set up interrupts) if that's the case.
+ *
+ * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
+ */
+
+#ifdef RTE_EAL_VFIO
+
+#define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
+#define PAGE_MASK   (~(PAGE_SIZE - 1))
+
+static struct rte_tailq_elem rte_vfio_tailq = {
+	.name = "VFIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_vfio_tailq)
+
+int
+pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
+		    void *buf, size_t len, off_t offs)
+{
+	return pread64(intr_handle->vfio_dev_fd, buf, len,
+	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
+}
+
+int
+pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
+		    const void *buf, size_t len, off_t offs)
+{
+	return pwrite64(intr_handle->vfio_dev_fd, buf, len,
+	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
+}
+
+/* get PCI BAR number where MSI-X interrupts are */
+static int
+pci_vfio_get_msix_bar(int fd, struct pci_msix_table *msix_table)
+{
+	int ret;
+	uint32_t reg;
+	uint16_t flags;
+	uint8_t cap_id, cap_offset;
+
+	/* read PCI capability pointer from config space */
+	ret = pread64(fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_CAPABILITY_LIST);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
+				"config space!\n");
+		return -1;
+	}
+
+	/* we need first byte */
+	cap_offset = reg & 0xFF;
+
+	while (cap_offset) {
+
+		/* read PCI capability ID */
+		ret = pread64(fd, &reg, sizeof(reg),
+				VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+				cap_offset);
+		if (ret != sizeof(reg)) {
+			RTE_LOG(ERR, EAL, "Cannot read capability ID from PCI "
+					"config space!\n");
+			return -1;
+		}
+
+		/* we need first byte */
+		cap_id = reg & 0xFF;
+
+		/* if we haven't reached MSI-X, check next capability */
+		if (cap_id != PCI_CAP_ID_MSIX) {
+			ret = pread64(fd, &reg, sizeof(reg),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset);
+			if (ret != sizeof(reg)) {
+				RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
+						"config space!\n");
+				return -1;
+			}
+
+			/* we need second byte */
+			cap_offset = (reg & 0xFF00) >> 8;
+
+			continue;
+		}
+		/* else, read table offset */
+		else {
+			/* table offset resides in the next 4 bytes */
+			ret = pread64(fd, &reg, sizeof(reg),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset + 4);
+			if (ret != sizeof(reg)) {
+				RTE_LOG(ERR, EAL, "Cannot read table offset from PCI config "
+						"space!\n");
+				return -1;
+			}
+
+			ret = pread64(fd, &flags, sizeof(flags),
+					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+					cap_offset + 2);
+			if (ret != sizeof(flags)) {
+				RTE_LOG(ERR, EAL, "Cannot read table flags from PCI config "
+						"space!\n");
+				return -1;
+			}
+
+			msix_table->bar_index = reg & RTE_PCI_MSIX_TABLE_BIR;
+			msix_table->offset = reg & RTE_PCI_MSIX_TABLE_OFFSET;
+			msix_table->size =
+				16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE));
+
+			return 0;
+		}
+	}
+	return 0;
+}
+
+/* set PCI bus mastering */
+static int
+pci_vfio_set_bus_master(int dev_fd, bool op)
+{
+	uint16_t reg;
+	int ret;
+
+	ret = pread64(dev_fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_COMMAND);
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n");
+		return -1;
+	}
+
+	if (op)
+		/* set the master bit */
+		reg |= PCI_COMMAND_MASTER;
+	else
+		reg &= ~(PCI_COMMAND_MASTER);
+
+	ret = pwrite64(dev_fd, &reg, sizeof(reg),
+			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
+			PCI_COMMAND);
+
+	if (ret != sizeof(reg)) {
+		RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* set up interrupt support (but not enable interrupts) */
+static int
+pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
+{
+	int i, ret, intr_idx;
+	enum rte_intr_mode intr_mode;
+
+	/* default to invalid index */
+	intr_idx = VFIO_PCI_NUM_IRQS;
+
+	/* Get default / configured intr_mode */
+	intr_mode = rte_eal_vfio_intr_mode();
+
+	/* get interrupt type from internal config (MSI-X by default, can be
+	 * overridden from the command line
+	 */
+	switch (intr_mode) {
+	case RTE_INTR_MODE_MSIX:
+		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
+		break;
+	case RTE_INTR_MODE_MSI:
+		intr_idx = VFIO_PCI_MSI_IRQ_INDEX;
+		break;
+	case RTE_INTR_MODE_LEGACY:
+		intr_idx = VFIO_PCI_INTX_IRQ_INDEX;
+		break;
+	/* don't do anything if we want to automatically determine interrupt type */
+	case RTE_INTR_MODE_NONE:
+		break;
+	default:
+		RTE_LOG(ERR, EAL, "  unknown default interrupt type!\n");
+		return -1;
+	}
+
+	/* start from MSI-X interrupt type */
+	for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) {
+		struct vfio_irq_info irq = { .argsz = sizeof(irq) };
+		int fd = -1;
+
+		/* skip interrupt modes we don't want */
+		if (intr_mode != RTE_INTR_MODE_NONE &&
+				i != intr_idx)
+			continue;
+
+		irq.index = i;
+
+		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  cannot get IRQ info, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+
+		/* if this vector cannot be used with eventfd, fail if we explicitly
+		 * specified interrupt type, otherwise continue */
+		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
+			if (intr_mode != RTE_INTR_MODE_NONE) {
+				RTE_LOG(ERR, EAL,
+						"  interrupt vector does not support eventfd!\n");
+				return -1;
+			} else
+				continue;
+		}
+
+		/* set up an eventfd for interrupts */
+		fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
+		if (fd < 0) {
+			RTE_LOG(ERR, EAL, "  cannot set up eventfd, "
+					"error %i (%s)\n", errno, strerror(errno));
+			return -1;
+		}
+
+		dev->intr_handle.fd = fd;
+		dev->intr_handle.vfio_dev_fd = vfio_dev_fd;
+
+		switch (i) {
+		case VFIO_PCI_MSIX_IRQ_INDEX:
+			intr_mode = RTE_INTR_MODE_MSIX;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
+			break;
+		case VFIO_PCI_MSI_IRQ_INDEX:
+			intr_mode = RTE_INTR_MODE_MSI;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
+			break;
+		case VFIO_PCI_INTX_IRQ_INDEX:
+			intr_mode = RTE_INTR_MODE_LEGACY;
+			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
+			break;
+		default:
+			RTE_LOG(ERR, EAL, "  unknown interrupt type!\n");
+			return -1;
+		}
+
+		return 0;
+	}
+
+	/* if we're here, we haven't found a suitable interrupt vector */
+	return -1;
+}
+
+static int
+pci_vfio_is_ioport_bar(int vfio_dev_fd, int bar_index)
+{
+	uint32_t ioport_bar;
+	int ret;
+
+	ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar),
+			  VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX)
+			  + PCI_BASE_ADDRESS_0 + bar_index*4);
+	if (ret != sizeof(ioport_bar)) {
+		RTE_LOG(ERR, EAL, "Cannot read command (%x) from config space!\n",
+			PCI_BASE_ADDRESS_0 + bar_index*4);
+		return -1;
+	}
+
+	return (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) != 0;
+}
+
+static int
+pci_vfio_setup_device(struct rte_pci_device *dev, int vfio_dev_fd)
+{
+	if (pci_vfio_setup_interrupts(dev, vfio_dev_fd) != 0) {
+		RTE_LOG(ERR, EAL, "Error setting up interrupts!\n");
+		return -1;
+	}
+
+	/* set bus mastering for the device */
+	if (pci_vfio_set_bus_master(vfio_dev_fd, true)) {
+		RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
+		return -1;
+	}
+
+	/* Reset the device */
+	ioctl(vfio_dev_fd, VFIO_DEVICE_RESET);
+
+	return 0;
+}
+
+static int
+pci_vfio_mmap_bar(int vfio_dev_fd, struct mapped_pci_resource *vfio_res,
+		int bar_index, int additional_flags)
+{
+	struct memreg {
+		unsigned long offset, size;
+	} memreg[2] = {};
+	void *bar_addr;
+	struct pci_msix_table *msix_table = &vfio_res->msix_table;
+	struct pci_map *bar = &vfio_res->maps[bar_index];
+
+	if (bar->size == 0)
+		/* Skip this BAR */
+		return 0;
+
+	if (msix_table->bar_index == bar_index) {
+		/*
+		 * VFIO will not let us map the MSI-X table,
+		 * but we can map around it.
+		 */
+		uint32_t table_start = msix_table->offset;
+		uint32_t table_end = table_start + msix_table->size;
+		table_end = (table_end + ~PAGE_MASK) & PAGE_MASK;
+		table_start &= PAGE_MASK;
+
+		if (table_start == 0 && table_end >= bar->size) {
+			/* Cannot map this BAR */
+			RTE_LOG(DEBUG, EAL, "Skipping BAR%d\n", bar_index);
+			bar->size = 0;
+			bar->addr = 0;
+			return 0;
+		}
+
+		memreg[0].offset = bar->offset;
+		memreg[0].size = table_start;
+		memreg[1].offset = bar->offset + table_end;
+		memreg[1].size = bar->size - table_end;
+
+		RTE_LOG(DEBUG, EAL,
+			"Trying to map BAR%d that contains the MSI-X "
+			"table. Trying offsets: "
+			"0x%04lx:0x%04lx, 0x%04lx:0x%04lx\n", bar_index,
+			memreg[0].offset, memreg[0].size,
+			memreg[1].offset, memreg[1].size);
+	} else {
+		memreg[0].offset = bar->offset;
+		memreg[0].size = bar->size;
+	}
+
+	/* reserve the address using an inaccessible mapping */
+	bar_addr = mmap(bar->addr, bar->size, 0, MAP_PRIVATE |
+			MAP_ANONYMOUS | additional_flags, -1, 0);
+	if (bar_addr != MAP_FAILED) {
+		void *map_addr = NULL;
+		if (memreg[0].size) {
+			/* actual map of first part */
+			map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
+							memreg[0].offset,
+							memreg[0].size,
+							MAP_FIXED);
+		}
+
+		/* if there's a second part, try to map it */
+		if (map_addr != MAP_FAILED
+			&& memreg[1].offset && memreg[1].size) {
+			void *second_addr = RTE_PTR_ADD(bar_addr,
+							memreg[1].offset -
+							(uintptr_t)bar->offset);
+			map_addr = pci_map_resource(second_addr,
+							vfio_dev_fd,
+							memreg[1].offset,
+							memreg[1].size,
+							MAP_FIXED);
+		}
+
+		if (map_addr == MAP_FAILED || !map_addr) {
+			munmap(bar_addr, bar->size);
+			bar_addr = MAP_FAILED;
+			RTE_LOG(ERR, EAL, "Failed to map pci BAR%d\n",
+					bar_index);
+			return -1;
+		}
+	} else {
+		RTE_LOG(ERR, EAL,
+				"Failed to create inaccessible mapping for BAR%d\n",
+				bar_index);
+		return -1;
+	}
+
+	bar->addr = bar_addr;
+	return 0;
+}
+
+static int
+pci_vfio_map_resource_primary(struct rte_pci_device *dev)
+{
+	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+	char pci_addr[PATH_MAX] = {0};
+	int vfio_dev_fd;
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list =
+		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+
+	struct pci_map *maps;
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
+					&vfio_dev_fd, &device_info);
+	if (ret)
+		return ret;
+
+	/* allocate vfio_res and get region info */
+	vfio_res = rte_zmalloc("VFIO_RES", sizeof(*vfio_res), 0);
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot store uio mmap details\n", __func__);
+		goto err_vfio_dev_fd;
+	}
+	memcpy(&vfio_res->pci_addr, &dev->addr, sizeof(vfio_res->pci_addr));
+
+	/* get number of registers (up to BAR5) */
+	vfio_res->nb_maps = RTE_MIN((int) device_info.num_regions,
+			VFIO_PCI_BAR5_REGION_INDEX + 1);
+
+	/* map BARs */
+	maps = vfio_res->maps;
+
+	vfio_res->msix_table.bar_index = -1;
+	/* get MSI-X BAR, if any (we have to know where it is because we can't
+	 * easily mmap it when using VFIO)
+	 */
+	ret = pci_vfio_get_msix_bar(vfio_dev_fd, &vfio_res->msix_table);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "  %s cannot get MSI-X BAR number!\n",
+				pci_addr);
+		goto err_vfio_dev_fd;
+	}
+
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+		struct vfio_region_info reg = { .argsz = sizeof(reg) };
+		void *bar_addr;
+
+		reg.index = i;
+
+		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg);
+		if (ret) {
+			RTE_LOG(ERR, EAL, "  %s cannot get device region info "
+					"error %i (%s)\n", pci_addr, errno, strerror(errno));
+			goto err_vfio_res;
+		}
+
+		/* chk for io port region */
+		ret = pci_vfio_is_ioport_bar(vfio_dev_fd, i);
+		if (ret < 0)
+			goto err_vfio_res;
+		else if (ret) {
+			RTE_LOG(INFO, EAL, "Ignore mapping IO port bar(%d)\n",
+					i);
+			continue;
+		}
+
+		/* skip non-mmapable BARs */
+		if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0)
+			continue;
+
+		/* try mapping somewhere close to the end of hugepages */
+		if (pci_map_addr == NULL)
+			pci_map_addr = pci_find_max_end_va();
+
+		bar_addr = pci_map_addr;
+		pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
+
+		maps[i].addr = bar_addr;
+		maps[i].offset = reg.offset;
+		maps[i].size = reg.size;
+		maps[i].path = NULL; /* vfio doesn't have per-resource paths */
+
+		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, 0);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
+					pci_addr, i, strerror(errno));
+			goto err_vfio_res;
+		}
+
+		dev->mem_resource[i].addr = maps[i].addr;
+	}
+
+	if (pci_vfio_setup_device(dev, vfio_dev_fd) < 0) {
+		RTE_LOG(ERR, EAL, "  %s setup device failed\n", pci_addr);
+		goto err_vfio_res;
+	}
+
+	TAILQ_INSERT_TAIL(vfio_res_list, vfio_res, next);
+
+	return 0;
+err_vfio_res:
+	rte_free(vfio_res);
+err_vfio_dev_fd:
+	close(vfio_dev_fd);
+	return -1;
+}
+
+static int
+pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
+{
+	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+	char pci_addr[PATH_MAX] = {0};
+	int vfio_dev_fd;
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list =
+		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+
+	struct pci_map *maps;
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
+					&vfio_dev_fd, &device_info);
+	if (ret)
+		return ret;
+
+	/* if we're in a secondary process, just find our tailq entry */
+	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
+		if (pci_addr_cmp(&vfio_res->pci_addr,
+						 &dev->addr))
+			continue;
+		break;
+	}
+	/* if we haven't found our tailq entry, something's wrong */
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
+				pci_addr);
+		goto err_vfio_dev_fd;
+	}
+
+	/* map BARs */
+	maps = vfio_res->maps;
+
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, MAP_FIXED);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
+					pci_addr, i, strerror(errno));
+			goto err_vfio_dev_fd;
+		}
+
+		dev->mem_resource[i].addr = maps[i].addr;
+	}
+
+	return 0;
+err_vfio_dev_fd:
+	close(vfio_dev_fd);
+	return -1;
+}
+
+/*
+ * map the PCI resources of a PCI device in virtual memory (VFIO version).
+ * primary and secondary processes follow almost exactly the same path
+ */
+int
+pci_vfio_map_resource(struct rte_pci_device *dev)
+{
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		return pci_vfio_map_resource_primary(dev);
+	else
+		return pci_vfio_map_resource_secondary(dev);
+}
+
+int
+pci_vfio_unmap_resource(struct rte_pci_device *dev)
+{
+	char pci_addr[PATH_MAX] = {0};
+	struct rte_pci_addr *loc = &dev->addr;
+	int i, ret;
+	struct mapped_pci_resource *vfio_res = NULL;
+	struct mapped_pci_res_list *vfio_res_list;
+
+	struct pci_map *maps;
+
+	/* store PCI address string */
+	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
+			loc->domain, loc->bus, loc->devid, loc->function);
+
+
+	if (close(dev->intr_handle.fd) < 0) {
+		RTE_LOG(INFO, EAL, "Error when closing eventfd file descriptor for %s\n",
+			pci_addr);
+		return -1;
+	}
+
+	if (pci_vfio_set_bus_master(dev->intr_handle.vfio_dev_fd, false)) {
+		RTE_LOG(ERR, EAL, "  %s cannot unset bus mastering for PCI device!\n",
+				pci_addr);
+		return -1;
+	}
+
+	ret = vfio_release_device(pci_get_sysfs_path(), pci_addr,
+				  dev->intr_handle.vfio_dev_fd);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL,
+			"%s(): cannot release device\n", __func__);
+		return ret;
+	}
+
+	vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
+	/* Get vfio_res */
+	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
+		if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
+			continue;
+		break;
+	}
+	/* if we haven't found our tailq entry, something's wrong */
+	if (vfio_res == NULL) {
+		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
+				pci_addr);
+		return -1;
+	}
+
+	/* unmap BARs */
+	maps = vfio_res->maps;
+
+	RTE_LOG(INFO, EAL, "Releasing pci mapped resource for %s\n",
+		pci_addr);
+	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
+
+		/*
+		 * We do not need to be aware of MSI-X table BAR mappings as
+		 * when mapping. Just using current maps array is enough
+		 */
+		if (maps[i].addr) {
+			RTE_LOG(INFO, EAL, "Calling pci_unmap_resource for %s at %p\n",
+				pci_addr, maps[i].addr);
+			pci_unmap_resource(maps[i].addr, maps[i].size);
+		}
+	}
+
+	TAILQ_REMOVE(vfio_res_list, vfio_res, next);
+
+	return 0;
+}
+
+int
+pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
+		    struct rte_pci_ioport *p)
+{
+	if (bar < VFIO_PCI_BAR0_REGION_INDEX ||
+	    bar > VFIO_PCI_BAR5_REGION_INDEX) {
+		RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar);
+		return -1;
+	}
+
+	p->dev = dev;
+	p->base = VFIO_GET_REGION_ADDR(bar);
+	return 0;
+}
+
+void
+pci_vfio_ioport_read(struct rte_pci_ioport *p,
+		     void *data, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
+
+	if (pread64(intr_handle->vfio_dev_fd, data,
+		    len, p->base + offset) <= 0)
+		RTE_LOG(ERR, EAL,
+			"Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n",
+			VFIO_GET_REGION_IDX(p->base), (int)offset);
+}
+
+void
+pci_vfio_ioport_write(struct rte_pci_ioport *p,
+		      const void *data, size_t len, off_t offset)
+{
+	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
+
+	if (pwrite64(intr_handle->vfio_dev_fd, data,
+		     len, p->base + offset) <= 0)
+		RTE_LOG(ERR, EAL,
+			"Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n",
+			VFIO_GET_REGION_IDX(p->base), (int)offset);
+}
+
+int
+pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
+{
+	RTE_SET_USED(p);
+	return -1;
+}
+
+int
+pci_vfio_is_enabled(void)
+{
+	return vfio_is_enabled("vfio_pci");
+}
+#endif
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
new file mode 100644
index 0000000..3e27779
--- /dev/null
+++ b/drivers/bus/pci/pci_common.c
@@ -0,0 +1,541 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+#include <rte_devargs.h>
+
+#include "private.h"
+
+extern struct rte_pci_bus rte_pci_bus;
+
+#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
+
+const char *pci_get_sysfs_path(void)
+{
+	const char *path = NULL;
+
+	path = getenv("SYSFS_PCI_DEVICES");
+	if (path == NULL)
+		return SYSFS_PCI_DEVICES;
+
+	return path;
+}
+
+static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
+{
+	struct rte_devargs *devargs;
+	struct rte_pci_addr addr;
+	struct rte_bus *pbus;
+
+	pbus = rte_bus_find_by_name("pci");
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->bus != pbus)
+			continue;
+		devargs->bus->parse(devargs->name, &addr);
+		if (!pci_addr_cmp(&dev->addr, &addr))
+			return devargs;
+	}
+	return NULL;
+}
+
+void
+pci_name_set(struct rte_pci_device *dev)
+{
+	struct rte_devargs *devargs;
+
+	/* Each device has its internal, canonical name set. */
+	rte_pci_device_name(&dev->addr,
+			dev->name, sizeof(dev->name));
+	devargs = pci_devargs_lookup(dev);
+	dev->device.devargs = devargs;
+	/* In blacklist mode, if the device is not blacklisted, no
+	 * rte_devargs exists for it.
+	 */
+	if (devargs != NULL)
+		/* If an rte_devargs exists, the generic rte_device uses the
+		 * given name as its namea
+		 */
+		dev->device.name = dev->device.devargs->name;
+	else
+		/* Otherwise, it uses the internal, canonical form. */
+		dev->device.name = dev->name;
+}
+
+/*
+ * Match the PCI Driver and Device using the ID Table
+ */
+int
+rte_pci_match(const struct rte_pci_driver *pci_drv,
+	      const struct rte_pci_device *pci_dev)
+{
+	const struct rte_pci_id *id_table;
+
+	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
+	     id_table++) {
+		/* check if device's identifiers match the driver's ones */
+		if (id_table->vendor_id != pci_dev->id.vendor_id &&
+				id_table->vendor_id != PCI_ANY_ID)
+			continue;
+		if (id_table->device_id != pci_dev->id.device_id &&
+				id_table->device_id != PCI_ANY_ID)
+			continue;
+		if (id_table->subsystem_vendor_id !=
+		    pci_dev->id.subsystem_vendor_id &&
+		    id_table->subsystem_vendor_id != PCI_ANY_ID)
+			continue;
+		if (id_table->subsystem_device_id !=
+		    pci_dev->id.subsystem_device_id &&
+		    id_table->subsystem_device_id != PCI_ANY_ID)
+			continue;
+		if (id_table->class_id != pci_dev->id.class_id &&
+				id_table->class_id != RTE_CLASS_ANY_ID)
+			continue;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * If vendor/device ID match, call the probe() function of the
+ * driver.
+ */
+static int
+rte_pci_probe_one_driver(struct rte_pci_driver *dr,
+			 struct rte_pci_device *dev)
+{
+	int ret;
+	struct rte_pci_addr *loc;
+
+	if ((dr == NULL) || (dev == NULL))
+		return -EINVAL;
+
+	loc = &dev->addr;
+
+	/* The device is not blacklisted; Check if driver supports it */
+	if (!rte_pci_match(dr, dev))
+		/* Match of device and driver failed */
+		return 1;
+
+	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			loc->domain, loc->bus, loc->devid, loc->function,
+			dev->device.numa_node);
+
+	/* no initialization when blacklisted, return without error */
+	if (dev->device.devargs != NULL &&
+		dev->device.devargs->policy ==
+			RTE_DEV_BLACKLISTED) {
+		RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
+			" initializing\n");
+		return 1;
+	}
+
+	if (dev->device.numa_node < 0) {
+		RTE_LOG(WARNING, EAL, "  Invalid NUMA socket, default to 0\n");
+		dev->device.numa_node = 0;
+	}
+
+	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
+		dev->id.device_id, dr->driver.name);
+
+	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+		/* map resources for devices that use igb_uio */
+		ret = rte_pci_map_device(dev);
+		if (ret != 0)
+			return ret;
+	}
+
+	/* reference driver structure */
+	dev->driver = dr;
+	dev->device.driver = &dr->driver;
+
+	/* call the driver probe() function */
+	ret = dr->probe(dr, dev);
+	if (ret) {
+		dev->driver = NULL;
+		dev->device.driver = NULL;
+		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
+			/* Don't unmap if device is unsupported and
+			 * driver needs mapped resources.
+			 */
+			!(ret > 0 &&
+				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
+			rte_pci_unmap_device(dev);
+	}
+
+	return ret;
+}
+
+/*
+ * If vendor/device ID match, call the remove() function of the
+ * driver.
+ */
+static int
+rte_pci_detach_dev(struct rte_pci_device *dev)
+{
+	struct rte_pci_addr *loc;
+	struct rte_pci_driver *dr;
+	int ret = 0;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	dr = dev->driver;
+	loc = &dev->addr;
+
+	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+			loc->domain, loc->bus, loc->devid,
+			loc->function, dev->device.numa_node);
+
+	RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
+			dev->id.device_id, dr->driver.name);
+
+	if (dr->remove) {
+		ret = dr->remove(dev);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* clear driver structure */
+	dev->driver = NULL;
+
+	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
+		/* unmap resources for devices that use igb_uio */
+		rte_pci_unmap_device(dev);
+
+	return 0;
+}
+
+/*
+ * If vendor/device ID match, call the probe() function of all
+ * registered driver for the given device. Return -1 if initialization
+ * failed, return 1 if no driver is found for this device.
+ */
+static int
+pci_probe_all_drivers(struct rte_pci_device *dev)
+{
+	struct rte_pci_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	/* Check if a driver is already loaded */
+	if (dev->driver != NULL)
+		return 0;
+
+	FOREACH_DRIVER_ON_PCIBUS(dr) {
+		rc = rte_pci_probe_one_driver(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * Find the pci device specified by pci address, then invoke probe function of
+ * the driver of the device.
+ */
+int
+rte_pci_probe_one(const struct rte_pci_addr *addr)
+{
+	struct rte_pci_device *dev = NULL;
+
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	/* update current pci device in global list, kernel bindings might have
+	 * changed since last time we looked at it.
+	 */
+	if (pci_update_device(addr) < 0)
+		goto err_return;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (pci_addr_cmp(&dev->addr, addr))
+			continue;
+
+		ret = pci_probe_all_drivers(dev);
+		if (ret)
+			goto err_return;
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL,
+		"Requested device " PCI_PRI_FMT " cannot be used\n",
+		addr->domain, addr->bus, addr->devid, addr->function);
+	return -1;
+}
+
+/*
+ * Detach device specified by its pci address.
+ */
+int
+rte_pci_detach(const struct rte_pci_addr *addr)
+{
+	struct rte_pci_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (pci_addr_cmp(&dev->addr, addr))
+			continue;
+
+		ret = rte_pci_detach_dev(dev);
+		if (ret < 0)
+			/* negative value is an error */
+			goto err_return;
+		if (ret > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+
+		rte_pci_remove_device(dev);
+		free(dev);
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
+			" cannot be used\n", dev->addr.domain, dev->addr.bus,
+			dev->addr.devid, dev->addr.function);
+	return -1;
+}
+
+/*
+ * Scan the content of the PCI bus, and call the probe() function for
+ * all registered drivers that have a matching entry in its id_table
+ * for discovered devices.
+ */
+int
+rte_pci_probe(void)
+{
+	struct rte_pci_device *dev = NULL;
+	size_t probed = 0, failed = 0;
+	struct rte_devargs *devargs;
+	int probe_all = 0;
+	int ret = 0;
+
+	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
+		probe_all = 1;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		probed++;
+
+		devargs = dev->device.devargs;
+		/* probe all or only whitelisted devices */
+		if (probe_all)
+			ret = pci_probe_all_drivers(dev);
+		else if (devargs != NULL &&
+			devargs->policy == RTE_DEV_WHITELISTED)
+			ret = pci_probe_all_drivers(dev);
+		if (ret < 0) {
+			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
+				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
+				 dev->addr.devid, dev->addr.function);
+			rte_errno = errno;
+			failed++;
+			ret = 0;
+		}
+	}
+
+	return (probed && probed == failed) ? -1 : 0;
+}
+
+/* dump one device */
+static int
+pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
+{
+	int i;
+
+	fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
+	       dev->addr.devid, dev->addr.function);
+	fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
+	       dev->id.device_id);
+
+	for (i = 0; i != sizeof(dev->mem_resource) /
+		sizeof(dev->mem_resource[0]); i++) {
+		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
+			dev->mem_resource[i].phys_addr,
+			dev->mem_resource[i].len);
+	}
+	return 0;
+}
+
+/* dump devices on the bus */
+void
+rte_pci_dump(FILE *f)
+{
+	struct rte_pci_device *dev = NULL;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		pci_dump_one_device(f, dev);
+	}
+}
+
+static int
+pci_parse(const char *name, void *addr)
+{
+	struct rte_pci_addr *out = addr;
+	struct rte_pci_addr pci_addr;
+	bool parse;
+
+	parse = (pci_addr_parse(name, &pci_addr) == 0);
+	if (parse && addr != NULL)
+		*out = pci_addr;
+	return parse == false;
+}
+
+/* register a driver */
+void
+rte_pci_register(struct rte_pci_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
+	driver->bus = &rte_pci_bus;
+}
+
+/* unregister a driver */
+void
+rte_pci_unregister(struct rte_pci_driver *driver)
+{
+	TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
+	driver->bus = NULL;
+}
+
+/* Add a device to PCI bus */
+void
+rte_pci_add_device(struct rte_pci_device *pci_dev)
+{
+	TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
+}
+
+/* Insert a device into a predefined position in PCI bus */
+void
+rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+		      struct rte_pci_device *new_pci_dev)
+{
+	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
+}
+
+/* Remove a device from PCI bus */
+void
+rte_pci_remove_device(struct rte_pci_device *pci_dev)
+{
+	TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
+}
+
+static struct rte_device *
+pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
+		const void *data)
+{
+	struct rte_pci_device *dev;
+
+	FOREACH_DEVICE_ON_PCIBUS(dev) {
+		if (start && &dev->device == start) {
+			start = NULL; /* starting point found */
+			continue;
+		}
+		if (cmp(&dev->device, data) == 0)
+			return &dev->device;
+	}
+
+	return NULL;
+}
+
+static int
+pci_plug(struct rte_device *dev)
+{
+	return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
+}
+
+static int
+pci_unplug(struct rte_device *dev)
+{
+	struct rte_pci_device *pdev;
+	int ret;
+
+	pdev = RTE_DEV_TO_PCI(dev);
+	ret = rte_pci_detach_dev(pdev);
+	if (ret == 0) {
+		rte_pci_remove_device(pdev);
+		free(pdev);
+	}
+	return ret;
+}
+
+struct rte_pci_bus rte_pci_bus = {
+	.bus = {
+		.scan = rte_pci_scan,
+		.probe = rte_pci_probe,
+		.find_device = pci_find_device,
+		.plug = pci_plug,
+		.unplug = pci_unplug,
+		.parse = pci_parse,
+		.get_iommu_class = rte_pci_get_iommu_class,
+	},
+	.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
+	.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
+};
+
+RTE_REGISTER_BUS(pci, rte_pci_bus.bus);
diff --git a/drivers/bus/pci/pci_common_uio.c b/drivers/bus/pci/pci_common_uio.c
new file mode 100644
index 0000000..b58bcf5
--- /dev/null
+++ b/drivers/bus/pci/pci_common_uio.c
@@ -0,0 +1,235 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_tailq.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+
+#include "private.h"
+
+static struct rte_tailq_elem rte_uio_tailq = {
+	.name = "UIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_uio_tailq)
+
+static int
+pci_uio_map_secondary(struct rte_pci_device *dev)
+{
+	int fd, i, j;
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	TAILQ_FOREACH(uio_res, uio_res_list, next) {
+
+		/* skip this element if it doesn't match our PCI address */
+		if (pci_addr_cmp(&uio_res->pci_addr, &dev->addr))
+			continue;
+
+		for (i = 0; i != uio_res->nb_maps; i++) {
+			/*
+			 * open devname, to mmap it
+			 */
+			fd = open(uio_res->maps[i].path, O_RDWR);
+			if (fd < 0) {
+				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+					uio_res->maps[i].path, strerror(errno));
+				return -1;
+			}
+
+			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
+					fd, (off_t)uio_res->maps[i].offset,
+					(size_t)uio_res->maps[i].size, 0);
+			/* fd is not needed in slave process, close it */
+			close(fd);
+			if (mapaddr != uio_res->maps[i].addr) {
+				RTE_LOG(ERR, EAL,
+					"Cannot mmap device resource file %s to address: %p\n",
+					uio_res->maps[i].path,
+					uio_res->maps[i].addr);
+				if (mapaddr != MAP_FAILED) {
+					/* unmap addrs correctly mapped */
+					for (j = 0; j < i; j++)
+						pci_unmap_resource(
+							uio_res->maps[j].addr,
+							(size_t)uio_res->maps[j].size);
+					/* unmap addr wrongly mapped */
+					pci_unmap_resource(mapaddr,
+						(size_t)uio_res->maps[i].size);
+				}
+				return -1;
+			}
+		}
+		return 0;
+	}
+
+	RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
+	return 1;
+}
+
+/* map the PCI resource of a PCI device in virtual memory */
+int
+pci_uio_map_resource(struct rte_pci_device *dev)
+{
+	int i, map_idx = 0, ret;
+	uint64_t phaddr;
+	struct mapped_pci_resource *uio_res = NULL;
+	struct mapped_pci_res_list *uio_res_list =
+		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.uio_cfg_fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+	/* secondary processes - use already recorded details */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return pci_uio_map_secondary(dev);
+
+	/* allocate uio resource */
+	ret = pci_uio_alloc_resource(dev, &uio_res);
+	if (ret)
+		return ret;
+
+	/* Map all BARs */
+	for (i = 0; i != PCI_MAX_RESOURCE; i++) {
+		/* skip empty BAR */
+		phaddr = dev->mem_resource[i].phys_addr;
+		if (phaddr == 0)
+			continue;
+
+		ret = pci_uio_map_resource_by_index(dev, i,
+				uio_res, map_idx);
+		if (ret)
+			goto error;
+
+		map_idx++;
+	}
+
+	uio_res->nb_maps = map_idx;
+
+	TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
+
+	return 0;
+error:
+	for (i = 0; i < map_idx; i++) {
+		pci_unmap_resource(uio_res->maps[i].addr,
+				(size_t)uio_res->maps[i].size);
+		rte_free(uio_res->maps[i].path);
+	}
+	pci_uio_free_resource(dev, uio_res);
+	return -1;
+}
+
+static void
+pci_uio_unmap(struct mapped_pci_resource *uio_res)
+{
+	int i;
+
+	if (uio_res == NULL)
+		return;
+
+	for (i = 0; i != uio_res->nb_maps; i++) {
+		pci_unmap_resource(uio_res->maps[i].addr,
+				(size_t)uio_res->maps[i].size);
+		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+			rte_free(uio_res->maps[i].path);
+	}
+}
+
+static struct mapped_pci_resource *
+pci_uio_find_resource(struct rte_pci_device *dev)
+{
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	if (dev == NULL)
+		return NULL;
+
+	TAILQ_FOREACH(uio_res, uio_res_list, next) {
+
+		/* skip this element if it doesn't match our PCI address */
+		if (!pci_addr_cmp(&uio_res->pci_addr, &dev->addr))
+			return uio_res;
+	}
+	return NULL;
+}
+
+/* unmap the PCI resource of a PCI device in virtual memory */
+void
+pci_uio_unmap_resource(struct rte_pci_device *dev)
+{
+	struct mapped_pci_resource *uio_res;
+	struct mapped_pci_res_list *uio_res_list =
+			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
+
+	if (dev == NULL)
+		return;
+
+	/* find an entry for the device */
+	uio_res = pci_uio_find_resource(dev);
+	if (uio_res == NULL)
+		return;
+
+	/* secondary processes - just free maps */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return pci_uio_unmap(uio_res);
+
+	TAILQ_REMOVE(uio_res_list, uio_res, next);
+
+	/* unmap all resources */
+	pci_uio_unmap(uio_res);
+
+	/* free uio resource */
+	rte_free(uio_res);
+
+	/* close fd if in primary process */
+	close(dev->intr_handle.fd);
+	if (dev->intr_handle.uio_cfg_fd >= 0) {
+		close(dev->intr_handle.uio_cfg_fd);
+		dev->intr_handle.uio_cfg_fd = -1;
+	}
+
+	dev->intr_handle.fd = -1;
+	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+}
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
new file mode 100644
index 0000000..2283f09
--- /dev/null
+++ b/drivers/bus/pci/private.h
@@ -0,0 +1,248 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 6WIND. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PCI_PRIVATE_H_
+#define _PCI_PRIVATE_H_
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+
+struct rte_pci_driver;
+struct rte_pci_device;
+
+/**
+ * Probe the PCI bus
+ *
+ * @return
+ *   - 0 on success.
+ *   - !0 on error.
+ */
+int
+rte_pci_probe(void);
+
+/**
+ * Scan the content of the PCI bus, and the devices in the devices
+ * list
+ *
+ * @return
+ *  0 on success, negative on error
+ */
+int rte_pci_scan(void);
+
+/**
+ * Probe the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the probe() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to probe.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_probe_one(const struct rte_pci_addr *addr);
+
+/**
+ * Close the single PCI device.
+ *
+ * Scan the content of the PCI bus, and find the pci device specified by pci
+ * address, then call the remove() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_pci_detach(const struct rte_pci_addr *addr);
+
+/**
+ * Find the name of a PCI device.
+ */
+void
+pci_name_set(struct rte_pci_device *dev);
+
+/**
+ * Add a PCI device to the PCI Bus (append to PCI Device list). This function
+ * also updates the bus references of the PCI Device (and the generic device
+ * object embedded within.
+ *
+ * @param pci_dev
+ *	PCI device to add
+ * @return void
+ */
+void rte_pci_add_device(struct rte_pci_device *pci_dev);
+
+/**
+ * Insert a PCI device in the PCI Bus at a particular location in the device
+ * list. It also updates the PCI Bus reference of the new devices to be
+ * inserted.
+ *
+ * @param exist_pci_dev
+ *	Existing PCI device in PCI Bus
+ * @param new_pci_dev
+ *	PCI device to be added before exist_pci_dev
+ * @return void
+ */
+void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+		struct rte_pci_device *new_pci_dev);
+
+/**
+ * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
+ * in the PCI device object as well as the generic device object.
+ *
+ * @param pci_device
+ *	PCI device to be removed from PCI Bus
+ * @return void
+ */
+void rte_pci_remove_device(struct rte_pci_device *pci_device);
+
+/**
+ * Update a pci device object by asking the kernel for the latest information.
+ *
+ * This function is private to EAL.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to look for
+ * @return
+ *   - 0 on success.
+ *   - negative on error.
+ */
+int pci_update_device(const struct rte_pci_addr *addr);
+
+/**
+ * Unbind kernel driver for this device
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_unbind_kernel_driver(struct rte_pci_device *dev);
+
+/**
+ * Map the PCI resource of a PCI device in virtual memory
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_map_resource(struct rte_pci_device *dev);
+
+/**
+ * Unmap the PCI resource of a PCI device
+ *
+ * This function is private to EAL.
+ */
+void pci_uio_unmap_resource(struct rte_pci_device *dev);
+
+/**
+ * Allocate uio resource for PCI device
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device to allocate uio resource
+ * @param uio_res
+ *   Pointer to uio resource.
+ *   If the function returns 0, the pointer will be filled.
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_alloc_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource **uio_res);
+
+/**
+ * Free uio resource for PCI device
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device to free uio resource
+ * @param uio_res
+ *   Pointer to uio resource.
+ */
+void pci_uio_free_resource(struct rte_pci_device *dev,
+		struct mapped_pci_resource *uio_res);
+
+/**
+ * Map device memory to uio resource
+ *
+ * This function is private to EAL.
+ *
+ * @param dev
+ *   PCI device that has memory information.
+ * @param res_idx
+ *   Memory resource index of the PCI device.
+ * @param uio_res
+ *  uio resource that will keep mapping information.
+ * @param map_idx
+ *   Mapping information index of the uio resource.
+ * @return
+ *   0 on success, negative on error
+ */
+int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
+		struct mapped_pci_resource *uio_res, int map_idx);
+
+/*
+ * Match the PCI Driver and Device using the ID Table
+ *
+ * @param pci_drv
+ *      PCI driver from which ID table would be extracted
+ * @param pci_dev
+ *      PCI device to match against the driver
+ * @return
+ *      1 for successful match
+ *      0 for unsuccessful match
+ */
+int
+rte_pci_match(const struct rte_pci_driver *pci_drv,
+	      const struct rte_pci_device *pci_dev);
+
+/**
+ * Get iommu class of PCI devices on the bus.
+ * And return their preferred iova mapping mode.
+ *
+ * @return
+ *   - enum rte_iova_mode.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void);
+
+#endif /* _PCI_PRIVATE_H_ */
diff --git a/drivers/bus/pci/rte_bus_pci_version.map b/drivers/bus/pci/rte_bus_pci_version.map
new file mode 100644
index 0000000..ee67033
--- /dev/null
+++ b/drivers/bus/pci/rte_bus_pci_version.map
@@ -0,0 +1,17 @@
+DPDK_17.11 {
+	global:
+
+	rte_pci_dump;
+	rte_pci_ioport_map;
+	rte_pci_ioport_read;
+	rte_pci_ioport_unmap;
+	rte_pci_ioport_write;
+	rte_pci_map_device;
+	rte_pci_read_config;
+	rte_pci_register;
+	rte_pci_unmap_device;
+	rte_pci_unregister;
+	rte_pci_write_config;
+
+	local: *;
+};
diff --git a/drivers/crypto/qat/Makefile b/drivers/crypto/qat/Makefile
index c38b80d..745d019 100644
--- a/drivers/crypto/qat/Makefile
+++ b/drivers/crypto/qat/Makefile
@@ -45,6 +45,7 @@ CFLAGS += -I$(SRCDIR)/qat_adf
 LDLIBS += -lcrypto
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_cryptodev
+LDLIBS += -lrte_pci -lrte_bus_pci
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat_crypto.c
diff --git a/drivers/crypto/qat/qat_qp.c b/drivers/crypto/qat/qat_qp.c
index 8bd60ff..814ba17 100644
--- a/drivers/crypto/qat/qat_qp.c
+++ b/drivers/crypto/qat/qat_qp.c
@@ -37,6 +37,7 @@
 #include <rte_memzone.h>
 #include <rte_cryptodev_pmd.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_prefetch.h>
 
diff --git a/drivers/crypto/qat/rte_qat_cryptodev.c b/drivers/crypto/qat/rte_qat_cryptodev.c
index 701c5a6..4f8e4bf 100644
--- a/drivers/crypto/qat/rte_qat_cryptodev.c
+++ b/drivers/crypto/qat/rte_qat_cryptodev.c
@@ -31,6 +31,7 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <rte_bus_pci.h>
 #include <rte_common.h>
 #include <rte_dev.h>
 #include <rte_malloc.h>
diff --git a/drivers/event/octeontx/Makefile b/drivers/event/octeontx/Makefile
index 59639b2..ae901a3 100644
--- a/drivers/event/octeontx/Makefile
+++ b/drivers/event/octeontx/Makefile
@@ -42,6 +42,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/mempool/octeontx/
 CFLAGS += -I$(RTE_SDK)/drivers/net/octeontx/
 
 LDLIBS += -lrte_eal -lrte_eventdev -lrte_mempool_octeontx
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_octeontx_ssovf_version.map
 
diff --git a/drivers/event/skeleton/Makefile b/drivers/event/skeleton/Makefile
index e4a9f41..65e1641 100644
--- a/drivers/event/skeleton/Makefile
+++ b/drivers/event/skeleton/Makefile
@@ -39,6 +39,7 @@ LIB = librte_pmd_skeleton_event.a
 
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_eventdev
+LDLIBS += -lrte_pci -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_skeleton_event_version.map
 
diff --git a/drivers/mempool/octeontx/Makefile b/drivers/mempool/octeontx/Makefile
index 4e8477b..a2e2863 100644
--- a/drivers/mempool/octeontx/Makefile
+++ b/drivers/mempool/octeontx/Makefile
@@ -63,5 +63,6 @@ CFLAGS_rte_mempool_octeontx.o += -Ofast
 endif
 
 LDLIBS += -lrte_eal -lrte_mempool -lrte_ring -lrte_mbuf
+LDLIBS += -lrte_bus_pci
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/mempool/octeontx/octeontx_fpavf.c b/drivers/mempool/octeontx/octeontx_fpavf.c
index 831c48d..07b6ffb 100644
--- a/drivers/mempool/octeontx/octeontx_fpavf.c
+++ b/drivers/mempool/octeontx/octeontx_fpavf.c
@@ -41,7 +41,7 @@
 
 #include <rte_atomic.h>
 #include <rte_eal.h>
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_errno.h>
 #include <rte_memory.h>
 #include <rte_malloc.h>
diff --git a/drivers/mempool/octeontx/octeontx_ssovf.c b/drivers/mempool/octeontx/octeontx_ssovf.c
index 9953b2e..012c887 100644
--- a/drivers/mempool/octeontx/octeontx_ssovf.c
+++ b/drivers/mempool/octeontx/octeontx_ssovf.c
@@ -35,6 +35,7 @@
 #include <rte_eal.h>
 #include <rte_io.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "octeontx_mbox.h"
 #include "octeontx_pool_logs.h"
diff --git a/drivers/net/ark/Makefile b/drivers/net/ark/Makefile
index 5f70415..f1433bd 100644
--- a/drivers/net/ark/Makefile
+++ b/drivers/net/ark/Makefile
@@ -64,5 +64,6 @@ LDLIBS += -ldl
 endif
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 1760628..ff87c20 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -35,6 +35,7 @@
 #include <sys/stat.h>
 #include <dlfcn.h>
 
+#include <rte_bus_pci.h>
 #include <rte_ethdev_pci.h>
 #include <rte_kvargs.h>
 
diff --git a/drivers/net/avp/Makefile b/drivers/net/avp/Makefile
index a754fa0..c29ecf4 100644
--- a/drivers/net/avp/Makefile
+++ b/drivers/net/avp/Makefile
@@ -41,6 +41,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_avp_version.map
 
diff --git a/drivers/net/avp/avp_ethdev.c b/drivers/net/avp/avp_ethdev.c
index 4b336bd..ad41222 100644
--- a/drivers/net/avp/avp_ethdev.c
+++ b/drivers/net/avp/avp_ethdev.c
@@ -36,6 +36,7 @@
 #include <errno.h>
 #include <unistd.h>
 
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_memcpy.h>
@@ -45,6 +46,7 @@
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
diff --git a/drivers/net/bnx2x/Makefile b/drivers/net/bnx2x/Makefile
index 762d42e..90ff8b1 100644
--- a/drivers/net/bnx2x/Makefile
+++ b/drivers/net/bnx2x/Makefile
@@ -11,6 +11,7 @@ CFLAGS += -DZLIB_CONST
 LDLIBS += -lz
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_bnx2x_version.map
 
diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 7aed17e..2aa0441 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -46,6 +46,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_bnxt_version.map
 
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 294a174..039b248 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -39,6 +39,7 @@
 #include <sys/queue.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_memory.h>
 #include <rte_lcore.h>
diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 84ef4ed..b86b240 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -40,6 +40,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_cmdline
+LDLIBS += -lrte_pci -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_bond_version.map
 
diff --git a/drivers/net/bonding/rte_eth_bond_args.c b/drivers/net/bonding/rte_eth_bond_args.c
index ebbcc5b..e816da3 100644
--- a/drivers/net/bonding/rte_eth_bond_args.c
+++ b/drivers/net/bonding/rte_eth_bond_args.c
@@ -33,6 +33,7 @@
 
 #include <rte_devargs.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 
 #include <cmdline_parse.h>
diff --git a/drivers/net/cxgbe/Makefile b/drivers/net/cxgbe/Makefile
index 49a49c7..65df142 100644
--- a/drivers/net/cxgbe/Makefile
+++ b/drivers/net/cxgbe/Makefile
@@ -64,6 +64,7 @@ CFLAGS_BASE_DRIVER =
 endif
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 #
 # Add extra flags for base driver files (also known as shared code)
diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index 5e5f221..f2057af 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -36,6 +36,7 @@
 #ifndef __T4_ADAPTER_H__
 #define __T4_ADAPTER_H__
 
+#include <rte_bus_pci.h>
 #include <rte_mbuf.h>
 #include <rte_io.h>
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 02b4f62..b1405e5 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/e1000/Makefile b/drivers/net/e1000/Makefile
index 833034e..3f0344b 100644
--- a/drivers/net/e1000/Makefile
+++ b/drivers/net/e1000/Makefile
@@ -40,6 +40,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_e1000_version.map
 
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index a3e72b7..4cabc7d 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index e829035..0a6c97e 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/e1000/igb_pf.c b/drivers/net/e1000/igb_pf.c
index 6809d30..cd6ae2f 100644
--- a/drivers/net/e1000/igb_pf.c
+++ b/drivers/net/e1000/igb_pf.c
@@ -39,6 +39,7 @@
 #include <stdarg.h>
 #include <inttypes.h>
 
+#include <rte_bus_pci.h>
 #include <rte_interrupts.h>
 #include <rte_log.h>
 #include <rte_debug.h>
diff --git a/drivers/net/ena/Makefile b/drivers/net/ena/Makefile
index 1cab5e2..f9bfe05 100644
--- a/drivers/net/ena/Makefile
+++ b/drivers/net/ena/Makefile
@@ -54,5 +54,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena_eth_com.c
 CFLAGS += $(INCLUDES)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/ena/ena_ethdev.h b/drivers/net/ena/ena_ethdev.h
index dc3080f..be8bc9f 100644
--- a/drivers/net/ena/ena_ethdev.h
+++ b/drivers/net/ena/ena_ethdev.h
@@ -35,6 +35,7 @@
 #define _ENA_ETHDEV_H_
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "ena_com.h"
 
diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile
index 6a99a99..5191db5 100644
--- a/drivers/net/enic/Makefile
+++ b/drivers/net/enic/Makefile
@@ -47,6 +47,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -Wno-strict-aliasing
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
+LDLIBS += -lrte_bus_pci
 
 VPATH += $(SRCDIR)/src
 
diff --git a/drivers/net/enic/base/vnic_dev.h b/drivers/net/enic/base/vnic_dev.h
index 9a9e691..c9ca25b 100644
--- a/drivers/net/enic/base/vnic_dev.h
+++ b/drivers/net/enic/base/vnic_dev.h
@@ -35,8 +35,10 @@
 #ifndef _VNIC_DEV_H_
 #define _VNIC_DEV_H_
 
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+
 #include "enic_compat.h"
-#include "rte_pci.h"
 #include "vnic_resource.h"
 #include "vnic_devcmd.h"
 
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index c02f9b7..669dbf3 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -37,6 +37,7 @@
 
 #include <rte_dev.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_string_fns.h>
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 7932605..f2e06e8 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -40,6 +40,7 @@
 #include <libgen.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_memzone.h>
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
diff --git a/drivers/net/fm10k/Makefile b/drivers/net/fm10k/Makefile
index 9d02c21..1129596 100644
--- a/drivers/net/fm10k/Makefile
+++ b/drivers/net/fm10k/Makefile
@@ -78,6 +78,7 @@ endif
 endif
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
+LDLIBS += -lrte_bus_pci
 
 #
 # Add extra flags for base driver source files to disable warnings in them
diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile
index 1ec6160..9ab8c84 100644
--- a/drivers/net/i40e/Makefile
+++ b/drivers/net/i40e/Makefile
@@ -41,6 +41,7 @@ CFLAGS += $(WERROR_FLAGS) -DPF_DRIVER -DVF_DRIVER -DINTEGRATED_VF
 CFLAGS += -DX722_A0_SUPPORT
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_i40e_version.map
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 33a5fa8..bcd9ef1 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -43,6 +43,7 @@
 #include <rte_eal.h>
 #include <rte_string_fns.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 6957f52..3b76c9e 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -47,6 +47,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
index f03c426..074d9f8 100644
--- a/drivers/net/ixgbe/Makefile
+++ b/drivers/net/ixgbe/Makefile
@@ -84,6 +84,7 @@ endif
 endif
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
+LDLIBS += -lrte_bus_pci
 
 #
 # Add extra flags for base driver files (also known as shared code)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 4339347..d207d54 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index f5b52c4..cf3733e 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -42,6 +42,7 @@
 #include <rte_time.h>
 #include <rte_hash.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tm_driver.h>
 
 /* need update link, bit flag */
diff --git a/drivers/net/liquidio/Makefile b/drivers/net/liquidio/Makefile
index 79120d1..5110099 100644
--- a/drivers/net/liquidio/Makefile
+++ b/drivers/net/liquidio/Makefile
@@ -42,6 +42,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)/base -I$(SRCDIR)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_lio_version.map
 
diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile
index fc5ea3c..f1f47c2 100644
--- a/drivers/net/mlx4/Makefile
+++ b/drivers/net/mlx4/Makefile
@@ -57,6 +57,7 @@ CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -libverbs -lmlx4
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 # A few warnings cannot be avoided in external headers.
 CFLAGS += -Wno-error=cast-qual
diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
index ca2170e..b0acd12 100644
--- a/drivers/net/mlx4/mlx4_ethdev.c
+++ b/drivers/net/mlx4/mlx4_ethdev.c
@@ -61,6 +61,7 @@
 #pragma GCC diagnostic error "-Wpedantic"
 #endif
 
+#include <rte_bus_pci.h>
 #include <rte_errno.h>
 #include <rte_ethdev.h>
 #include <rte_ether.h>
diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile
index 24c0789..a3984eb 100644
--- a/drivers/net/mlx5/Makefile
+++ b/drivers/net/mlx5/Makefile
@@ -67,6 +67,7 @@ CFLAGS += -Wno-strict-prototypes
 LDLIBS += -libverbs -lmlx5
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 # A few warnings cannot be avoided in external headers.
 CFLAGS += -Wno-error=cast-qual
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b7f7fa8..0548d17 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -54,6 +54,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_common.h>
 #include <rte_kvargs.h>
 
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index e06dce3..c31ea4b 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -56,6 +56,7 @@
 
 #include <rte_atomic.h>
 #include <rte_ethdev.h>
+#include <rte_bus_pci.h>
 #include <rte_mbuf.h>
 #include <rte_common.h>
 #include <rte_interrupts.h>
diff --git a/drivers/net/nfp/Makefile b/drivers/net/nfp/Makefile
index c1e51cb..4ba066a 100644
--- a/drivers/net/nfp/Makefile
+++ b/drivers/net/nfp/Makefile
@@ -42,6 +42,7 @@ CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lm
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_nfp_version.map
 
diff --git a/drivers/net/nfp/nfp_nfpu.c b/drivers/net/nfp/nfp_nfpu.c
index 556ded3..5775d8d 100644
--- a/drivers/net/nfp/nfp_nfpu.c
+++ b/drivers/net/nfp/nfp_nfpu.c
@@ -8,7 +8,7 @@
 #include <fcntl.h>
 #include <sys/types.h>
 
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_malloc.h>
 
 #include "nfp_nfpu.h"
diff --git a/drivers/net/nfp/nfp_nfpu.h b/drivers/net/nfp/nfp_nfpu.h
index 31511b3..e56fa09 100644
--- a/drivers/net/nfp/nfp_nfpu.h
+++ b/drivers/net/nfp/nfp_nfpu.h
@@ -42,7 +42,7 @@
  */
 
 
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include "nfp_nspu.h"
 
 typedef struct {
diff --git a/drivers/net/octeontx/Makefile b/drivers/net/octeontx/Makefile
index 30fb459..078fcd4 100644
--- a/drivers/net/octeontx/Makefile
+++ b/drivers/net/octeontx/Makefile
@@ -73,5 +73,6 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_mempool_octeontx
 LDLIBS += -lrte_eventdev
+LDLIBS += -lrte_bus_pci
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/octeontx/base/octeontx_pkivf.c b/drivers/net/octeontx/base/octeontx_pkivf.c
index f9e4053..b97f05c 100644
--- a/drivers/net/octeontx/base/octeontx_pkivf.c
+++ b/drivers/net/octeontx/base/octeontx_pkivf.c
@@ -32,7 +32,7 @@
 #include <string.h>
 
 #include <rte_eal.h>
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "octeontx_pkivf.h"
 
diff --git a/drivers/net/octeontx/base/octeontx_pkovf.c b/drivers/net/octeontx/base/octeontx_pkovf.c
index a8f6e5d..2bf607b 100644
--- a/drivers/net/octeontx/base/octeontx_pkovf.c
+++ b/drivers/net/octeontx/base/octeontx_pkovf.c
@@ -37,7 +37,7 @@
 #include <rte_cycles.h>
 #include <rte_malloc.h>
 #include <rte_memory.h>
-#include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_spinlock.h>
 
 #include "../octeontx_logs.h"
diff --git a/drivers/net/qede/Makefile b/drivers/net/qede/Makefile
index 5e8e087..a166e9f 100644
--- a/drivers/net/qede/Makefile
+++ b/drivers/net/qede/Makefile
@@ -15,6 +15,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_qede_version.map
 
diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile
index e097a66..2cfd62a 100644
--- a/drivers/net/sfc/Makefile
+++ b/drivers/net/sfc/Makefile
@@ -71,6 +71,7 @@ CFLAGS_sfc_ef10_tx.o += -wd3656
 endif
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 #
 # List of base driver object files for which
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index c170384..7f11bf2 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -35,6 +35,7 @@
 #include <stdbool.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 #include <rte_kvargs.h>
 #include <rte_spinlock.h>
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index cd82b0d..2f5f86f 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -33,6 +33,7 @@
 #include <rte_ethdev.h>
 #include <rte_ethdev_pci.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_errno.h>
 
 #include "efx.h"
diff --git a/drivers/net/szedata2/Makefile b/drivers/net/szedata2/Makefile
index f38125d..0ebd3ec 100644
--- a/drivers/net/szedata2/Makefile
+++ b/drivers/net/szedata2/Makefile
@@ -41,6 +41,7 @@ CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lsze2
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_szedata2_version.map
 
diff --git a/drivers/net/thunderx/Makefile b/drivers/net/thunderx/Makefile
index 183ac4b..e50e1ad 100644
--- a/drivers/net/thunderx/Makefile
+++ b/drivers/net/thunderx/Makefile
@@ -42,6 +42,7 @@ CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lm
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_thunderx_nicvf_version.map
 
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index 551b371..24ac3f9 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -61,6 +61,7 @@
 #include <rte_malloc.h>
 #include <rte_random.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_tailq.h>
 
 #include "base/nicvf_plat.h"
diff --git a/drivers/net/virtio/Makefile b/drivers/net/virtio/Makefile
index 156b2e8..32e99da 100644
--- a/drivers/net/virtio/Makefile
+++ b/drivers/net/virtio/Makefile
@@ -40,6 +40,7 @@ CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 EXPORT_MAP := rte_pmd_virtio_version.map
 
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index ff2d9d6..a8ae788 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -46,6 +46,7 @@
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ether.h>
 #include <rte_common.h>
 #include <rte_errno.h>
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 5f3b6c8..36d452c 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -37,6 +37,7 @@
 #include <stdint.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 
 struct virtqueue;
diff --git a/drivers/net/vmxnet3/Makefile b/drivers/net/vmxnet3/Makefile
index 9359a7b..f09de96 100644
--- a/drivers/net/vmxnet3/Makefile
+++ b/drivers/net/vmxnet3/Makefile
@@ -65,6 +65,7 @@ CFLAGS_BASE_DRIVER += -Wno-strict-aliasing -Wno-format-extra-args
 endif
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
+LDLIBS += -lrte_bus_pci
 
 VPATH += $(SRCDIR)/base
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 6328464..9037d80 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -48,6 +48,7 @@
 #include <rte_log.h>
 #include <rte_debug.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
diff --git a/lib/Makefile b/lib/Makefile
index 8693cda..dc4e8df 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-y += librte_compat
 DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
+DIRS-$(CONFIG_RTE_LIBRTE_PCI) += librte_pci
+DEPDIRS-librte_pci := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
 DEPDIRS-librte_ring := librte_eal
 DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 351fa57..934c12b 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -55,7 +55,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
@@ -69,8 +68,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_errno.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index af15812..09112b6 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -66,7 +66,6 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_bus.h>
-#include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_version.h>
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
deleted file mode 100644
index e73b7cd..0000000
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ /dev/null
@@ -1,680 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-#include <limits.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/pciio.h>
-#include <dev/pci/pcireg.h>
-
-#if defined(RTE_ARCH_X86)
-#include <machine/cpufunc.h>
-#endif
-
-#include <rte_interrupts.h>
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_common.h>
-#include <rte_launch.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_eal.h>
-#include <rte_eal_memconfig.h>
-#include <rte_per_lcore.h>
-#include <rte_lcore.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-#include <rte_debug.h>
-#include <rte_devargs.h>
-
-#include "eal_filesystem.h"
-#include "eal_private.h"
-
-/**
- * @file
- * PCI probing under linux
- *
- * This code is used to simulate a PCI probe by parsing information in
- * sysfs. Moreover, when a registered driver matches a device, the
- * kernel driver currently using it is unloaded and replaced by
- * igb_uio module, which is a very minimal userland driver for Intel
- * network card, only providing access to PCI BAR to applications, and
- * enabling bus master.
- */
-
-extern struct rte_pci_bus rte_pci_bus;
-
-/* Map pci device */
-int
-rte_pci_map_device(struct rte_pci_device *dev)
-{
-	int ret = -1;
-
-	/* try mapping the NIC resources */
-	switch (dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		/* map resources for devices that use uio */
-		ret = pci_uio_map_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		ret = 1;
-		break;
-	}
-
-	return ret;
-}
-
-/* Unmap pci device */
-void
-rte_pci_unmap_device(struct rte_pci_device *dev)
-{
-	/* try unmapping the NIC resources */
-	switch (dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		/* unmap resources for devices that use uio */
-		pci_uio_unmap_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		break;
-	}
-}
-
-void
-pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res)
-{
-	rte_free(uio_res);
-
-	if (dev->intr_handle.fd) {
-		close(dev->intr_handle.fd);
-		dev->intr_handle.fd = -1;
-		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	}
-}
-
-int
-pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res)
-{
-	char devname[PATH_MAX]; /* contains the /dev/uioX */
-	struct rte_pci_addr *loc;
-
-	loc = &dev->addr;
-
-	snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
-			dev->addr.bus, dev->addr.devid, dev->addr.function);
-
-	if (access(devname, O_RDWR) < 0) {
-		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
-				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
-		return 1;
-	}
-
-	/* save fd if in primary process */
-	dev->intr_handle.fd = open(devname, O_RDWR);
-	if (dev->intr_handle.fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			devname, strerror(errno));
-		goto error;
-	}
-	dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-
-	/* allocate the mapping details for secondary processes*/
-	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
-	if (*uio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto error;
-	}
-
-	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
-	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
-
-	return 0;
-
-error:
-	pci_uio_free_resource(dev, *uio_res);
-	return -1;
-}
-
-int
-pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx)
-{
-	int fd;
-	char *devname;
-	void *mapaddr;
-	uint64_t offset;
-	uint64_t pagesz;
-	struct pci_map *maps;
-
-	maps = uio_res->maps;
-	devname = uio_res->path;
-	pagesz = sysconf(_SC_PAGESIZE);
-
-	/* allocate memory to keep path */
-	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
-	if (maps[map_idx].path == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
-				strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * open resource file, to mmap it
-	 */
-	fd = open(devname, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				devname, strerror(errno));
-		goto error;
-	}
-
-	/* if matching map is found, then use it */
-	offset = res_idx * pagesz;
-	mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
-			(size_t)dev->mem_resource[res_idx].len, 0);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		goto error;
-
-	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
-	maps[map_idx].size = dev->mem_resource[res_idx].len;
-	maps[map_idx].addr = mapaddr;
-	maps[map_idx].offset = offset;
-	strcpy(maps[map_idx].path, devname);
-	dev->mem_resource[res_idx].addr = mapaddr;
-
-	return 0;
-
-error:
-	rte_free(maps[map_idx].path);
-	return -1;
-}
-
-static int
-pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
-{
-	struct rte_pci_device *dev;
-	struct pci_bar_io bar;
-	unsigned i, max;
-
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL) {
-		return -1;
-	}
-
-	memset(dev, 0, sizeof(*dev));
-	dev->addr.domain = conf->pc_sel.pc_domain;
-	dev->addr.bus = conf->pc_sel.pc_bus;
-	dev->addr.devid = conf->pc_sel.pc_dev;
-	dev->addr.function = conf->pc_sel.pc_func;
-
-	/* get vendor id */
-	dev->id.vendor_id = conf->pc_vendor;
-
-	/* get device id */
-	dev->id.device_id = conf->pc_device;
-
-	/* get subsystem_vendor id */
-	dev->id.subsystem_vendor_id = conf->pc_subvendor;
-
-	/* get subsystem_device id */
-	dev->id.subsystem_device_id = conf->pc_subdevice;
-
-	/* get class id */
-	dev->id.class_id = (conf->pc_class << 16) |
-			   (conf->pc_subclass << 8) |
-			   (conf->pc_progif);
-
-	/* TODO: get max_vfs */
-	dev->max_vfs = 0;
-
-	/* FreeBSD has no NUMA support (yet) */
-	dev->device.numa_node = 0;
-
-	pci_name_set(dev);
-
-	/* FreeBSD has only one pass through driver */
-	dev->kdrv = RTE_KDRV_NIC_UIO;
-
-	/* parse resources */
-	switch (conf->pc_hdr & PCIM_HDRTYPE) {
-	case PCIM_HDRTYPE_NORMAL:
-		max = PCIR_MAX_BAR_0;
-		break;
-	case PCIM_HDRTYPE_BRIDGE:
-		max = PCIR_MAX_BAR_1;
-		break;
-	case PCIM_HDRTYPE_CARDBUS:
-		max = PCIR_MAX_BAR_2;
-		break;
-	default:
-		goto skipdev;
-	}
-
-	for (i = 0; i <= max; i++) {
-		bar.pbi_sel = conf->pc_sel;
-		bar.pbi_reg = PCIR_BAR(i);
-		if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
-			continue;
-
-		dev->mem_resource[i].len = bar.pbi_length;
-		if (PCI_BAR_IO(bar.pbi_base)) {
-			dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
-			continue;
-		}
-		dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
-	}
-
-	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-		rte_pci_add_device(dev);
-	}
-	else {
-		struct rte_pci_device *dev2 = NULL;
-		int ret;
-
-		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr);
-			if (ret > 0)
-				continue;
-			else if (ret < 0) {
-				rte_pci_insert_device(dev2, dev);
-			} else { /* already registered */
-				dev2->kdrv = dev->kdrv;
-				dev2->max_vfs = dev->max_vfs;
-				pci_name_set(dev2);
-				memmove(dev2->mem_resource,
-					dev->mem_resource,
-					sizeof(dev->mem_resource));
-				free(dev);
-			}
-			return 0;
-		}
-		rte_pci_add_device(dev);
-	}
-
-	return 0;
-
-skipdev:
-	free(dev);
-	return 0;
-}
-
-/*
- * Scan the content of the PCI bus, and add the devices in the devices
- * list. Call pci_scan_one() for each pci entry found.
- */
-int
-rte_pci_scan(void)
-{
-	int fd;
-	unsigned dev_count = 0;
-	struct pci_conf matches[16];
-	struct pci_conf_io conf_io = {
-			.pat_buf_len = 0,
-			.num_patterns = 0,
-			.patterns = NULL,
-			.match_buf_len = sizeof(matches),
-			.matches = &matches[0],
-	};
-
-	/* for debug purposes, PCI can be disabled */
-	if (!rte_eal_has_pci())
-		return 0;
-
-	fd = open("/dev/pci", O_RDONLY);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	do {
-		unsigned i;
-		if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
-			RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
-					__func__, strerror(errno));
-			goto error;
-		}
-
-		for (i = 0; i < conf_io.num_matches; i++)
-			if (pci_scan_one(fd, &matches[i]) < 0)
-				goto error;
-
-		dev_count += conf_io.num_matches;
-	} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
-
-	close(fd);
-
-	RTE_LOG(DEBUG, EAL, "PCI scan found %u devices\n", dev_count);
-	return 0;
-
-error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/*
- * Get iommu class of PCI devices on the bus.
- */
-enum rte_iova_mode
-rte_pci_get_iommu_class(void)
-{
-	/* Supports only RTE_KDRV_NIC_UIO */
-	return RTE_IOVA_PA;
-}
-
-int
-pci_update_device(const struct rte_pci_addr *addr)
-{
-	int fd;
-	struct pci_conf matches[2];
-	struct pci_match_conf match = {
-		.pc_sel = {
-			.pc_domain = addr->domain,
-			.pc_bus = addr->bus,
-			.pc_dev = addr->devid,
-			.pc_func = addr->function,
-		},
-	};
-	struct pci_conf_io conf_io = {
-		.pat_buf_len = 0,
-		.num_patterns = 1,
-		.patterns = &match,
-		.match_buf_len = sizeof(matches),
-		.matches = &matches[0],
-	};
-
-	fd = open("/dev/pci", O_RDONLY);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
-				__func__, strerror(errno));
-		goto error;
-	}
-
-	if (conf_io.num_matches != 1)
-		goto error;
-
-	if (pci_scan_one(fd, &matches[0]) < 0)
-		goto error;
-
-	close(fd);
-
-	return 0;
-
-error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/* Read PCI config space. */
-int rte_pci_read_config(const struct rte_pci_device *dev,
-		void *buf, size_t len, off_t offset)
-{
-	int fd = -1;
-	int size;
-	struct pci_io pi = {
-		.pi_sel = {
-			.pc_domain = dev->addr.domain,
-			.pc_bus = dev->addr.bus,
-			.pc_dev = dev->addr.devid,
-			.pc_func = dev->addr.function,
-		},
-		.pi_reg = offset,
-	};
-
-	fd = open("/dev/pci", O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	while (len > 0) {
-		size = (len >= 4) ? 4 : ((len >= 2) ? 2 : 1);
-		pi.pi_width = size;
-
-		if (ioctl(fd, PCIOCREAD, &pi) < 0)
-			goto error;
-		memcpy(buf, &pi.pi_data, size);
-
-		buf = (char *)buf + size;
-		pi.pi_reg += size;
-		len -= size;
-	}
-	close(fd);
-
-	return 0;
-
- error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-/* Write PCI config space. */
-int rte_pci_write_config(const struct rte_pci_device *dev,
-		const void *buf, size_t len, off_t offset)
-{
-	int fd = -1;
-
-	struct pci_io pi = {
-		.pi_sel = {
-			.pc_domain = dev->addr.domain,
-			.pc_bus = dev->addr.bus,
-			.pc_dev = dev->addr.devid,
-			.pc_func = dev->addr.function,
-		},
-		.pi_reg = offset,
-		.pi_data = *(const uint32_t *)buf,
-		.pi_width = len,
-	};
-
-	if (len == 3 || len > sizeof(pi.pi_data)) {
-		RTE_LOG(ERR, EAL, "%s(): invalid pci read length\n", __func__);
-		goto error;
-	}
-
-	memcpy(&pi.pi_data, buf, len);
-
-	fd = open("/dev/pci", O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
-		goto error;
-	}
-
-	if (ioctl(fd, PCIOCWRITE, &pi) < 0)
-		goto error;
-
-	close(fd);
-	return 0;
-
- error:
-	if (fd >= 0)
-		close(fd);
-	return -1;
-}
-
-int
-rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p)
-{
-	int ret;
-
-	switch (dev->kdrv) {
-#if defined(RTE_ARCH_X86)
-	case RTE_KDRV_NIC_UIO:
-		if ((uintptr_t) dev->mem_resource[bar].addr <= UINT16_MAX) {
-			p->base = (uintptr_t)dev->mem_resource[bar].addr;
-			ret = 0;
-		} else
-			ret = -1;
-		break;
-#endif
-	default:
-		ret = -1;
-		break;
-	}
-
-	if (!ret)
-		p->dev = dev;
-
-	return ret;
-}
-
-static void
-pci_uio_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-#if defined(RTE_ARCH_X86)
-	uint8_t *d;
-	int size;
-	unsigned short reg = p->base + offset;
-
-	for (d = data; len > 0; d += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-			*(uint32_t *)d = inl(reg);
-		} else if (len >= 2) {
-			size = 2;
-			*(uint16_t *)d = inw(reg);
-		} else {
-			size = 1;
-			*d = inb(reg);
-		}
-	}
-#else
-	RTE_SET_USED(p);
-	RTE_SET_USED(data);
-	RTE_SET_USED(len);
-	RTE_SET_USED(offset);
-#endif
-}
-
-void
-rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	default:
-		break;
-	}
-}
-
-static void
-pci_uio_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-#if defined(RTE_ARCH_X86)
-	const uint8_t *s;
-	int size;
-	unsigned short reg = p->base + offset;
-
-	for (s = data; len > 0; s += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-			outl(reg, *(const uint32_t *)s);
-		} else if (len >= 2) {
-			size = 2;
-			outw(reg, *(const uint16_t *)s);
-		} else {
-			size = 1;
-			outb(reg, *s);
-		}
-	}
-#else
-	RTE_SET_USED(p);
-	RTE_SET_USED(data);
-	RTE_SET_USED(len);
-	RTE_SET_USED(offset);
-#endif
-}
-
-void
-rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-	case RTE_KDRV_NIC_UIO:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	default:
-		break;
-	}
-}
-
-int
-rte_pci_ioport_unmap(struct rte_pci_ioport *p)
-{
-	int ret;
-
-	switch (p->dev->kdrv) {
-#if defined(RTE_ARCH_X86)
-	case RTE_KDRV_NIC_UIO:
-		ret = 0;
-		break;
-#endif
-	default:
-		ret = -1;
-		break;
-	}
-
-	return ret;
-}
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 64ff811..16a2f26 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -34,7 +34,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 INC := rte_branch_prediction.h rte_common.h
 INC += rte_debug.h rte_eal.h rte_eal_interrupts.h
 INC += rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h
 INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
deleted file mode 100644
index 99e1765..0000000
--- a/lib/librte_eal/common/eal_common_pci.c
+++ /dev/null
@@ -1,699 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   Copyright 2013-2014 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-
-#include <rte_errno.h>
-#include <rte_interrupts.h>
-#include <rte_log.h>
-#include <rte_bus.h>
-#include <rte_pci.h>
-#include <rte_per_lcore.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_eal.h>
-#include <rte_string_fns.h>
-#include <rte_common.h>
-#include <rte_devargs.h>
-
-#include "eal_private.h"
-
-extern struct rte_pci_bus rte_pci_bus;
-
-#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
-
-const char *pci_get_sysfs_path(void)
-{
-	const char *path = NULL;
-
-	path = getenv("SYSFS_PCI_DEVICES");
-	if (path == NULL)
-		return SYSFS_PCI_DEVICES;
-
-	return path;
-}
-
-static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_pci_addr addr;
-	struct rte_bus *pbus;
-
-	pbus = rte_bus_find_by_name("pci");
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-		if (devargs->bus != pbus)
-			continue;
-		devargs->bus->parse(devargs->name, &addr);
-		if (!rte_pci_addr_cmp(&dev->addr, &addr))
-			return devargs;
-	}
-	return NULL;
-}
-
-static inline const char *
-get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
-{
-	unsigned long val;
-	uint8_t *u8 = _u8;
-	char *end;
-
-	errno = 0;
-	val = strtoul(in, &end, 16);
-	if (errno != 0 || end[0] != dlm || val > UINT8_MAX) {
-		errno = errno ? errno : EINVAL;
-		return NULL;
-	}
-	*u8 = (uint8_t)val;
-	return end + 1;
-}
-
-
-static int
-rte_pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
-{
-	const char *in = input;
-
-	dev_addr->domain = 0;
-	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
-	if (in == NULL)
-		return -EINVAL;
-	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
-	if (in == NULL)
-		return -EINVAL;
-	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
-	if (in == NULL)
-		return -EINVAL;
-	return 0;
-}
-
-int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	return rte_pci_bdf_parse(input, dev_addr);
-}
-
-static int
-rte_pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
-{
-	const char *in = input;
-	unsigned long val;
-	char *end;
-
-	errno = 0;
-	val = strtoul(in, &end, 16);
-	if (errno != 0 || end[0] != ':' || val > UINT16_MAX)
-		return -EINVAL;
-	dev_addr->domain = (uint16_t)val;
-	in = end + 1;
-	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
-	if (in == NULL)
-		return -EINVAL;
-	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
-	if (in == NULL)
-		return -EINVAL;
-	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
-	if (in == NULL)
-		return -EINVAL;
-	return 0;
-}
-
-int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
-	return rte_pci_dbdf_parse(input, dev_addr);
-}
-
-void
-rte_pci_device_name(const struct rte_pci_addr *addr,
-		     char *output, size_t size)
-{
-	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
-	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
-			    addr->domain, addr->bus,
-			    addr->devid, addr->function) >= 0);
-}
-
-int
-rte_pci_addr_cmp(const struct rte_pci_addr *addr,
-		 const struct rte_pci_addr *addr2)
-{
-	uint64_t dev_addr, dev_addr2;
-
-	if ((addr == NULL) || (addr2 == NULL))
-		 return -1;
-
-	dev_addr = ((uint64_t)addr->domain << 24) |
-		 (addr->bus << 16) | (addr->devid << 8) | addr->function;
-	dev_addr2 = ((uint64_t)addr2->domain << 24) |
-		 (addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
-
-	if (dev_addr > dev_addr2)
-		 return 1;
-	else if (dev_addr < dev_addr2)
-		 return -1;
-	else
-		 return 0;
-}
-
-int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			 const struct rte_pci_addr *addr2)
-{
-	return rte_pci_addr_cmp(addr, addr2);
-}
-
-int
-rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr)
-{
-	if (rte_pci_bdf_parse(str, addr) == 0 ||
-	    rte_pci_dbdf_parse(str, addr) == 0)
-		return 0;
-	return -1;
-}
-
-void
-pci_name_set(struct rte_pci_device *dev)
-{
-	struct rte_devargs *devargs;
-
-	/* Each device has its internal, canonical name set. */
-	rte_pci_device_name(&dev->addr,
-			dev->name, sizeof(dev->name));
-	devargs = pci_devargs_lookup(dev);
-	dev->device.devargs = devargs;
-	/* In blacklist mode, if the device is not blacklisted, no
-	 * rte_devargs exists for it.
-	 */
-	if (devargs != NULL)
-		/* If an rte_devargs exists, the generic rte_device uses the
-		 * given name as its namea
-		 */
-		dev->device.name = dev->device.devargs->name;
-	else
-		/* Otherwise, it uses the internal, canonical form. */
-		dev->device.name = dev->name;
-}
-
-/* map a particular resource from a file */
-void *
-pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
-		 int additional_flags)
-{
-	void *mapaddr;
-
-	/* Map the PCI memory resource of device */
-	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
-			MAP_SHARED | additional_flags, fd, offset);
-	if (mapaddr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
-			__func__, fd, requested_addr,
-			(unsigned long)size, (unsigned long)offset,
-			strerror(errno), mapaddr);
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
-
-	return mapaddr;
-}
-
-/* unmap a particular resource */
-void
-pci_unmap_resource(void *requested_addr, size_t size)
-{
-	if (requested_addr == NULL)
-		return;
-
-	/* Unmap the PCI memory resource of device */
-	if (munmap(requested_addr, size)) {
-		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
-			__func__, requested_addr, (unsigned long)size,
-			strerror(errno));
-	} else
-		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
-				requested_addr);
-}
-
-/*
- * Match the PCI Driver and Device using the ID Table
- */
-int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev)
-{
-	const struct rte_pci_id *id_table;
-
-	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
-	     id_table++) {
-		/* check if device's identifiers match the driver's ones */
-		if (id_table->vendor_id != pci_dev->id.vendor_id &&
-				id_table->vendor_id != PCI_ANY_ID)
-			continue;
-		if (id_table->device_id != pci_dev->id.device_id &&
-				id_table->device_id != PCI_ANY_ID)
-			continue;
-		if (id_table->subsystem_vendor_id !=
-		    pci_dev->id.subsystem_vendor_id &&
-		    id_table->subsystem_vendor_id != PCI_ANY_ID)
-			continue;
-		if (id_table->subsystem_device_id !=
-		    pci_dev->id.subsystem_device_id &&
-		    id_table->subsystem_device_id != PCI_ANY_ID)
-			continue;
-		if (id_table->class_id != pci_dev->id.class_id &&
-				id_table->class_id != RTE_CLASS_ANY_ID)
-			continue;
-
-		return 1;
-	}
-
-	return 0;
-}
-
-/*
- * If vendor/device ID match, call the probe() function of the
- * driver.
- */
-static int
-rte_pci_probe_one_driver(struct rte_pci_driver *dr,
-			 struct rte_pci_device *dev)
-{
-	int ret;
-	struct rte_pci_addr *loc;
-
-	if ((dr == NULL) || (dev == NULL))
-		return -EINVAL;
-
-	loc = &dev->addr;
-
-	/* The device is not blacklisted; Check if driver supports it */
-	if (!rte_pci_match(dr, dev))
-		/* Match of device and driver failed */
-		return 1;
-
-	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-			loc->domain, loc->bus, loc->devid, loc->function,
-			dev->device.numa_node);
-
-	/* no initialization when blacklisted, return without error */
-	if (dev->device.devargs != NULL &&
-		dev->device.devargs->policy ==
-			RTE_DEV_BLACKLISTED) {
-		RTE_LOG(INFO, EAL, "  Device is blacklisted, not"
-			" initializing\n");
-		return 1;
-	}
-
-	if (dev->device.numa_node < 0) {
-		RTE_LOG(WARNING, EAL, "  Invalid NUMA socket, default to 0\n");
-		dev->device.numa_node = 0;
-	}
-
-	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
-		dev->id.device_id, dr->driver.name);
-
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
-		/* map resources for devices that use igb_uio */
-		ret = rte_pci_map_device(dev);
-		if (ret != 0)
-			return ret;
-	}
-
-	/* reference driver structure */
-	dev->driver = dr;
-	dev->device.driver = &dr->driver;
-
-	/* call the driver probe() function */
-	ret = dr->probe(dr, dev);
-	if (ret) {
-		dev->driver = NULL;
-		dev->device.driver = NULL;
-		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
-			/* Don't unmap if device is unsupported and
-			 * driver needs mapped resources.
-			 */
-			!(ret > 0 &&
-				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
-			rte_pci_unmap_device(dev);
-	}
-
-	return ret;
-}
-
-/*
- * If vendor/device ID match, call the remove() function of the
- * driver.
- */
-static int
-rte_pci_detach_dev(struct rte_pci_device *dev)
-{
-	struct rte_pci_addr *loc;
-	struct rte_pci_driver *dr;
-	int ret = 0;
-
-	if (dev == NULL)
-		return -EINVAL;
-
-	dr = dev->driver;
-	loc = &dev->addr;
-
-	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
-			loc->domain, loc->bus, loc->devid,
-			loc->function, dev->device.numa_node);
-
-	RTE_LOG(DEBUG, EAL, "  remove driver: %x:%x %s\n", dev->id.vendor_id,
-			dev->id.device_id, dr->driver.name);
-
-	if (dr->remove) {
-		ret = dr->remove(dev);
-		if (ret < 0)
-			return ret;
-	}
-
-	/* clear driver structure */
-	dev->driver = NULL;
-
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
-		/* unmap resources for devices that use igb_uio */
-		rte_pci_unmap_device(dev);
-
-	return 0;
-}
-
-/*
- * If vendor/device ID match, call the probe() function of all
- * registered driver for the given device. Return -1 if initialization
- * failed, return 1 if no driver is found for this device.
- */
-static int
-pci_probe_all_drivers(struct rte_pci_device *dev)
-{
-	struct rte_pci_driver *dr = NULL;
-	int rc = 0;
-
-	if (dev == NULL)
-		return -1;
-
-	/* Check if a driver is already loaded */
-	if (dev->driver != NULL)
-		return 0;
-
-	FOREACH_DRIVER_ON_PCIBUS(dr) {
-		rc = rte_pci_probe_one_driver(dr, dev);
-		if (rc < 0)
-			/* negative value is an error */
-			return -1;
-		if (rc > 0)
-			/* positive value means driver doesn't support it */
-			continue;
-		return 0;
-	}
-	return 1;
-}
-
-/*
- * Find the pci device specified by pci address, then invoke probe function of
- * the driver of the device.
- */
-int
-rte_pci_probe_one(const struct rte_pci_addr *addr)
-{
-	struct rte_pci_device *dev = NULL;
-
-	int ret = 0;
-
-	if (addr == NULL)
-		return -1;
-
-	/* update current pci device in global list, kernel bindings might have
-	 * changed since last time we looked at it.
-	 */
-	if (pci_update_device(addr) < 0)
-		goto err_return;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_pci_addr_cmp(&dev->addr, addr))
-			continue;
-
-		ret = pci_probe_all_drivers(dev);
-		if (ret)
-			goto err_return;
-		return 0;
-	}
-	return -1;
-
-err_return:
-	RTE_LOG(WARNING, EAL,
-		"Requested device " PCI_PRI_FMT " cannot be used\n",
-		addr->domain, addr->bus, addr->devid, addr->function);
-	return -1;
-}
-
-/*
- * Detach device specified by its pci address.
- */
-int
-rte_pci_detach(const struct rte_pci_addr *addr)
-{
-	struct rte_pci_device *dev = NULL;
-	int ret = 0;
-
-	if (addr == NULL)
-		return -1;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (rte_pci_addr_cmp(&dev->addr, addr))
-			continue;
-
-		ret = rte_pci_detach_dev(dev);
-		if (ret < 0)
-			/* negative value is an error */
-			goto err_return;
-		if (ret > 0)
-			/* positive value means driver doesn't support it */
-			continue;
-
-		rte_pci_remove_device(dev);
-		free(dev);
-		return 0;
-	}
-	return -1;
-
-err_return:
-	RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT
-			" cannot be used\n", dev->addr.domain, dev->addr.bus,
-			dev->addr.devid, dev->addr.function);
-	return -1;
-}
-
-/*
- * Scan the content of the PCI bus, and call the probe() function for
- * all registered drivers that have a matching entry in its id_table
- * for discovered devices.
- */
-int
-rte_pci_probe(void)
-{
-	struct rte_pci_device *dev = NULL;
-	size_t probed = 0, failed = 0;
-	struct rte_devargs *devargs;
-	int probe_all = 0;
-	int ret = 0;
-
-	if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST)
-		probe_all = 1;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		probed++;
-
-		devargs = dev->device.devargs;
-		/* probe all or only whitelisted devices */
-		if (probe_all)
-			ret = pci_probe_all_drivers(dev);
-		else if (devargs != NULL &&
-			devargs->policy == RTE_DEV_WHITELISTED)
-			ret = pci_probe_all_drivers(dev);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
-				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
-				 dev->addr.devid, dev->addr.function);
-			rte_errno = errno;
-			failed++;
-			ret = 0;
-		}
-	}
-
-	return (probed && probed == failed) ? -1 : 0;
-}
-
-/* dump one device */
-static int
-pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
-{
-	int i;
-
-	fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
-	       dev->addr.devid, dev->addr.function);
-	fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
-	       dev->id.device_id);
-
-	for (i = 0; i != sizeof(dev->mem_resource) /
-		sizeof(dev->mem_resource[0]); i++) {
-		fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
-			dev->mem_resource[i].phys_addr,
-			dev->mem_resource[i].len);
-	}
-	return 0;
-}
-
-/* dump devices on the bus */
-void
-rte_pci_dump(FILE *f)
-{
-	struct rte_pci_device *dev = NULL;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		pci_dump_one_device(f, dev);
-	}
-}
-
-static int
-pci_parse(const char *name, void *addr)
-{
-	struct rte_pci_addr *out = addr;
-	struct rte_pci_addr pci_addr;
-	bool parse;
-
-	parse = (rte_pci_addr_parse(name, &pci_addr) == 0);
-	if (parse && addr != NULL)
-		*out = pci_addr;
-	return parse == false;
-}
-
-/* register a driver */
-void
-rte_pci_register(struct rte_pci_driver *driver)
-{
-	TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);
-	driver->bus = &rte_pci_bus;
-}
-
-/* unregister a driver */
-void
-rte_pci_unregister(struct rte_pci_driver *driver)
-{
-	TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next);
-	driver->bus = NULL;
-}
-
-/* Add a device to PCI bus */
-void
-rte_pci_add_device(struct rte_pci_device *pci_dev)
-{
-	TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next);
-}
-
-/* Insert a device into a predefined position in PCI bus */
-void
-rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
-		      struct rte_pci_device *new_pci_dev)
-{
-	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
-}
-
-/* Remove a device from PCI bus */
-void
-rte_pci_remove_device(struct rte_pci_device *pci_dev)
-{
-	TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next);
-}
-
-static struct rte_device *
-pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
-		const void *data)
-{
-	struct rte_pci_device *dev;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (start && &dev->device == start) {
-			start = NULL; /* starting point found */
-			continue;
-		}
-		if (cmp(&dev->device, data) == 0)
-			return &dev->device;
-	}
-
-	return NULL;
-}
-
-static int
-pci_plug(struct rte_device *dev)
-{
-	return pci_probe_all_drivers(RTE_DEV_TO_PCI(dev));
-}
-
-static int
-pci_unplug(struct rte_device *dev)
-{
-	struct rte_pci_device *pdev;
-	int ret;
-
-	pdev = RTE_DEV_TO_PCI(dev);
-	ret = rte_pci_detach_dev(pdev);
-	if (ret == 0) {
-		rte_pci_remove_device(pdev);
-		free(pdev);
-	}
-	return ret;
-}
-
-struct rte_pci_bus rte_pci_bus = {
-	.bus = {
-		.scan = rte_pci_scan,
-		.probe = rte_pci_probe,
-		.find_device = pci_find_device,
-		.plug = pci_plug,
-		.unplug = pci_unplug,
-		.parse = pci_parse,
-		.get_iommu_class = rte_pci_get_iommu_class,
-	},
-	.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
-	.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
-};
-
-RTE_REGISTER_BUS(pci, rte_pci_bus.bus);
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
deleted file mode 100644
index 9df3833..0000000
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include <rte_eal.h>
-#include <rte_tailq.h>
-#include <rte_log.h>
-#include <rte_malloc.h>
-
-#include "eal_private.h"
-
-static struct rte_tailq_elem rte_uio_tailq = {
-	.name = "UIO_RESOURCE_LIST",
-};
-EAL_REGISTER_TAILQ(rte_uio_tailq)
-
-static int
-pci_uio_map_secondary(struct rte_pci_device *dev)
-{
-	int fd, i, j;
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	TAILQ_FOREACH(uio_res, uio_res_list, next) {
-
-		/* skip this element if it doesn't match our PCI address */
-		if (rte_pci_addr_cmp(&uio_res->pci_addr, &dev->addr))
-			continue;
-
-		for (i = 0; i != uio_res->nb_maps; i++) {
-			/*
-			 * open devname, to mmap it
-			 */
-			fd = open(uio_res->maps[i].path, O_RDWR);
-			if (fd < 0) {
-				RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-					uio_res->maps[i].path, strerror(errno));
-				return -1;
-			}
-
-			void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
-					fd, (off_t)uio_res->maps[i].offset,
-					(size_t)uio_res->maps[i].size, 0);
-			/* fd is not needed in slave process, close it */
-			close(fd);
-			if (mapaddr != uio_res->maps[i].addr) {
-				RTE_LOG(ERR, EAL,
-					"Cannot mmap device resource file %s to address: %p\n",
-					uio_res->maps[i].path,
-					uio_res->maps[i].addr);
-				if (mapaddr != MAP_FAILED) {
-					/* unmap addrs correctly mapped */
-					for (j = 0; j < i; j++)
-						pci_unmap_resource(
-							uio_res->maps[j].addr,
-							(size_t)uio_res->maps[j].size);
-					/* unmap addr wrongly mapped */
-					pci_unmap_resource(mapaddr,
-						(size_t)uio_res->maps[i].size);
-				}
-				return -1;
-			}
-		}
-		return 0;
-	}
-
-	RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
-	return 1;
-}
-
-/* map the PCI resource of a PCI device in virtual memory */
-int
-pci_uio_map_resource(struct rte_pci_device *dev)
-{
-	int i, map_idx = 0, ret;
-	uint64_t phaddr;
-	struct mapped_pci_resource *uio_res = NULL;
-	struct mapped_pci_res_list *uio_res_list =
-		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.uio_cfg_fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* secondary processes - use already recorded details */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return pci_uio_map_secondary(dev);
-
-	/* allocate uio resource */
-	ret = pci_uio_alloc_resource(dev, &uio_res);
-	if (ret)
-		return ret;
-
-	/* Map all BARs */
-	for (i = 0; i != PCI_MAX_RESOURCE; i++) {
-		/* skip empty BAR */
-		phaddr = dev->mem_resource[i].phys_addr;
-		if (phaddr == 0)
-			continue;
-
-		ret = pci_uio_map_resource_by_index(dev, i,
-				uio_res, map_idx);
-		if (ret)
-			goto error;
-
-		map_idx++;
-	}
-
-	uio_res->nb_maps = map_idx;
-
-	TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
-
-	return 0;
-error:
-	for (i = 0; i < map_idx; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
-				(size_t)uio_res->maps[i].size);
-		rte_free(uio_res->maps[i].path);
-	}
-	pci_uio_free_resource(dev, uio_res);
-	return -1;
-}
-
-static void
-pci_uio_unmap(struct mapped_pci_resource *uio_res)
-{
-	int i;
-
-	if (uio_res == NULL)
-		return;
-
-	for (i = 0; i != uio_res->nb_maps; i++) {
-		pci_unmap_resource(uio_res->maps[i].addr,
-				(size_t)uio_res->maps[i].size);
-		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-			rte_free(uio_res->maps[i].path);
-	}
-}
-
-static struct mapped_pci_resource *
-pci_uio_find_resource(struct rte_pci_device *dev)
-{
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	if (dev == NULL)
-		return NULL;
-
-	TAILQ_FOREACH(uio_res, uio_res_list, next) {
-
-		/* skip this element if it doesn't match our PCI address */
-		if (!rte_pci_addr_cmp(&uio_res->pci_addr, &dev->addr))
-			return uio_res;
-	}
-	return NULL;
-}
-
-/* unmap the PCI resource of a PCI device in virtual memory */
-void
-pci_uio_unmap_resource(struct rte_pci_device *dev)
-{
-	struct mapped_pci_resource *uio_res;
-	struct mapped_pci_res_list *uio_res_list =
-			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-
-	if (dev == NULL)
-		return;
-
-	/* find an entry for the device */
-	uio_res = pci_uio_find_resource(dev);
-	if (uio_res == NULL)
-		return;
-
-	/* secondary processes - just free maps */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return pci_uio_unmap(uio_res);
-
-	TAILQ_REMOVE(uio_res_list, uio_res, next);
-
-	/* unmap all resources */
-	pci_uio_unmap(uio_res);
-
-	/* free uio resource */
-	rte_free(uio_res);
-
-	/* close fd if in primary process */
-	close(dev->intr_handle.fd);
-	if (dev->intr_handle.uio_cfg_fd >= 0) {
-		close(dev->intr_handle.uio_cfg_fd);
-		dev->intr_handle.uio_cfg_fd = -1;
-	}
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 4eb1bd2..462226f 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -37,7 +37,6 @@
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
-#include <rte_pci.h>
 
 /**
  * Initialize the memzone subsystem (private to eal).
@@ -110,211 +109,6 @@ int rte_eal_timer_init(void);
  */
 int rte_eal_log_init(const char *id, int facility);
 
-struct rte_pci_driver;
-struct rte_pci_device;
-
-/**
- * Probe the PCI bus
- *
- * @return
- *   - 0 on success.
- *   - !0 on error.
- */
-int
-rte_pci_probe(void);
-
-/**
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- *
- * @return
- *  0 on success, negative on error
- */
-int rte_pci_scan(void);
-
-/**
- * Probe the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the probe() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *     The PCI Bus-Device-Function address to probe.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_probe_one(const struct rte_pci_addr *addr);
-
-/**
- * Close the single PCI device.
- *
- * Scan the content of the PCI bus, and find the pci device specified by pci
- * address, then call the remove() function for registered driver that has a
- * matching entry in its id_table for discovered device.
- *
- * @param addr
- *     The PCI Bus-Device-Function address to close.
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_pci_detach(const struct rte_pci_addr *addr);
-
-/**
- * Find the name of a PCI device.
- */
-void pci_name_set(struct rte_pci_device *dev);
-
-/**
- * Add a PCI device to the PCI Bus (append to PCI Device list). This function
- * also updates the bus references of the PCI Device (and the generic device
- * object embedded within.
- *
- * @param pci_dev
- *	PCI device to add
- * @return void
- */
-void rte_pci_add_device(struct rte_pci_device *pci_dev);
-
-/**
- * Insert a PCI device in the PCI Bus at a particular location in the device
- * list. It also updates the PCI Bus reference of the new devices to be
- * inserted.
- *
- * @param exist_pci_dev
- *	Existing PCI device in PCI Bus
- * @param new_pci_dev
- *	PCI device to be added before exist_pci_dev
- * @return void
- */
-void rte_pci_insert_device(struct rte_pci_device *exist_pci_dev,
-		struct rte_pci_device *new_pci_dev);
-
-/**
- * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
- * in the PCI device object as well as the generic device object.
- *
- * @param pci_device
- *	PCI device to be removed from PCI Bus
- * @return void
- */
-void rte_pci_remove_device(struct rte_pci_device *pci_device);
-
-/**
- * Update a pci device object by asking the kernel for the latest information.
- *
- * This function is private to EAL.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to look for
- * @return
- *   - 0 on success.
- *   - negative on error.
- */
-int pci_update_device(const struct rte_pci_addr *addr);
-
-/**
- * Unbind kernel driver for this device
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int pci_unbind_kernel_driver(struct rte_pci_device *dev);
-
-/**
- * Map the PCI resource of a PCI device in virtual memory
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_map_resource(struct rte_pci_device *dev);
-
-/**
- * Unmap the PCI resource of a PCI device
- *
- * This function is private to EAL.
- */
-void pci_uio_unmap_resource(struct rte_pci_device *dev);
-
-/**
- * Allocate uio resource for PCI device
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device to allocate uio resource
- * @param uio_res
- *   Pointer to uio resource.
- *   If the function returns 0, the pointer will be filled.
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res);
-
-/**
- * Free uio resource for PCI device
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device to free uio resource
- * @param uio_res
- *   Pointer to uio resource.
- */
-void pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res);
-
-/**
- * Map device memory to uio resource
- *
- * This function is private to EAL.
- *
- * @param dev
- *   PCI device that has memory information.
- * @param res_idx
- *   Memory resource index of the PCI device.
- * @param uio_res
- *  uio resource that will keep mapping information.
- * @param map_idx
- *   Mapping information index of the uio resource.
- * @return
- *   0 on success, negative on error
- */
-int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx);
-
-/*
- * Match the PCI Driver and Device using the ID Table
- *
- * @param pci_drv
- *      PCI driver from which ID table would be extracted
- * @param pci_dev
- *      PCI device to match against the driver
- * @return
- *      1 for successful match
- *      0 for unsuccessful match
- */
-int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev);
-
-/**
- * Get iommu class of PCI devices on the bus.
- * And return their preferred iova mapping mode.
- *
- * @return
- *   - enum rte_iova_mode.
- */
-enum rte_iova_mode
-rte_pci_get_iommu_class(void);
-
 /**
  * Init tail queues for non-EAL library structures. This is to allow
  * the rings, mempools, etc. lists to be shared among multiple processes
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
deleted file mode 100644
index 3c8cbd8..0000000
--- a/lib/librte_eal/common/include/rte_pci.h
+++ /dev/null
@@ -1,533 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   Copyright 2013-2014 6WIND S.A.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_PCI_H_
-#define _RTE_PCI_H_
-
-/**
- * @file
- *
- * RTE PCI Interface
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <errno.h>
-#include <sys/queue.h>
-#include <stdint.h>
-#include <inttypes.h>
-
-#include <rte_debug.h>
-#include <rte_interrupts.h>
-#include <rte_dev.h>
-#include <rte_bus.h>
-
-/** Pathname of PCI devices directory. */
-const char *pci_get_sysfs_path(void);
-
-/** Formatting string for PCI device identifier: Ex: 0000:00:01.0 */
-#define PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
-#define PCI_PRI_STR_SIZE sizeof("XXXXXXXX:XX:XX.X")
-
-/** Short formatting string, without domain, for PCI device: Ex: 00:01.0 */
-#define PCI_SHORT_PRI_FMT "%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
-
-/** Nb. of values in PCI device identifier format string. */
-#define PCI_FMT_NVAL 4
-
-/** Nb. of values in PCI resource format. */
-#define PCI_RESOURCE_FMT_NVAL 3
-
-/** Maximum number of PCI resources. */
-#define PCI_MAX_RESOURCE 6
-
-/* Forward declarations */
-struct rte_pci_device;
-struct rte_pci_driver;
-
-/** List of PCI devices */
-TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
-/** List of PCI drivers */
-TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
-
-/* PCI Bus iterators */
-#define FOREACH_DEVICE_ON_PCIBUS(p)	\
-		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
-
-#define FOREACH_DRIVER_ON_PCIBUS(p)	\
-		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
-
-/**
- * A structure describing an ID for a PCI driver. Each driver provides a
- * table of these IDs for each device that it supports.
- */
-struct rte_pci_id {
-	uint32_t class_id;            /**< Class ID (class, subclass, pi) or RTE_CLASS_ANY_ID. */
-	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
-	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
-	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
-	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
-};
-
-/**
- * A structure describing the location of a PCI device.
- */
-struct rte_pci_addr {
-	uint32_t domain;                /**< Device domain */
-	uint8_t bus;                    /**< Device bus */
-	uint8_t devid;                  /**< Device ID */
-	uint8_t function;               /**< Device function. */
-};
-
-struct rte_devargs;
-
-/**
- * A structure describing a PCI device.
- */
-struct rte_pci_device {
-	TAILQ_ENTRY(rte_pci_device) next;       /**< Next probed PCI device. */
-	struct rte_device device;               /**< Inherit core device */
-	struct rte_pci_addr addr;               /**< PCI location. */
-	struct rte_pci_id id;                   /**< PCI ID. */
-	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
-						/**< PCI Memory Resource */
-	struct rte_intr_handle intr_handle;     /**< Interrupt handle */
-	struct rte_pci_driver *driver;          /**< Associated driver */
-	uint16_t max_vfs;                       /**< sriov enable if not zero */
-	enum rte_kernel_driver kdrv;            /**< Kernel driver passthrough */
-	char name[PCI_PRI_STR_SIZE+1];          /**< PCI location (ASCII) */
-};
-
-/**
- * @internal
- * Helper macro for drivers that need to convert to struct rte_pci_device.
- */
-#define RTE_DEV_TO_PCI(ptr) container_of(ptr, struct rte_pci_device, device)
-
-/** Any PCI device identifier (vendor, device, ...) */
-#define PCI_ANY_ID (0xffff)
-#define RTE_CLASS_ANY_ID (0xffffff)
-
-#ifdef __cplusplus
-/** C++ macro used to help building up tables of device IDs */
-#define RTE_PCI_DEVICE(vend, dev) \
-	RTE_CLASS_ANY_ID,         \
-	(vend),                   \
-	(dev),                    \
-	PCI_ANY_ID,               \
-	PCI_ANY_ID
-#else
-/** Macro used to help building up tables of device IDs */
-#define RTE_PCI_DEVICE(vend, dev)          \
-	.class_id = RTE_CLASS_ANY_ID,      \
-	.vendor_id = (vend),               \
-	.device_id = (dev),                \
-	.subsystem_vendor_id = PCI_ANY_ID, \
-	.subsystem_device_id = PCI_ANY_ID
-#endif
-
-/**
- * Initialisation function for the driver called during PCI probing.
- */
-typedef int (pci_probe_t)(struct rte_pci_driver *, struct rte_pci_device *);
-
-/**
- * Uninitialisation function for the driver called during hotplugging.
- */
-typedef int (pci_remove_t)(struct rte_pci_device *);
-
-/**
- * A structure describing a PCI driver.
- */
-struct rte_pci_driver {
-	TAILQ_ENTRY(rte_pci_driver) next;       /**< Next in list. */
-	struct rte_driver driver;               /**< Inherit core driver. */
-	struct rte_pci_bus *bus;                /**< PCI bus reference. */
-	pci_probe_t *probe;                     /**< Device Probe function. */
-	pci_remove_t *remove;                   /**< Device Remove function. */
-	const struct rte_pci_id *id_table;	/**< ID table, NULL terminated. */
-	uint32_t drv_flags;                     /**< Flags contolling handling of device. */
-};
-
-/**
- * Structure describing the PCI bus
- */
-struct rte_pci_bus {
-	struct rte_bus bus;               /**< Inherit the generic class */
-	struct rte_pci_device_list device_list;  /**< List of PCI devices */
-	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
-};
-
-/** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
-#define RTE_PCI_DRV_NEED_MAPPING 0x0001
-/** Device driver supports link state interrupt */
-#define RTE_PCI_DRV_INTR_LSC	0x0008
-/** Device driver supports device removal interrupt */
-#define RTE_PCI_DRV_INTR_RMV 0x0010
-/** Device driver needs to keep mapped resources if unsupported dev detected */
-#define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
-/** Device driver supports IOVA as VA */
-#define RTE_PCI_DRV_IOVA_AS_VA 0X0040
-
-/**
- * A structure describing a PCI mapping.
- */
-struct pci_map {
-	void *addr;
-	char *path;
-	uint64_t offset;
-	uint64_t size;
-	uint64_t phaddr;
-};
-
-struct pci_msix_table {
-	int bar_index;
-	uint32_t offset;
-	uint32_t size;
-};
-
-/**
- * A structure describing a mapped PCI resource.
- * For multi-process we need to reproduce all PCI mappings in secondary
- * processes, so save them in a tailq.
- */
-struct mapped_pci_resource {
-	TAILQ_ENTRY(mapped_pci_resource) next;
-
-	struct rte_pci_addr pci_addr;
-	char path[PATH_MAX];
-	int nb_maps;
-	struct pci_map maps[PCI_MAX_RESOURCE];
-	struct pci_msix_table msix_table;
-};
-
-/** mapped pci device list */
-TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
-
-/**
- * @deprecated
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided without
- * a domain prefix (i.e. domain returned is always 0)
- *
- * @param input
- *	The input string to be parsed. Should have the format XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned. Domain will always be
- *	returned as 0
- * @return
- *  0 on success, negative on error.
- */
-int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
-
-/**
- * @deprecated
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided including
- * a domain prefix.
- *
- * @param input
- *	The input string to be parsed. Should have the format XXXX:XX:XX.X
- * @param dev_addr
- *	The PCI Bus-Device-Function address to be returned
- * @return
- *  0 on success, negative on error.
- */
-int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
-
-/**
- * Utility function to write a pci device name, this device name can later be
- * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
- * BDF helpers.
- *
- * @param addr
- *	The PCI Bus-Device-Function address
- * @param output
- *	The output buffer string
- * @param size
- *	The output buffer size
- */
-void rte_pci_device_name(const struct rte_pci_addr *addr, char *output,
-			 size_t size);
-
-/**
- * Utility function to compare two PCI device addresses.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to compare
- * @param addr2
- *	The PCI Bus-Device-Function address to compare
- * @return
- *	0 on equal PCI address.
- *	Positive on addr is greater than addr2.
- *	Negative on addr is less than addr2, or error.
- */
-int rte_pci_addr_cmp(const struct rte_pci_addr *addr,
-		     const struct rte_pci_addr *addr2);
-
-/**
- * @deprecated
- * Utility function to compare two PCI device addresses.
- *
- * @param addr
- *	The PCI Bus-Device-Function address to compare
- * @param addr2
- *	The PCI Bus-Device-Function address to compare
- * @return
- *	0 on equal PCI address.
- *	Positive on addr is greater than addr2.
- *	Negative on addr is less than addr2, or error.
- */
-int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
-			     const struct rte_pci_addr *addr2);
-
-/**
- * Utility function to parse a string into a PCI location.
- *
- * @param str
- *     The string to parse
- * @param addr
- *     The reference to the structure where the location
- *     is stored.
- * @return
- *     0 on success
- *     <0 otherwise
- */
-int rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr);
-
-/**
- * Map the PCI device resources in user space virtual memory address
- *
- * Note that driver should not call this function when flag
- * RTE_PCI_DRV_NEED_MAPPING is set, as EAL will do that for
- * you when it's on.
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- *
- * @return
- *   0 on success, negative on error and positive if no driver
- *   is found for the device.
- */
-int rte_pci_map_device(struct rte_pci_device *dev);
-
-/**
- * Unmap this device
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- */
-void rte_pci_unmap_device(struct rte_pci_device *dev);
-
-/**
- * @internal
- * Map a particular resource from a file.
- *
- * @param requested_addr
- *      The starting address for the new mapping range.
- * @param fd
- *      The file descriptor.
- * @param offset
- *      The offset for the mapping range.
- * @param size
- *      The size for the mapping range.
- * @param additional_flags
- *      The additional flags for the mapping range.
- * @return
- *   - On success, the function returns a pointer to the mapped area.
- *   - On error, the value MAP_FAILED is returned.
- */
-void *pci_map_resource(void *requested_addr, int fd, off_t offset,
-		size_t size, int additional_flags);
-
-/**
- * @internal
- * Unmap a particular resource.
- *
- * @param requested_addr
- *      The address for the unmapping range.
- * @param size
- *      The size for the unmapping range.
- */
-void pci_unmap_resource(void *requested_addr, size_t size);
-
-/**
- * Dump the content of the PCI bus.
- *
- * @param f
- *   A pointer to a file for output
- */
-void rte_pci_dump(FILE *f);
-
-/**
- * Register a PCI driver.
- *
- * @param driver
- *   A pointer to a rte_pci_driver structure describing the driver
- *   to be registered.
- */
-void rte_pci_register(struct rte_pci_driver *driver);
-
-/** Helper for PCI device registration from driver (eth, crypto) instance */
-#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
-RTE_INIT(pciinitfn_ ##nm); \
-static void pciinitfn_ ##nm(void) \
-{\
-	(pci_drv).driver.name = RTE_STR(nm);\
-	rte_pci_register(&pci_drv); \
-} \
-RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
-
-/**
- * Unregister a PCI driver.
- *
- * @param driver
- *   A pointer to a rte_pci_driver structure describing the driver
- *   to be unregistered.
- */
-void rte_pci_unregister(struct rte_pci_driver *driver);
-
-/**
- * Read PCI config space.
- *
- * @param device
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- * @param buf
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into PCI config space
- */
-int rte_pci_read_config(const struct rte_pci_device *device,
-		void *buf, size_t len, off_t offset);
-
-/**
- * Write PCI config space.
- *
- * @param device
- *   A pointer to a rte_pci_device structure describing the device
- *   to use
- * @param buf
- *   A data buffer containing the bytes should be written
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into PCI config space
- */
-int rte_pci_write_config(const struct rte_pci_device *device,
-		const void *buf, size_t len, off_t offset);
-
-/**
- * A structure used to access io resources for a pci device.
- * rte_pci_ioport is arch, os, driver specific, and should not be used outside
- * of pci ioport api.
- */
-struct rte_pci_ioport {
-	struct rte_pci_device *dev;
-	uint64_t base;
-	uint64_t len; /* only filled for memory mapped ports */
-};
-
-/**
- * Initialize a rte_pci_ioport object for a pci device io resource.
- *
- * This object is then used to gain access to those io resources (see below).
- *
- * @param dev
- *   A pointer to a rte_pci_device structure describing the device
- *   to use.
- * @param bar
- *   Index of the io pci resource we want to access.
- * @param p
- *   The rte_pci_ioport object to be initialized.
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p);
-
-/**
- * Release any resources used in a rte_pci_ioport object.
- *
- * @param p
- *   The rte_pci_ioport object to be uninitialized.
- * @return
- *  0 on success, negative on error.
- */
-int rte_pci_ioport_unmap(struct rte_pci_ioport *p);
-
-/**
- * Read from a io pci resource.
- *
- * @param p
- *   The rte_pci_ioport object from which we want to read.
- * @param data
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into the pci io resource.
- */
-void rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset);
-
-/**
- * Write to a io pci resource.
- *
- * @param p
- *   The rte_pci_ioport object to which we want to write.
- * @param data
- *   A data buffer where the bytes should be read into
- * @param len
- *   The length of the data buffer.
- * @param offset
- *   The offset into the pci io resource.
- */
-void rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RTE_PCI_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 965da6e..cbe844c 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -62,9 +62,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
@@ -78,8 +75,6 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_errno.c
@@ -132,9 +127,6 @@ CFLAGS_eal_thread.o := -D_GNU_SOURCE
 CFLAGS_eal_log.o := -D_GNU_SOURCE
 CFLAGS_eal_common_log.o := -D_GNU_SOURCE
 CFLAGS_eal_hugepage_info.o := -D_GNU_SOURCE
-CFLAGS_eal_pci.o := -D_GNU_SOURCE
-CFLAGS_eal_pci_uio.o := -D_GNU_SOURCE
-CFLAGS_eal_pci_vfio.o := -D_GNU_SOURCE
 CFLAGS_eal_common_whitelist.o := -D_GNU_SOURCE
 CFLAGS_eal_common_options.o := -D_GNU_SOURCE
 CFLAGS_eal_common_thread.o := -D_GNU_SOURCE
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 91c3712..017c402 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -71,7 +71,6 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_bus.h>
-#include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_version.h>
diff --git a/lib/librte_eal/linuxapp/eal/eal_interrupts.c b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
index 6df63d4..cdd74ee 100644
--- a/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+++ b/lib/librte_eal/linuxapp/eal/eal_interrupts.c
@@ -60,7 +60,6 @@
 #include <rte_branch_prediction.h>
 #include <rte_debug.h>
 #include <rte_log.h>
-#include <rte_pci.h>
 #include <rte_malloc.h>
 #include <rte_errno.h>
 #include <rte_spinlock.h>
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
deleted file mode 100644
index cee4b94..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ /dev/null
@@ -1,823 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <dirent.h>
-
-#include <rte_log.h>
-#include <rte_bus.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-#include <rte_devargs.h>
-#include <rte_memcpy.h>
-#include <rte_vfio.h>
-
-#include "eal_filesystem.h"
-#include "eal_private.h"
-#include "eal_pci_init.h"
-
-/**
- * @file
- * PCI probing under linux
- *
- * This code is used to simulate a PCI probe by parsing information in sysfs.
- * When a registered device matches a driver, it is then initialized with
- * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
- */
-
-extern struct rte_pci_bus rte_pci_bus;
-
-static int
-pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
-{
-	int count;
-	char path[PATH_MAX];
-	char *name;
-
-	if (!filename || !dri_name)
-		return -1;
-
-	count = readlink(filename, path, PATH_MAX);
-	if (count >= PATH_MAX)
-		return -1;
-
-	/* For device does not have a driver */
-	if (count < 0)
-		return 1;
-
-	path[count] = '\0';
-
-	name = strrchr(path, '/');
-	if (name) {
-		strncpy(dri_name, name + 1, strlen(name + 1) + 1);
-		return 0;
-	}
-
-	return -1;
-}
-
-/* Map pci device */
-int
-rte_pci_map_device(struct rte_pci_device *dev)
-{
-	int ret = -1;
-
-	/* try mapping the NIC resources using VFIO if it exists */
-	switch (dev->kdrv) {
-	case RTE_KDRV_VFIO:
-#ifdef VFIO_PRESENT
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_map_resource(dev);
-#endif
-		break;
-	case RTE_KDRV_IGB_UIO:
-	case RTE_KDRV_UIO_GENERIC:
-		if (rte_eal_using_phys_addrs()) {
-			/* map resources for devices that use uio */
-			ret = pci_uio_map_resource(dev);
-		}
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		ret = 1;
-		break;
-	}
-
-	return ret;
-}
-
-/* Unmap pci device */
-void
-rte_pci_unmap_device(struct rte_pci_device *dev)
-{
-	/* try unmapping the NIC resources using VFIO if it exists */
-	switch (dev->kdrv) {
-	case RTE_KDRV_VFIO:
-#ifdef VFIO_PRESENT
-		if (pci_vfio_is_enabled())
-			pci_vfio_unmap_resource(dev);
-#endif
-		break;
-	case RTE_KDRV_IGB_UIO:
-	case RTE_KDRV_UIO_GENERIC:
-		/* unmap resources for devices that use uio */
-		pci_uio_unmap_resource(dev);
-		break;
-	default:
-		RTE_LOG(DEBUG, EAL,
-			"  Not managed by a supported kernel driver, skipped\n");
-		break;
-	}
-}
-
-void *
-pci_find_max_end_va(void)
-{
-	const struct rte_memseg *seg = rte_eal_get_physmem_layout();
-	const struct rte_memseg *last = seg;
-	unsigned i = 0;
-
-	for (i = 0; i < RTE_MAX_MEMSEG; i++, seg++) {
-		if (seg->addr == NULL)
-			break;
-
-		if (seg->addr > last->addr)
-			last = seg;
-
-	}
-	return RTE_PTR_ADD(last->addr, last->len);
-}
-
-/* parse one line of the "resource" sysfs file (note that the 'line'
- * string is modified)
- */
-int
-pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
-	uint64_t *end_addr, uint64_t *flags)
-{
-	union pci_resource_info {
-		struct {
-			char *phys_addr;
-			char *end_addr;
-			char *flags;
-		};
-		char *ptrs[PCI_RESOURCE_FMT_NVAL];
-	} res_info;
-
-	if (rte_strsplit(line, len, res_info.ptrs, 3, ' ') != 3) {
-		RTE_LOG(ERR, EAL,
-			"%s(): bad resource format\n", __func__);
-		return -1;
-	}
-	errno = 0;
-	*phys_addr = strtoull(res_info.phys_addr, NULL, 16);
-	*end_addr = strtoull(res_info.end_addr, NULL, 16);
-	*flags = strtoull(res_info.flags, NULL, 16);
-	if (errno != 0) {
-		RTE_LOG(ERR, EAL,
-			"%s(): bad resource format\n", __func__);
-		return -1;
-	}
-
-	return 0;
-}
-
-/* parse the "resource" sysfs file */
-static int
-pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
-{
-	FILE *f;
-	char buf[BUFSIZ];
-	int i;
-	uint64_t phys_addr, end_addr, flags;
-
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot open sysfs resource\n");
-		return -1;
-	}
-
-	for (i = 0; i<PCI_MAX_RESOURCE; i++) {
-
-		if (fgets(buf, sizeof(buf), f) == NULL) {
-			RTE_LOG(ERR, EAL,
-				"%s(): cannot read resource\n", __func__);
-			goto error;
-		}
-		if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
-				&end_addr, &flags) < 0)
-			goto error;
-
-		if (flags & IORESOURCE_MEM) {
-			dev->mem_resource[i].phys_addr = phys_addr;
-			dev->mem_resource[i].len = end_addr - phys_addr + 1;
-			/* not mapped for now */
-			dev->mem_resource[i].addr = NULL;
-		}
-	}
-	fclose(f);
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
-}
-
-/* Scan one pci sysfs entry, and fill the devices list from it. */
-static int
-pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
-{
-	char filename[PATH_MAX];
-	unsigned long tmp;
-	struct rte_pci_device *dev;
-	char driver[PATH_MAX];
-	int ret;
-
-	dev = malloc(sizeof(*dev));
-	if (dev == NULL)
-		return -1;
-
-	memset(dev, 0, sizeof(*dev));
-	dev->addr = *addr;
-
-	/* get vendor id */
-	snprintf(filename, sizeof(filename), "%s/vendor", dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.vendor_id = (uint16_t)tmp;
-
-	/* get device id */
-	snprintf(filename, sizeof(filename), "%s/device", dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.device_id = (uint16_t)tmp;
-
-	/* get subsystem_vendor id */
-	snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.subsystem_vendor_id = (uint16_t)tmp;
-
-	/* get subsystem_device id */
-	snprintf(filename, sizeof(filename), "%s/subsystem_device",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	dev->id.subsystem_device_id = (uint16_t)tmp;
-
-	/* get class_id */
-	snprintf(filename, sizeof(filename), "%s/class",
-		 dirname);
-	if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-		free(dev);
-		return -1;
-	}
-	/* the least 24 bits are valid: class, subclass, program interface */
-	dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID;
-
-	/* get max_vfs */
-	dev->max_vfs = 0;
-	snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
-	if (!access(filename, F_OK) &&
-	    eal_parse_sysfs_value(filename, &tmp) == 0)
-		dev->max_vfs = (uint16_t)tmp;
-	else {
-		/* for non igb_uio driver, need kernel version >= 3.8 */
-		snprintf(filename, sizeof(filename),
-			 "%s/sriov_numvfs", dirname);
-		if (!access(filename, F_OK) &&
-		    eal_parse_sysfs_value(filename, &tmp) == 0)
-			dev->max_vfs = (uint16_t)tmp;
-	}
-
-	/* get numa node, default to 0 if not present */
-	snprintf(filename, sizeof(filename), "%s/numa_node",
-		 dirname);
-
-	if (access(filename, F_OK) != -1) {
-		if (eal_parse_sysfs_value(filename, &tmp) == 0)
-			dev->device.numa_node = tmp;
-		else
-			dev->device.numa_node = -1;
-	} else {
-		dev->device.numa_node = 0;
-	}
-
-	pci_name_set(dev);
-
-	/* parse resources */
-	snprintf(filename, sizeof(filename), "%s/resource", dirname);
-	if (pci_parse_sysfs_resource(filename, dev) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse resource\n", __func__);
-		free(dev);
-		return -1;
-	}
-
-	/* parse driver */
-	snprintf(filename, sizeof(filename), "%s/driver", dirname);
-	ret = pci_get_kernel_driver_by_path(filename, driver);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
-		free(dev);
-		return -1;
-	}
-
-	if (!ret) {
-		if (!strcmp(driver, "vfio-pci"))
-			dev->kdrv = RTE_KDRV_VFIO;
-		else if (!strcmp(driver, "igb_uio"))
-			dev->kdrv = RTE_KDRV_IGB_UIO;
-		else if (!strcmp(driver, "uio_pci_generic"))
-			dev->kdrv = RTE_KDRV_UIO_GENERIC;
-		else
-			dev->kdrv = RTE_KDRV_UNKNOWN;
-	} else
-		dev->kdrv = RTE_KDRV_NONE;
-
-	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-		rte_pci_add_device(dev);
-	} else {
-		struct rte_pci_device *dev2;
-		int ret;
-
-		TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-			ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr);
-			if (ret > 0)
-				continue;
-
-			if (ret < 0) {
-				rte_pci_insert_device(dev2, dev);
-			} else { /* already registered */
-				dev2->kdrv = dev->kdrv;
-				dev2->max_vfs = dev->max_vfs;
-				pci_name_set(dev2);
-				memmove(dev2->mem_resource, dev->mem_resource,
-					sizeof(dev->mem_resource));
-				free(dev);
-			}
-			return 0;
-		}
-
-		rte_pci_add_device(dev);
-	}
-
-	return 0;
-}
-
-int
-pci_update_device(const struct rte_pci_addr *addr)
-{
-	char filename[PATH_MAX];
-
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT,
-		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
-		 addr->function);
-
-	return pci_scan_one(filename, addr);
-}
-
-/*
- * split up a pci address into its constituent parts.
- */
-static int
-parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
-{
-	/* first split on ':' */
-	union splitaddr {
-		struct {
-			char *domain;
-			char *bus;
-			char *devid;
-			char *function;
-		};
-		char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */
-	} splitaddr;
-
-	char *buf_copy = strndup(buf, bufsize);
-	if (buf_copy == NULL)
-		return -1;
-
-	if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':')
-			!= PCI_FMT_NVAL - 1)
-		goto error;
-	/* final split is on '.' between devid and function */
-	splitaddr.function = strchr(splitaddr.devid,'.');
-	if (splitaddr.function == NULL)
-		goto error;
-	*splitaddr.function++ = '\0';
-
-	/* now convert to int values */
-	errno = 0;
-	addr->domain = strtoul(splitaddr.domain, NULL, 16);
-	addr->bus = strtoul(splitaddr.bus, NULL, 16);
-	addr->devid = strtoul(splitaddr.devid, NULL, 16);
-	addr->function = strtoul(splitaddr.function, NULL, 10);
-	if (errno != 0)
-		goto error;
-
-	free(buf_copy); /* free the copy made with strdup */
-	return 0;
-error:
-	free(buf_copy);
-	return -1;
-}
-
-/*
- * Scan the content of the PCI bus, and the devices in the devices
- * list
- */
-int
-rte_pci_scan(void)
-{
-	struct dirent *e;
-	DIR *dir;
-	char dirname[PATH_MAX];
-	struct rte_pci_addr addr;
-
-	/* for debug purposes, PCI can be disabled */
-	if (!rte_eal_has_pci())
-		return 0;
-
-#ifdef VFIO_PRESENT
-	if (!pci_vfio_is_enabled())
-		RTE_LOG(DEBUG, EAL, "VFIO PCI modules not loaded\n");
-#endif
-
-	dir = opendir(pci_get_sysfs_path());
-	if (dir == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
-			__func__, strerror(errno));
-		return -1;
-	}
-
-	while ((e = readdir(dir)) != NULL) {
-		if (e->d_name[0] == '.')
-			continue;
-
-		if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
-			continue;
-
-		snprintf(dirname, sizeof(dirname), "%s/%s",
-				pci_get_sysfs_path(), e->d_name);
-
-		if (pci_scan_one(dirname, &addr) < 0)
-			goto error;
-	}
-	closedir(dir);
-	return 0;
-
-error:
-	closedir(dir);
-	return -1;
-}
-
-/*
- * Is pci device bound to any kdrv
- */
-static inline int
-pci_one_device_is_bound(void)
-{
-	struct rte_pci_device *dev = NULL;
-	int ret = 0;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (dev->kdrv == RTE_KDRV_UNKNOWN ||
-		    dev->kdrv == RTE_KDRV_NONE) {
-			continue;
-		} else {
-			ret = 1;
-			break;
-		}
-	}
-	return ret;
-}
-
-/*
- * Any one of the device bound to uio
- */
-static inline int
-pci_one_device_bound_uio(void)
-{
-	struct rte_pci_device *dev = NULL;
-
-	FOREACH_DEVICE_ON_PCIBUS(dev) {
-		if (dev->kdrv == RTE_KDRV_IGB_UIO ||
-		   dev->kdrv == RTE_KDRV_UIO_GENERIC) {
-			return 1;
-		}
-	}
-	return 0;
-}
-
-/*
- * Any one of the device has iova as va
- */
-static inline int
-pci_one_device_has_iova_va(void)
-{
-	struct rte_pci_device *dev = NULL;
-	struct rte_pci_driver *drv = NULL;
-
-	FOREACH_DRIVER_ON_PCIBUS(drv) {
-		if (drv && drv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) {
-			FOREACH_DEVICE_ON_PCIBUS(dev) {
-				if (dev->kdrv == RTE_KDRV_VFIO &&
-				    rte_pci_match(drv, dev))
-					return 1;
-			}
-		}
-	}
-	return 0;
-}
-
-/*
- * Get iommu class of PCI devices on the bus.
- */
-enum rte_iova_mode
-rte_pci_get_iommu_class(void)
-{
-	bool is_bound;
-	bool is_vfio_noiommu_enabled = true;
-	bool has_iova_va;
-	bool is_bound_uio;
-
-	is_bound = pci_one_device_is_bound();
-	if (!is_bound)
-		return RTE_IOVA_DC;
-
-	has_iova_va = pci_one_device_has_iova_va();
-	is_bound_uio = pci_one_device_bound_uio();
-#ifdef VFIO_PRESENT
-	is_vfio_noiommu_enabled = vfio_noiommu_is_enabled() == true ?
-					true : false;
-#endif
-
-	if (has_iova_va && !is_bound_uio && !is_vfio_noiommu_enabled)
-		return RTE_IOVA_VA;
-
-	if (has_iova_va) {
-		RTE_LOG(WARNING, EAL, "Some devices want iova as va but pa will be used because.. ");
-		if (is_vfio_noiommu_enabled)
-			RTE_LOG(WARNING, EAL, "vfio-noiommu mode configured\n");
-		if (is_bound_uio)
-			RTE_LOG(WARNING, EAL, "few device bound to UIO\n");
-	}
-
-	return RTE_IOVA_PA;
-}
-
-/* Read PCI config space. */
-int rte_pci_read_config(const struct rte_pci_device *device,
-		void *buf, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &device->intr_handle;
-
-	switch (intr_handle->type) {
-	case RTE_INTR_HANDLE_UIO:
-	case RTE_INTR_HANDLE_UIO_INTX:
-		return pci_uio_read_config(intr_handle, buf, len, offset);
-
-#ifdef VFIO_PRESENT
-	case RTE_INTR_HANDLE_VFIO_MSIX:
-	case RTE_INTR_HANDLE_VFIO_MSI:
-	case RTE_INTR_HANDLE_VFIO_LEGACY:
-		return pci_vfio_read_config(intr_handle, buf, len, offset);
-#endif
-	default:
-		RTE_LOG(ERR, EAL,
-			"Unknown handle type of fd %d\n",
-					intr_handle->fd);
-		return -1;
-	}
-}
-
-/* Write PCI config space. */
-int rte_pci_write_config(const struct rte_pci_device *device,
-		const void *buf, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &device->intr_handle;
-
-	switch (intr_handle->type) {
-	case RTE_INTR_HANDLE_UIO:
-	case RTE_INTR_HANDLE_UIO_INTX:
-		return pci_uio_write_config(intr_handle, buf, len, offset);
-
-#ifdef VFIO_PRESENT
-	case RTE_INTR_HANDLE_VFIO_MSIX:
-	case RTE_INTR_HANDLE_VFIO_MSI:
-	case RTE_INTR_HANDLE_VFIO_LEGACY:
-		return pci_vfio_write_config(intr_handle, buf, len, offset);
-#endif
-	default:
-		RTE_LOG(ERR, EAL,
-			"Unknown handle type of fd %d\n",
-					intr_handle->fd);
-		return -1;
-	}
-}
-
-#if defined(RTE_ARCH_X86)
-static int
-pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
-		struct rte_pci_ioport *p)
-{
-	uint16_t start, end;
-	FILE *fp;
-	char *line = NULL;
-	char pci_id[16];
-	int found = 0;
-	size_t linesz;
-
-	snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
-		 dev->addr.domain, dev->addr.bus,
-		 dev->addr.devid, dev->addr.function);
-
-	fp = fopen("/proc/ioports", "r");
-	if (fp == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): can't open ioports\n", __func__);
-		return -1;
-	}
-
-	while (getdelim(&line, &linesz, '\n', fp) > 0) {
-		char *ptr = line;
-		char *left;
-		int n;
-
-		n = strcspn(ptr, ":");
-		ptr[n] = 0;
-		left = &ptr[n + 1];
-
-		while (*left && isspace(*left))
-			left++;
-
-		if (!strncmp(left, pci_id, strlen(pci_id))) {
-			found = 1;
-
-			while (*ptr && isspace(*ptr))
-				ptr++;
-
-			sscanf(ptr, "%04hx-%04hx", &start, &end);
-
-			break;
-		}
-	}
-
-	free(line);
-	fclose(fp);
-
-	if (!found)
-		return -1;
-
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	p->base = start;
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%x\n", start);
-
-	return 0;
-}
-#endif
-
-int
-rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
-		struct rte_pci_ioport *p)
-{
-	int ret = -1;
-
-	switch (dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_ioport_map(dev, bar, p);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		ret = pci_uio_ioport_map(dev, bar, p);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-#if defined(RTE_ARCH_X86)
-		ret = pci_ioport_map(dev, bar, p);
-#else
-		ret = pci_uio_ioport_map(dev, bar, p);
-#endif
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		ret = pci_ioport_map(dev, bar, p);
-#endif
-		break;
-	default:
-		break;
-	}
-
-	if (!ret)
-		p->dev = dev;
-
-	return ret;
-}
-
-void
-rte_pci_ioport_read(struct rte_pci_ioport *p,
-		void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		pci_vfio_ioport_read(p, data, len, offset);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-		pci_uio_ioport_read(p, data, len, offset);
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		pci_uio_ioport_read(p, data, len, offset);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-void
-rte_pci_ioport_write(struct rte_pci_ioport *p,
-		const void *data, size_t len, off_t offset)
-{
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		pci_vfio_ioport_write(p, data, len, offset);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-		pci_uio_ioport_write(p, data, len, offset);
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		pci_uio_ioport_write(p, data, len, offset);
-#endif
-		break;
-	default:
-		break;
-	}
-}
-
-int
-rte_pci_ioport_unmap(struct rte_pci_ioport *p)
-{
-	int ret = -1;
-
-	switch (p->dev->kdrv) {
-#ifdef VFIO_PRESENT
-	case RTE_KDRV_VFIO:
-		if (pci_vfio_is_enabled())
-			ret = pci_vfio_ioport_unmap(p);
-		break;
-#endif
-	case RTE_KDRV_IGB_UIO:
-		ret = pci_uio_ioport_unmap(p);
-		break;
-	case RTE_KDRV_UIO_GENERIC:
-#if defined(RTE_ARCH_X86)
-		ret = 0;
-#else
-		ret = pci_uio_ioport_unmap(p);
-#endif
-		break;
-	case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-		ret = 0;
-#endif
-		break;
-	default:
-		break;
-	}
-
-	return ret;
-}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/eal_pci_init.h
deleted file mode 100644
index 99d7a2e..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_init.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef EAL_PCI_INIT_H_
-#define EAL_PCI_INIT_H_
-
-#include <linux/version.h>
-
-#include <rte_vfio.h>
-
-/** IO resource type: */
-#define IORESOURCE_IO         0x00000100
-#define IORESOURCE_MEM        0x00000200
-
-/*
- * Helper function to map PCI resources right after hugepages in virtual memory
- */
-extern void *pci_map_addr;
-void *pci_find_max_end_va(void);
-
-/* parse one line of the "resource" sysfs file (note that the 'line'
- * string is modified)
- */
-int pci_parse_one_sysfs_resource(char *line, size_t len, uint64_t *phys_addr,
-	uint64_t *end_addr, uint64_t *flags);
-
-int pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res);
-void pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res);
-int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx);
-
-int pci_uio_read_config(const struct rte_intr_handle *intr_handle,
-			void *buf, size_t len, off_t offs);
-int pci_uio_write_config(const struct rte_intr_handle *intr_handle,
-			 const void *buf, size_t len, off_t offs);
-
-int pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		       struct rte_pci_ioport *p);
-void pci_uio_ioport_read(struct rte_pci_ioport *p,
-			 void *data, size_t len, off_t offset);
-void pci_uio_ioport_write(struct rte_pci_ioport *p,
-			  const void *data, size_t len, off_t offset);
-int pci_uio_ioport_unmap(struct rte_pci_ioport *p);
-
-#ifdef RTE_EAL_VFIO
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
-#define RTE_PCI_MSIX_TABLE_BIR    0x7
-#define RTE_PCI_MSIX_TABLE_OFFSET 0xfffffff8
-#define RTE_PCI_MSIX_FLAGS_QSIZE  0x07ff
-#else
-#define RTE_PCI_MSIX_TABLE_BIR    PCI_MSIX_TABLE_BIR
-#define RTE_PCI_MSIX_TABLE_OFFSET PCI_MSIX_TABLE_OFFSET
-#define RTE_PCI_MSIX_FLAGS_QSIZE  PCI_MSIX_FLAGS_QSIZE
-#endif
-
-/* access config space */
-int pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
-			 void *buf, size_t len, off_t offs);
-int pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
-			  const void *buf, size_t len, off_t offs);
-
-int pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
-		        struct rte_pci_ioport *p);
-void pci_vfio_ioport_read(struct rte_pci_ioport *p,
-			  void *data, size_t len, off_t offset);
-void pci_vfio_ioport_write(struct rte_pci_ioport *p,
-			   const void *data, size_t len, off_t offset);
-int pci_vfio_ioport_unmap(struct rte_pci_ioport *p);
-
-/* map/unmap VFIO resource prototype */
-int pci_vfio_map_resource(struct rte_pci_device *dev);
-int pci_vfio_unmap_resource(struct rte_pci_device *dev);
-
-int pci_vfio_is_enabled(void);
-
-#endif
-
-#endif /* EAL_PCI_INIT_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
deleted file mode 100644
index d17837a..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/sysmacros.h>
-#include <linux/pci_regs.h>
-
-#if defined(RTE_ARCH_X86)
-#include <sys/io.h>
-#endif
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-
-void *pci_map_addr = NULL;
-
-#define OFF_MAX              ((uint64_t)(off_t)-1)
-
-int
-pci_uio_read_config(const struct rte_intr_handle *intr_handle,
-		    void *buf, size_t len, off_t offset)
-{
-	return pread(intr_handle->uio_cfg_fd, buf, len, offset);
-}
-
-int
-pci_uio_write_config(const struct rte_intr_handle *intr_handle,
-		     const void *buf, size_t len, off_t offset)
-{
-	return pwrite(intr_handle->uio_cfg_fd, buf, len, offset);
-}
-
-static int
-pci_uio_set_bus_master(int dev_fd)
-{
-	uint16_t reg;
-	int ret;
-
-	ret = pread(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL,
-			"Cannot read command from PCI config space!\n");
-		return -1;
-	}
-
-	/* return if bus mastering is already on */
-	if (reg & PCI_COMMAND_MASTER)
-		return 0;
-
-	reg |= PCI_COMMAND_MASTER;
-
-	ret = pwrite(dev_fd, &reg, sizeof(reg), PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL,
-			"Cannot write command to PCI config space!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-static int
-pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
-{
-	FILE *f;
-	char filename[PATH_MAX];
-	int ret;
-	unsigned major, minor;
-	dev_t dev;
-
-	/* get the name of the sysfs file that contains the major and minor
-	 * of the uio device and read its content */
-	snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path);
-
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n",
-			__func__);
-		return -1;
-	}
-
-	ret = fscanf(f, "%u:%u", &major, &minor);
-	if (ret != 2) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n",
-			__func__);
-		fclose(f);
-		return -1;
-	}
-	fclose(f);
-
-	/* create the char device "mknod /dev/uioX c major minor" */
-	snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
-	dev = makedev(major, minor);
-	ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
-	if (ret != 0) {
-		RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
-			__func__, strerror(errno));
-		return -1;
-	}
-
-	return ret;
-}
-
-/*
- * Return the uioX char device used for a pci device. On success, return
- * the UIO number and fill dstbuf string with the path of the device in
- * sysfs. On error, return a negative value. In this case dstbuf is
- * invalid.
- */
-static int
-pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf,
-			   unsigned int buflen, int create)
-{
-	struct rte_pci_addr *loc = &dev->addr;
-	int uio_num = -1;
-	struct dirent *e;
-	DIR *dir;
-	char dirname[PATH_MAX];
-
-	/* depending on kernel version, uio can be located in uio/uioX
-	 * or uio:uioX */
-
-	snprintf(dirname, sizeof(dirname),
-			"%s/" PCI_PRI_FMT "/uio", pci_get_sysfs_path(),
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	dir = opendir(dirname);
-	if (dir == NULL) {
-		/* retry with the parent directory */
-		snprintf(dirname, sizeof(dirname),
-				"%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
-				loc->domain, loc->bus, loc->devid, loc->function);
-		dir = opendir(dirname);
-
-		if (dir == NULL) {
-			RTE_LOG(ERR, EAL, "Cannot opendir %s\n", dirname);
-			return -1;
-		}
-	}
-
-	/* take the first file starting with "uio" */
-	while ((e = readdir(dir)) != NULL) {
-		/* format could be uio%d ...*/
-		int shortprefix_len = sizeof("uio") - 1;
-		/* ... or uio:uio%d */
-		int longprefix_len = sizeof("uio:uio") - 1;
-		char *endptr;
-
-		if (strncmp(e->d_name, "uio", 3) != 0)
-			continue;
-
-		/* first try uio%d */
-		errno = 0;
-		uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
-		if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
-			snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
-			break;
-		}
-
-		/* then try uio:uio%d */
-		errno = 0;
-		uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
-		if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
-			snprintf(dstbuf, buflen, "%s/uio:uio%u", dirname, uio_num);
-			break;
-		}
-	}
-	closedir(dir);
-
-	/* No uio resource found */
-	if (e == NULL)
-		return -1;
-
-	/* create uio device if we've been asked to */
-	if (rte_eal_create_uio_dev() && create &&
-			pci_mknod_uio_dev(dstbuf, uio_num) < 0)
-		RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num);
-
-	return uio_num;
-}
-
-void
-pci_uio_free_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource *uio_res)
-{
-	rte_free(uio_res);
-
-	if (dev->intr_handle.uio_cfg_fd >= 0) {
-		close(dev->intr_handle.uio_cfg_fd);
-		dev->intr_handle.uio_cfg_fd = -1;
-	}
-	if (dev->intr_handle.fd >= 0) {
-		close(dev->intr_handle.fd);
-		dev->intr_handle.fd = -1;
-		dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-	}
-}
-
-int
-pci_uio_alloc_resource(struct rte_pci_device *dev,
-		struct mapped_pci_resource **uio_res)
-{
-	char dirname[PATH_MAX];
-	char cfgname[PATH_MAX];
-	char devname[PATH_MAX]; /* contains the /dev/uioX */
-	int uio_num;
-	struct rte_pci_addr *loc;
-
-	loc = &dev->addr;
-
-	/* find uio resource */
-	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 1);
-	if (uio_num < 0) {
-		RTE_LOG(WARNING, EAL, "  "PCI_PRI_FMT" not managed by UIO driver, "
-				"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
-		return 1;
-	}
-	snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
-
-	/* save fd if in primary process */
-	dev->intr_handle.fd = open(devname, O_RDWR);
-	if (dev->intr_handle.fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			devname, strerror(errno));
-		goto error;
-	}
-
-	snprintf(cfgname, sizeof(cfgname),
-			"/sys/class/uio/uio%u/device/config", uio_num);
-	dev->intr_handle.uio_cfg_fd = open(cfgname, O_RDWR);
-	if (dev->intr_handle.uio_cfg_fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-			cfgname, strerror(errno));
-		goto error;
-	}
-
-	if (dev->kdrv == RTE_KDRV_IGB_UIO)
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-	else {
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
-
-		/* set bus master that is not done by uio_pci_generic */
-		if (pci_uio_set_bus_master(dev->intr_handle.uio_cfg_fd)) {
-			RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
-			goto error;
-		}
-	}
-
-	/* allocate the mapping details for secondary processes*/
-	*uio_res = rte_zmalloc("UIO_RES", sizeof(**uio_res), 0);
-	if (*uio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto error;
-	}
-
-	snprintf((*uio_res)->path, sizeof((*uio_res)->path), "%s", devname);
-	memcpy(&(*uio_res)->pci_addr, &dev->addr, sizeof((*uio_res)->pci_addr));
-
-	return 0;
-
-error:
-	pci_uio_free_resource(dev, *uio_res);
-	return -1;
-}
-
-int
-pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
-		struct mapped_pci_resource *uio_res, int map_idx)
-{
-	int fd;
-	char devname[PATH_MAX];
-	void *mapaddr;
-	struct rte_pci_addr *loc;
-	struct pci_map *maps;
-
-	loc = &dev->addr;
-	maps = uio_res->maps;
-
-	/* update devname for mmap  */
-	snprintf(devname, sizeof(devname),
-			"%s/" PCI_PRI_FMT "/resource%d",
-			pci_get_sysfs_path(),
-			loc->domain, loc->bus, loc->devid,
-			loc->function, res_idx);
-
-	/* allocate memory to keep path */
-	maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
-	if (maps[map_idx].path == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
-				strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * open resource file, to mmap it
-	 */
-	fd = open(devname, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				devname, strerror(errno));
-		goto error;
-	}
-
-	/* try mapping somewhere close to the end of hugepages */
-	if (pci_map_addr == NULL)
-		pci_map_addr = pci_find_max_end_va();
-
-	mapaddr = pci_map_resource(pci_map_addr, fd, 0,
-			(size_t)dev->mem_resource[res_idx].len, 0);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		goto error;
-
-	pci_map_addr = RTE_PTR_ADD(mapaddr,
-			(size_t)dev->mem_resource[res_idx].len);
-
-	maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
-	maps[map_idx].size = dev->mem_resource[res_idx].len;
-	maps[map_idx].addr = mapaddr;
-	maps[map_idx].offset = 0;
-	strcpy(maps[map_idx].path, devname);
-	dev->mem_resource[res_idx].addr = mapaddr;
-
-	return 0;
-
-error:
-	rte_free(maps[map_idx].path);
-	return -1;
-}
-
-#if defined(RTE_ARCH_X86)
-int
-pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		   struct rte_pci_ioport *p)
-{
-	char dirname[PATH_MAX];
-	char filename[PATH_MAX];
-	int uio_num;
-	unsigned long start;
-
-	uio_num = pci_get_uio_dev(dev, dirname, sizeof(dirname), 0);
-	if (uio_num < 0)
-		return -1;
-
-	/* get portio start */
-	snprintf(filename, sizeof(filename),
-		 "%s/portio/port%d/start", dirname, bar);
-	if (eal_parse_sysfs_value(filename, &start) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
-			__func__);
-		return -1;
-	}
-	/* ensure we don't get anything funny here, read/write will cast to
-	 * uin16_t */
-	if (start > UINT16_MAX)
-		return -1;
-
-	/* FIXME only for primary process ? */
-	if (dev->intr_handle.type == RTE_INTR_HANDLE_UNKNOWN) {
-
-		snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
-		dev->intr_handle.fd = open(filename, O_RDWR);
-		if (dev->intr_handle.fd < 0) {
-			RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
-				filename, strerror(errno));
-			return -1;
-		}
-		dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
-	}
-
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx\n", start);
-
-	p->base = start;
-	p->len = 0;
-	return 0;
-}
-#else
-int
-pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
-		   struct rte_pci_ioport *p)
-{
-	FILE *f;
-	char buf[BUFSIZ];
-	char filename[PATH_MAX];
-	uint64_t phys_addr, end_addr, flags;
-	int fd, i;
-	void *addr;
-
-	/* open and read addresses of the corresponding resource in sysfs */
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
-		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
-		dev->addr.devid, dev->addr.function);
-	f = fopen(filename, "r");
-	if (f == NULL) {
-		RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s\n",
-			strerror(errno));
-		return -1;
-	}
-	for (i = 0; i < bar + 1; i++) {
-		if (fgets(buf, sizeof(buf), f) == NULL) {
-			RTE_LOG(ERR, EAL, "Cannot read sysfs resource\n");
-			goto error;
-		}
-	}
-	if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
-			&end_addr, &flags) < 0)
-		goto error;
-	if ((flags & IORESOURCE_IO) == 0) {
-		RTE_LOG(ERR, EAL, "BAR %d is not an IO resource\n", bar);
-		goto error;
-	}
-	snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
-		pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
-		dev->addr.devid, dev->addr.function, bar);
-
-	/* mmap the pci resource */
-	fd = open(filename, O_RDWR);
-	if (fd < 0) {
-		RTE_LOG(ERR, EAL, "Cannot open %s: %s\n", filename,
-			strerror(errno));
-		goto error;
-	}
-	addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
-		MAP_SHARED, fd, 0);
-	close(fd);
-	if (addr == MAP_FAILED) {
-		RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s\n",
-			strerror(errno));
-		goto error;
-	}
-
-	/* strangely, the base address is mmap addr + phys_addr */
-	p->base = (uintptr_t)addr + phys_addr;
-	p->len = end_addr + 1;
-	RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"\n", p->base);
-	fclose(f);
-
-	return 0;
-
-error:
-	fclose(f);
-	return -1;
-}
-#endif
-
-void
-pci_uio_ioport_read(struct rte_pci_ioport *p,
-		    void *data, size_t len, off_t offset)
-{
-	uint8_t *d;
-	int size;
-	uintptr_t reg = p->base + offset;
-
-	for (d = data; len > 0; d += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-#if defined(RTE_ARCH_X86)
-			*(uint32_t *)d = inl(reg);
-#else
-			*(uint32_t *)d = *(volatile uint32_t *)reg;
-#endif
-		} else if (len >= 2) {
-			size = 2;
-#if defined(RTE_ARCH_X86)
-			*(uint16_t *)d = inw(reg);
-#else
-			*(uint16_t *)d = *(volatile uint16_t *)reg;
-#endif
-		} else {
-			size = 1;
-#if defined(RTE_ARCH_X86)
-			*d = inb(reg);
-#else
-			*d = *(volatile uint8_t *)reg;
-#endif
-		}
-	}
-}
-
-void
-pci_uio_ioport_write(struct rte_pci_ioport *p,
-		     const void *data, size_t len, off_t offset)
-{
-	const uint8_t *s;
-	int size;
-	uintptr_t reg = p->base + offset;
-
-	for (s = data; len > 0; s += size, reg += size, len -= size) {
-		if (len >= 4) {
-			size = 4;
-#if defined(RTE_ARCH_X86)
-			outl_p(*(const uint32_t *)s, reg);
-#else
-			*(volatile uint32_t *)reg = *(const uint32_t *)s;
-#endif
-		} else if (len >= 2) {
-			size = 2;
-#if defined(RTE_ARCH_X86)
-			outw_p(*(const uint16_t *)s, reg);
-#else
-			*(volatile uint16_t *)reg = *(const uint16_t *)s;
-#endif
-		} else {
-			size = 1;
-#if defined(RTE_ARCH_X86)
-			outb_p(*s, reg);
-#else
-			*(volatile uint8_t *)reg = *s;
-#endif
-		}
-	}
-}
-
-int
-pci_uio_ioport_unmap(struct rte_pci_ioport *p)
-{
-#if defined(RTE_ARCH_X86)
-	RTE_SET_USED(p);
-	/* FIXME close intr fd ? */
-	return 0;
-#else
-	return munmap((void *)(uintptr_t)p->base, p->len);
-#endif
-}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
deleted file mode 100644
index 7006a1d..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ /dev/null
@@ -1,754 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <fcntl.h>
-#include <linux/pci_regs.h>
-#include <sys/eventfd.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <stdbool.h>
-
-#include <rte_log.h>
-#include <rte_pci.h>
-#include <rte_eal_memconfig.h>
-#include <rte_malloc.h>
-#include <rte_vfio.h>
-
-#include "eal_filesystem.h"
-#include "eal_pci_init.h"
-#include "eal_private.h"
-
-/**
- * @file
- * PCI probing under linux (VFIO version)
- *
- * This code tries to determine if the PCI device is bound to VFIO driver,
- * and initialize it (map BARs, set up interrupts) if that's the case.
- *
- * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y".
- */
-
-#ifdef RTE_EAL_VFIO
-
-#define PAGE_SIZE   (sysconf(_SC_PAGESIZE))
-#define PAGE_MASK   (~(PAGE_SIZE - 1))
-
-static struct rte_tailq_elem rte_vfio_tailq = {
-	.name = "VFIO_RESOURCE_LIST",
-};
-EAL_REGISTER_TAILQ(rte_vfio_tailq)
-
-int
-pci_vfio_read_config(const struct rte_intr_handle *intr_handle,
-		    void *buf, size_t len, off_t offs)
-{
-	return pread64(intr_handle->vfio_dev_fd, buf, len,
-	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
-}
-
-int
-pci_vfio_write_config(const struct rte_intr_handle *intr_handle,
-		    const void *buf, size_t len, off_t offs)
-{
-	return pwrite64(intr_handle->vfio_dev_fd, buf, len,
-	       VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs);
-}
-
-/* get PCI BAR number where MSI-X interrupts are */
-static int
-pci_vfio_get_msix_bar(int fd, struct pci_msix_table *msix_table)
-{
-	int ret;
-	uint32_t reg;
-	uint16_t flags;
-	uint8_t cap_id, cap_offset;
-
-	/* read PCI capability pointer from config space */
-	ret = pread64(fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_CAPABILITY_LIST);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
-				"config space!\n");
-		return -1;
-	}
-
-	/* we need first byte */
-	cap_offset = reg & 0xFF;
-
-	while (cap_offset) {
-
-		/* read PCI capability ID */
-		ret = pread64(fd, &reg, sizeof(reg),
-				VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-				cap_offset);
-		if (ret != sizeof(reg)) {
-			RTE_LOG(ERR, EAL, "Cannot read capability ID from PCI "
-					"config space!\n");
-			return -1;
-		}
-
-		/* we need first byte */
-		cap_id = reg & 0xFF;
-
-		/* if we haven't reached MSI-X, check next capability */
-		if (cap_id != PCI_CAP_ID_MSIX) {
-			ret = pread64(fd, &reg, sizeof(reg),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset);
-			if (ret != sizeof(reg)) {
-				RTE_LOG(ERR, EAL, "Cannot read capability pointer from PCI "
-						"config space!\n");
-				return -1;
-			}
-
-			/* we need second byte */
-			cap_offset = (reg & 0xFF00) >> 8;
-
-			continue;
-		}
-		/* else, read table offset */
-		else {
-			/* table offset resides in the next 4 bytes */
-			ret = pread64(fd, &reg, sizeof(reg),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset + 4);
-			if (ret != sizeof(reg)) {
-				RTE_LOG(ERR, EAL, "Cannot read table offset from PCI config "
-						"space!\n");
-				return -1;
-			}
-
-			ret = pread64(fd, &flags, sizeof(flags),
-					VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-					cap_offset + 2);
-			if (ret != sizeof(flags)) {
-				RTE_LOG(ERR, EAL, "Cannot read table flags from PCI config "
-						"space!\n");
-				return -1;
-			}
-
-			msix_table->bar_index = reg & RTE_PCI_MSIX_TABLE_BIR;
-			msix_table->offset = reg & RTE_PCI_MSIX_TABLE_OFFSET;
-			msix_table->size =
-				16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE));
-
-			return 0;
-		}
-	}
-	return 0;
-}
-
-/* set PCI bus mastering */
-static int
-pci_vfio_set_bus_master(int dev_fd, bool op)
-{
-	uint16_t reg;
-	int ret;
-
-	ret = pread64(dev_fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_COMMAND);
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot read command from PCI config space!\n");
-		return -1;
-	}
-
-	if (op)
-		/* set the master bit */
-		reg |= PCI_COMMAND_MASTER;
-	else
-		reg &= ~(PCI_COMMAND_MASTER);
-
-	ret = pwrite64(dev_fd, &reg, sizeof(reg),
-			VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) +
-			PCI_COMMAND);
-
-	if (ret != sizeof(reg)) {
-		RTE_LOG(ERR, EAL, "Cannot write command to PCI config space!\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-/* set up interrupt support (but not enable interrupts) */
-static int
-pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
-{
-	int i, ret, intr_idx;
-	enum rte_intr_mode intr_mode;
-
-	/* default to invalid index */
-	intr_idx = VFIO_PCI_NUM_IRQS;
-
-	/* Get default / configured intr_mode */
-	intr_mode = rte_eal_vfio_intr_mode();
-
-	/* get interrupt type from internal config (MSI-X by default, can be
-	 * overridden from the command line
-	 */
-	switch (intr_mode) {
-	case RTE_INTR_MODE_MSIX:
-		intr_idx = VFIO_PCI_MSIX_IRQ_INDEX;
-		break;
-	case RTE_INTR_MODE_MSI:
-		intr_idx = VFIO_PCI_MSI_IRQ_INDEX;
-		break;
-	case RTE_INTR_MODE_LEGACY:
-		intr_idx = VFIO_PCI_INTX_IRQ_INDEX;
-		break;
-	/* don't do anything if we want to automatically determine interrupt type */
-	case RTE_INTR_MODE_NONE:
-		break;
-	default:
-		RTE_LOG(ERR, EAL, "  unknown default interrupt type!\n");
-		return -1;
-	}
-
-	/* start from MSI-X interrupt type */
-	for (i = VFIO_PCI_MSIX_IRQ_INDEX; i >= 0; i--) {
-		struct vfio_irq_info irq = { .argsz = sizeof(irq) };
-		int fd = -1;
-
-		/* skip interrupt modes we don't want */
-		if (intr_mode != RTE_INTR_MODE_NONE &&
-				i != intr_idx)
-			continue;
-
-		irq.index = i;
-
-		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  cannot get IRQ info, "
-					"error %i (%s)\n", errno, strerror(errno));
-			return -1;
-		}
-
-		/* if this vector cannot be used with eventfd, fail if we explicitly
-		 * specified interrupt type, otherwise continue */
-		if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
-			if (intr_mode != RTE_INTR_MODE_NONE) {
-				RTE_LOG(ERR, EAL,
-						"  interrupt vector does not support eventfd!\n");
-				return -1;
-			} else
-				continue;
-		}
-
-		/* set up an eventfd for interrupts */
-		fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
-		if (fd < 0) {
-			RTE_LOG(ERR, EAL, "  cannot set up eventfd, "
-					"error %i (%s)\n", errno, strerror(errno));
-			return -1;
-		}
-
-		dev->intr_handle.fd = fd;
-		dev->intr_handle.vfio_dev_fd = vfio_dev_fd;
-
-		switch (i) {
-		case VFIO_PCI_MSIX_IRQ_INDEX:
-			intr_mode = RTE_INTR_MODE_MSIX;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
-			break;
-		case VFIO_PCI_MSI_IRQ_INDEX:
-			intr_mode = RTE_INTR_MODE_MSI;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_MSI;
-			break;
-		case VFIO_PCI_INTX_IRQ_INDEX:
-			intr_mode = RTE_INTR_MODE_LEGACY;
-			dev->intr_handle.type = RTE_INTR_HANDLE_VFIO_LEGACY;
-			break;
-		default:
-			RTE_LOG(ERR, EAL, "  unknown interrupt type!\n");
-			return -1;
-		}
-
-		return 0;
-	}
-
-	/* if we're here, we haven't found a suitable interrupt vector */
-	return -1;
-}
-
-static int
-pci_vfio_is_ioport_bar(int vfio_dev_fd, int bar_index)
-{
-	uint32_t ioport_bar;
-	int ret;
-
-	ret = pread64(vfio_dev_fd, &ioport_bar, sizeof(ioport_bar),
-			  VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX)
-			  + PCI_BASE_ADDRESS_0 + bar_index*4);
-	if (ret != sizeof(ioport_bar)) {
-		RTE_LOG(ERR, EAL, "Cannot read command (%x) from config space!\n",
-			PCI_BASE_ADDRESS_0 + bar_index*4);
-		return -1;
-	}
-
-	return (ioport_bar & PCI_BASE_ADDRESS_SPACE_IO) != 0;
-}
-
-static int
-pci_vfio_setup_device(struct rte_pci_device *dev, int vfio_dev_fd)
-{
-	if (pci_vfio_setup_interrupts(dev, vfio_dev_fd) != 0) {
-		RTE_LOG(ERR, EAL, "Error setting up interrupts!\n");
-		return -1;
-	}
-
-	/* set bus mastering for the device */
-	if (pci_vfio_set_bus_master(vfio_dev_fd, true)) {
-		RTE_LOG(ERR, EAL, "Cannot set up bus mastering!\n");
-		return -1;
-	}
-
-	/* Reset the device */
-	ioctl(vfio_dev_fd, VFIO_DEVICE_RESET);
-
-	return 0;
-}
-
-static int
-pci_vfio_mmap_bar(int vfio_dev_fd, struct mapped_pci_resource *vfio_res,
-		int bar_index, int additional_flags)
-{
-	struct memreg {
-		unsigned long offset, size;
-	} memreg[2] = {};
-	void *bar_addr;
-	struct pci_msix_table *msix_table = &vfio_res->msix_table;
-	struct pci_map *bar = &vfio_res->maps[bar_index];
-
-	if (bar->size == 0)
-		/* Skip this BAR */
-		return 0;
-
-	if (msix_table->bar_index == bar_index) {
-		/*
-		 * VFIO will not let us map the MSI-X table,
-		 * but we can map around it.
-		 */
-		uint32_t table_start = msix_table->offset;
-		uint32_t table_end = table_start + msix_table->size;
-		table_end = (table_end + ~PAGE_MASK) & PAGE_MASK;
-		table_start &= PAGE_MASK;
-
-		if (table_start == 0 && table_end >= bar->size) {
-			/* Cannot map this BAR */
-			RTE_LOG(DEBUG, EAL, "Skipping BAR%d\n", bar_index);
-			bar->size = 0;
-			bar->addr = 0;
-			return 0;
-		}
-
-		memreg[0].offset = bar->offset;
-		memreg[0].size = table_start;
-		memreg[1].offset = bar->offset + table_end;
-		memreg[1].size = bar->size - table_end;
-
-		RTE_LOG(DEBUG, EAL,
-			"Trying to map BAR%d that contains the MSI-X "
-			"table. Trying offsets: "
-			"0x%04lx:0x%04lx, 0x%04lx:0x%04lx\n", bar_index,
-			memreg[0].offset, memreg[0].size,
-			memreg[1].offset, memreg[1].size);
-	} else {
-		memreg[0].offset = bar->offset;
-		memreg[0].size = bar->size;
-	}
-
-	/* reserve the address using an inaccessible mapping */
-	bar_addr = mmap(bar->addr, bar->size, 0, MAP_PRIVATE |
-			MAP_ANONYMOUS | additional_flags, -1, 0);
-	if (bar_addr != MAP_FAILED) {
-		void *map_addr = NULL;
-		if (memreg[0].size) {
-			/* actual map of first part */
-			map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
-							memreg[0].offset,
-							memreg[0].size,
-							MAP_FIXED);
-		}
-
-		/* if there's a second part, try to map it */
-		if (map_addr != MAP_FAILED
-			&& memreg[1].offset && memreg[1].size) {
-			void *second_addr = RTE_PTR_ADD(bar_addr,
-							memreg[1].offset -
-							(uintptr_t)bar->offset);
-			map_addr = pci_map_resource(second_addr,
-							vfio_dev_fd,
-							memreg[1].offset,
-							memreg[1].size,
-							MAP_FIXED);
-		}
-
-		if (map_addr == MAP_FAILED || !map_addr) {
-			munmap(bar_addr, bar->size);
-			bar_addr = MAP_FAILED;
-			RTE_LOG(ERR, EAL, "Failed to map pci BAR%d\n",
-					bar_index);
-			return -1;
-		}
-	} else {
-		RTE_LOG(ERR, EAL,
-				"Failed to create inaccessible mapping for BAR%d\n",
-				bar_index);
-		return -1;
-	}
-
-	bar->addr = bar_addr;
-	return 0;
-}
-
-static int
-pci_vfio_map_resource_primary(struct rte_pci_device *dev)
-{
-	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
-	char pci_addr[PATH_MAX] = {0};
-	int vfio_dev_fd;
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list =
-		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-
-	struct pci_map *maps;
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
-					&vfio_dev_fd, &device_info);
-	if (ret)
-		return ret;
-
-	/* allocate vfio_res and get region info */
-	vfio_res = rte_zmalloc("VFIO_RES", sizeof(*vfio_res), 0);
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot store uio mmap details\n", __func__);
-		goto err_vfio_dev_fd;
-	}
-	memcpy(&vfio_res->pci_addr, &dev->addr, sizeof(vfio_res->pci_addr));
-
-	/* get number of registers (up to BAR5) */
-	vfio_res->nb_maps = RTE_MIN((int) device_info.num_regions,
-			VFIO_PCI_BAR5_REGION_INDEX + 1);
-
-	/* map BARs */
-	maps = vfio_res->maps;
-
-	vfio_res->msix_table.bar_index = -1;
-	/* get MSI-X BAR, if any (we have to know where it is because we can't
-	 * easily mmap it when using VFIO)
-	 */
-	ret = pci_vfio_get_msix_bar(vfio_dev_fd, &vfio_res->msix_table);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "  %s cannot get MSI-X BAR number!\n",
-				pci_addr);
-		goto err_vfio_dev_fd;
-	}
-
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-		struct vfio_region_info reg = { .argsz = sizeof(reg) };
-		void *bar_addr;
-
-		reg.index = i;
-
-		ret = ioctl(vfio_dev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg);
-		if (ret) {
-			RTE_LOG(ERR, EAL, "  %s cannot get device region info "
-					"error %i (%s)\n", pci_addr, errno, strerror(errno));
-			goto err_vfio_res;
-		}
-
-		/* chk for io port region */
-		ret = pci_vfio_is_ioport_bar(vfio_dev_fd, i);
-		if (ret < 0)
-			goto err_vfio_res;
-		else if (ret) {
-			RTE_LOG(INFO, EAL, "Ignore mapping IO port bar(%d)\n",
-					i);
-			continue;
-		}
-
-		/* skip non-mmapable BARs */
-		if ((reg.flags & VFIO_REGION_INFO_FLAG_MMAP) == 0)
-			continue;
-
-		/* try mapping somewhere close to the end of hugepages */
-		if (pci_map_addr == NULL)
-			pci_map_addr = pci_find_max_end_va();
-
-		bar_addr = pci_map_addr;
-		pci_map_addr = RTE_PTR_ADD(bar_addr, (size_t) reg.size);
-
-		maps[i].addr = bar_addr;
-		maps[i].offset = reg.offset;
-		maps[i].size = reg.size;
-		maps[i].path = NULL; /* vfio doesn't have per-resource paths */
-
-		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, 0);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
-					pci_addr, i, strerror(errno));
-			goto err_vfio_res;
-		}
-
-		dev->mem_resource[i].addr = maps[i].addr;
-	}
-
-	if (pci_vfio_setup_device(dev, vfio_dev_fd) < 0) {
-		RTE_LOG(ERR, EAL, "  %s setup device failed\n", pci_addr);
-		goto err_vfio_res;
-	}
-
-	TAILQ_INSERT_TAIL(vfio_res_list, vfio_res, next);
-
-	return 0;
-err_vfio_res:
-	rte_free(vfio_res);
-err_vfio_dev_fd:
-	close(vfio_dev_fd);
-	return -1;
-}
-
-static int
-pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
-{
-	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
-	char pci_addr[PATH_MAX] = {0};
-	int vfio_dev_fd;
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list =
-		RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-
-	struct pci_map *maps;
-
-	dev->intr_handle.fd = -1;
-	dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-	ret = vfio_setup_device(pci_get_sysfs_path(), pci_addr,
-					&vfio_dev_fd, &device_info);
-	if (ret)
-		return ret;
-
-	/* if we're in a secondary process, just find our tailq entry */
-	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-		if (rte_pci_addr_cmp(&vfio_res->pci_addr,
-				     &dev->addr))
-			continue;
-		break;
-	}
-	/* if we haven't found our tailq entry, something's wrong */
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
-				pci_addr);
-		goto err_vfio_dev_fd;
-	}
-
-	/* map BARs */
-	maps = vfio_res->maps;
-
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-		ret = pci_vfio_mmap_bar(vfio_dev_fd, vfio_res, i, MAP_FIXED);
-		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "  %s mapping BAR%i failed: %s\n",
-					pci_addr, i, strerror(errno));
-			goto err_vfio_dev_fd;
-		}
-
-		dev->mem_resource[i].addr = maps[i].addr;
-	}
-
-	return 0;
-err_vfio_dev_fd:
-	close(vfio_dev_fd);
-	return -1;
-}
-
-/*
- * map the PCI resources of a PCI device in virtual memory (VFIO version).
- * primary and secondary processes follow almost exactly the same path
- */
-int
-pci_vfio_map_resource(struct rte_pci_device *dev)
-{
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
-		return pci_vfio_map_resource_primary(dev);
-	else
-		return pci_vfio_map_resource_secondary(dev);
-}
-
-int
-pci_vfio_unmap_resource(struct rte_pci_device *dev)
-{
-	char pci_addr[PATH_MAX] = {0};
-	struct rte_pci_addr *loc = &dev->addr;
-	int i, ret;
-	struct mapped_pci_resource *vfio_res = NULL;
-	struct mapped_pci_res_list *vfio_res_list;
-
-	struct pci_map *maps;
-
-	/* store PCI address string */
-	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
-			loc->domain, loc->bus, loc->devid, loc->function);
-
-
-	if (close(dev->intr_handle.fd) < 0) {
-		RTE_LOG(INFO, EAL, "Error when closing eventfd file descriptor for %s\n",
-			pci_addr);
-		return -1;
-	}
-
-	if (pci_vfio_set_bus_master(dev->intr_handle.vfio_dev_fd, false)) {
-		RTE_LOG(ERR, EAL, "  %s cannot unset bus mastering for PCI device!\n",
-				pci_addr);
-		return -1;
-	}
-
-	ret = vfio_release_device(pci_get_sysfs_path(), pci_addr,
-				  dev->intr_handle.vfio_dev_fd);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL,
-			"%s(): cannot release device\n", __func__);
-		return ret;
-	}
-
-	vfio_res_list = RTE_TAILQ_CAST(rte_vfio_tailq.head, mapped_pci_res_list);
-	/* Get vfio_res */
-	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
-		if (memcmp(&vfio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
-			continue;
-		break;
-	}
-	/* if we haven't found our tailq entry, something's wrong */
-	if (vfio_res == NULL) {
-		RTE_LOG(ERR, EAL, "  %s cannot find TAILQ entry for PCI device!\n",
-				pci_addr);
-		return -1;
-	}
-
-	/* unmap BARs */
-	maps = vfio_res->maps;
-
-	RTE_LOG(INFO, EAL, "Releasing pci mapped resource for %s\n",
-		pci_addr);
-	for (i = 0; i < (int) vfio_res->nb_maps; i++) {
-
-		/*
-		 * We do not need to be aware of MSI-X table BAR mappings as
-		 * when mapping. Just using current maps array is enough
-		 */
-		if (maps[i].addr) {
-			RTE_LOG(INFO, EAL, "Calling pci_unmap_resource for %s at %p\n",
-				pci_addr, maps[i].addr);
-			pci_unmap_resource(maps[i].addr, maps[i].size);
-		}
-	}
-
-	TAILQ_REMOVE(vfio_res_list, vfio_res, next);
-
-	return 0;
-}
-
-int
-pci_vfio_ioport_map(struct rte_pci_device *dev, int bar,
-		    struct rte_pci_ioport *p)
-{
-	if (bar < VFIO_PCI_BAR0_REGION_INDEX ||
-	    bar > VFIO_PCI_BAR5_REGION_INDEX) {
-		RTE_LOG(ERR, EAL, "invalid bar (%d)!\n", bar);
-		return -1;
-	}
-
-	p->dev = dev;
-	p->base = VFIO_GET_REGION_ADDR(bar);
-	return 0;
-}
-
-void
-pci_vfio_ioport_read(struct rte_pci_ioport *p,
-		     void *data, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
-
-	if (pread64(intr_handle->vfio_dev_fd, data,
-		    len, p->base + offset) <= 0)
-		RTE_LOG(ERR, EAL,
-			"Can't read from PCI bar (%" PRIu64 ") : offset (%x)\n",
-			VFIO_GET_REGION_IDX(p->base), (int)offset);
-}
-
-void
-pci_vfio_ioport_write(struct rte_pci_ioport *p,
-		      const void *data, size_t len, off_t offset)
-{
-	const struct rte_intr_handle *intr_handle = &p->dev->intr_handle;
-
-	if (pwrite64(intr_handle->vfio_dev_fd, data,
-		     len, p->base + offset) <= 0)
-		RTE_LOG(ERR, EAL,
-			"Can't write to PCI bar (%" PRIu64 ") : offset (%x)\n",
-			VFIO_GET_REGION_IDX(p->base), (int)offset);
-}
-
-int
-pci_vfio_ioport_unmap(struct rte_pci_ioport *p)
-{
-	RTE_SET_USED(p);
-	return -1;
-}
-
-int
-pci_vfio_is_enabled(void)
-{
-	return vfio_is_enabled("vfio_pci");
-}
-#endif
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 8d67b67..d2a4ff9 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -166,17 +166,6 @@ DPDK_17.05 {
 	rte_log_set_global_level;
 	rte_log_set_level;
 	rte_log_set_level_regexp;
-	rte_pci_dump;
-	rte_pci_ioport_map;
-	rte_pci_ioport_read;
-	rte_pci_ioport_unmap;
-	rte_pci_ioport_write;
-	rte_pci_map_device;
-	rte_pci_read_config;
-	rte_pci_register;
-	rte_pci_unmap_device;
-	rte_pci_unregister;
-	rte_pci_write_config;
 	rte_vdev_init;
 	rte_vdev_register;
 	rte_vdev_uninit;
@@ -237,11 +226,8 @@ EXPERIMENTAL {
 DPDK_17.11 {
 	global:
 
-	eal_parse_pci_BDF;
-	eal_parse_pci_DomBDF;
 	rte_eal_create_uio_dev;
 	rte_bus_get_iommu_class;
-	rte_eal_compare_pci_addr;
 	rte_eal_has_pci;
 	rte_eal_iova_mode;
 	rte_eal_mbuf_default_mempool_ops;
@@ -249,9 +235,6 @@ DPDK_17.11 {
 	rte_eal_vfio_intr_mode;
 	rte_lcore_has_role;
 	rte_memcpy_ptr;
-	rte_pci_addr_cmp;
-	rte_pci_addr_parse;
-	rte_pci_device_name;
 	vfio_enable;
 	vfio_is_enabled;
 	vfio_noiommu_is_enabled;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 9108a76..18e474d 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1156,8 +1156,6 @@ TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
 	} \
 } while (0)
 
-#define RTE_ETH_DEV_TO_PCI(eth_dev)	RTE_DEV_TO_PCI((eth_dev)->device)
-
 /**
  * l2 tunnel configuration.
  */
diff --git a/lib/librte_ether/rte_ethdev_pci.h b/lib/librte_ether/rte_ethdev_pci.h
index 56b1072..722075e 100644
--- a/lib/librte_ether/rte_ethdev_pci.h
+++ b/lib/librte_ether/rte_ethdev_pci.h
@@ -36,6 +36,7 @@
 
 #include <rte_malloc.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_ethdev.h>
 
 /**
diff --git a/lib/librte_eventdev/rte_eventdev_pmd_pci.h b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
index b6bd731..ade32b5 100644
--- a/lib/librte_eventdev/rte_eventdev_pmd_pci.h
+++ b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
@@ -50,6 +50,7 @@ extern "C" {
 #include <rte_eal.h>
 #include <rte_lcore.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include "rte_eventdev_pmd.h"
 
diff --git a/lib/librte_pci/Makefile b/lib/librte_pci/Makefile
new file mode 100644
index 0000000..82a16e2
--- /dev/null
+++ b/lib/librte_pci/Makefile
@@ -0,0 +1,49 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 6WIND S.A.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of 6WIND nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_pci.a
+
+CFLAGS := -I$(SRCDIR)/include -I$(SRCDIR) $(CFLAGS)
+CFLAGS += $(WERROR_FLAGS) -O3
+LDLIBS += -lrte_eal
+
+EXPORT_MAP := rte_pci_version.map
+
+LIBABIVER := 1
+
+SRCS-$(CONFIG_RTE_LIBRTE_PCI) += rte_pci.c
+
+SYMLINK-$(CONFIG_RTE_LIBRTE_PCI)-include += include/rte_pci.h
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_pci/include/rte_pci.h b/lib/librte_pci/include/rte_pci.h
new file mode 100644
index 0000000..ea0897c
--- /dev/null
+++ b/lib/librte_pci/include/rte_pci.h
@@ -0,0 +1,279 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_PCI_H_
+#define _RTE_PCI_H_
+
+/**
+ * @file
+ *
+ * RTE PCI Library
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+
+/** Formatting string for PCI device identifier: Ex: 0000:00:01.0 */
+#define PCI_PRI_FMT "%.4" PRIx16 ":%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+#define PCI_PRI_STR_SIZE sizeof("XXXXXXXX:XX:XX.X")
+
+/** Short formatting string, without domain, for PCI device: Ex: 00:01.0 */
+#define PCI_SHORT_PRI_FMT "%.2" PRIx8 ":%.2" PRIx8 ".%" PRIx8
+
+/** Nb. of values in PCI device identifier format string. */
+#define PCI_FMT_NVAL 4
+
+/** Nb. of values in PCI resource format. */
+#define PCI_RESOURCE_FMT_NVAL 3
+
+/** Maximum number of PCI resources. */
+#define PCI_MAX_RESOURCE 6
+
+/**
+ * A structure describing an ID for a PCI driver. Each driver provides a
+ * table of these IDs for each device that it supports.
+ */
+struct rte_pci_id {
+	uint32_t class_id;            /**< Class ID or RTE_CLASS_ANY_ID. */
+	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
+	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
+	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
+	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
+};
+
+/**
+ * A structure describing the location of a PCI device.
+ */
+struct rte_pci_addr {
+	uint32_t domain;                /**< Device domain */
+	uint8_t bus;                    /**< Device bus */
+	uint8_t devid;                  /**< Device ID */
+	uint8_t function;               /**< Device function. */
+};
+
+/** Any PCI device identifier (vendor, device, ...) */
+#define PCI_ANY_ID (0xffff)
+#define RTE_CLASS_ANY_ID (0xffffff)
+
+/**
+ * A structure describing a PCI mapping.
+ */
+struct pci_map {
+	void *addr;
+	char *path;
+	uint64_t offset;
+	uint64_t size;
+	uint64_t phaddr;
+};
+
+struct pci_msix_table {
+	int bar_index;
+	uint32_t offset;
+	uint32_t size;
+};
+
+/**
+ * A structure describing a mapped PCI resource.
+ * For multi-process we need to reproduce all PCI mappings in secondary
+ * processes, so save them in a tailq.
+ */
+struct mapped_pci_resource {
+	TAILQ_ENTRY(mapped_pci_resource) next;
+
+	struct rte_pci_addr pci_addr;
+	char path[PATH_MAX];
+	int nb_maps;
+	struct pci_map maps[PCI_MAX_RESOURCE];
+	struct pci_msix_table msix_table;
+};
+
+
+/** mapped pci device list */
+TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
+
+/**
+ * @deprecated
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided without
+ * a domain prefix (i.e. domain returned is always 0)
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned.
+ *	Domain will always be returned as 0
+ * @return
+ *  0 on success, negative on error.
+ */
+int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
+ * Utility function to produce a PCI Bus-Device-Function value
+ * given a string representation. Assumes that the BDF is provided including
+ * a domain prefix.
+ *
+ * @param input
+ *	The input string to be parsed. Should have the format XXXX:XX:XX.X
+ * @param dev_addr
+ *	The PCI Bus-Device-Function address to be returned
+ * @return
+ *  0 on success, negative on error.
+ */
+int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
+
+/**
+ * @deprecated
+ * Utility function to write a pci device name, this device name can later be
+ * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
+ * BDF helpers.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ */
+void rte_pci_device_name(const struct rte_pci_addr *addr,
+			 char *output, size_t size);
+
+/**
+ * Utility function to write a pci device name, this device name can later be
+ * used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
+ * BDF helpers.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address
+ * @param output
+ *	The output buffer string
+ * @param size
+ *	The output buffer size
+ */
+void pci_device_name(const struct rte_pci_addr *addr,
+		     char *output, size_t size);
+
+/**
+ * @deprecated
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
+int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			     const struct rte_pci_addr *addr2);
+
+/**
+ * Utility function to compare two PCI device addresses.
+ *
+ * @param addr
+ *	The PCI Bus-Device-Function address to compare
+ * @param addr2
+ *	The PCI Bus-Device-Function address to compare
+ * @return
+ *	0 on equal PCI address.
+ *	Positive on addr is greater than addr2.
+ *	Negative on addr is less than addr2, or error.
+ */
+int pci_addr_cmp(const struct rte_pci_addr *addr,
+		 const struct rte_pci_addr *addr2);
+
+
+/**
+ * Utility function to parse a string into a PCI location.
+ *
+ * @param str
+ *	The string to parse
+ * @param addr
+ *	The reference to the structure where the location
+ *	is stored.
+ * @return
+ *	0 on success
+ *	<0 otherwise
+ */
+int pci_addr_parse(const char *str, struct rte_pci_addr *addr);
+
+/**
+ * Map a particular resource from a file.
+ *
+ * @param requested_addr
+ *      The starting address for the new mapping range.
+ * @param fd
+ *      The file descriptor.
+ * @param offset
+ *      The offset for the mapping range.
+ * @param size
+ *      The size for the mapping range.
+ * @param additional_flags
+ *      The additional flags for the mapping range.
+ * @return
+ *   - On success, the function returns a pointer to the mapped area.
+ *   - On error, the value MAP_FAILED is returned.
+ */
+void *pci_map_resource(void *requested_addr, int fd, off_t offset,
+		size_t size, int additional_flags);
+
+/**
+ * Unmap a particular resource.
+ *
+ * @param requested_addr
+ *      The address for the unmapping range.
+ * @param size
+ *      The size for the unmapping range.
+ */
+void pci_unmap_resource(void *requested_addr, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PCI_H_ */
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
new file mode 100644
index 0000000..1307a18
--- /dev/null
+++ b/lib/librte_pci/rte_pci.c
@@ -0,0 +1,220 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright 2013-2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+
+#include <rte_errno.h>
+#include <rte_interrupts.h>
+#include <rte_log.h>
+#include <rte_bus.h>
+#include <rte_per_lcore.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_eal.h>
+#include <rte_string_fns.h>
+#include <rte_common.h>
+
+#include "rte_pci.h"
+
+static inline const char *
+get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
+{
+	unsigned long val;
+	uint8_t *u8 = _u8;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != dlm || val > UINT8_MAX) {
+		errno = errno ? errno : EINVAL;
+		return NULL;
+	}
+	*u8 = (uint8_t)val;
+	return end + 1;
+}
+
+static int
+pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
+{
+	const char *in = input;
+
+	dev_addr->domain = 0;
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
+	return 0;
+}
+
+static int
+pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
+{
+	const char *in = input;
+	unsigned long val;
+	char *end;
+
+	errno = 0;
+	val = strtoul(in, &end, 16);
+	if (errno != 0 || end[0] != ':' || val > UINT16_MAX)
+		return -EINVAL;
+	dev_addr->domain = (uint16_t)val;
+	in = end + 1;
+	in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+	if (in == NULL)
+		return -EINVAL;
+	in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+	if (in == NULL)
+		return -EINVAL;
+	return 0;
+}
+
+int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	return pci_bdf_parse(input, dev_addr);
+}
+
+int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+	return pci_dbdf_parse(input, dev_addr);
+}
+
+void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+		    char *output, size_t size)
+{
+	pci_device_name(addr, output, size);
+}
+
+void
+pci_device_name(const struct rte_pci_addr *addr,
+		char *output, size_t size)
+{
+	RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+	RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+			    addr->domain, addr->bus,
+			    addr->devid, addr->function) >= 0);
+}
+
+int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+			 const struct rte_pci_addr *addr2)
+{
+	return pci_addr_cmp(addr, addr2);
+}
+
+int
+pci_addr_cmp(const struct rte_pci_addr *addr,
+	     const struct rte_pci_addr *addr2)
+{
+	uint64_t dev_addr, dev_addr2;
+
+	if ((addr == NULL) || (addr2 == NULL))
+		return -1;
+
+	dev_addr = ((uint64_t)addr->domain << 24) |
+		(addr->bus << 16) | (addr->devid << 8) | addr->function;
+	dev_addr2 = ((uint64_t)addr2->domain << 24) |
+		(addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+	if (dev_addr > dev_addr2)
+		return 1;
+	else if (dev_addr < dev_addr2)
+		return -1;
+	else
+		return 0;
+}
+
+int
+pci_addr_parse(const char *str, struct rte_pci_addr *addr)
+{
+	if (pci_bdf_parse(str, addr) == 0 ||
+	    pci_dbdf_parse(str, addr) == 0)
+		return 0;
+	return -1;
+}
+
+
+/* map a particular resource from a file */
+void *
+pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+		 int additional_flags)
+{
+	void *mapaddr;
+
+	/* Map the PCI memory resource of device */
+	mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+			MAP_SHARED | additional_flags, fd, offset);
+	if (mapaddr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
+			__func__, fd, requested_addr,
+			(unsigned long)size, (unsigned long)offset,
+			strerror(errno), mapaddr);
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory mapped at %p\n", mapaddr);
+
+	return mapaddr;
+}
+
+/* unmap a particular resource */
+void
+pci_unmap_resource(void *requested_addr, size_t size)
+{
+	if (requested_addr == NULL)
+		return;
+
+	/* Unmap the PCI memory resource of device */
+	if (munmap(requested_addr, size)) {
+		RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+			__func__, requested_addr, (unsigned long)size,
+			strerror(errno));
+	} else
+		RTE_LOG(DEBUG, EAL, "  PCI memory unmapped at %p\n",
+				requested_addr);
+}
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
new file mode 100644
index 0000000..b5c9ec2
--- /dev/null
+++ b/lib/librte_pci/rte_pci_version.map
@@ -0,0 +1,15 @@
+DPDK_17.11 {
+	global:
+
+	eal_parse_pci_BDF;
+	eal_parse_pci_DomBDF;
+	pci_addr_cmp;
+	pci_addr_parse;
+	pci_device_name;
+	pci_map_resource;
+	pci_unmap_resource;
+	rte_eal_compare_pci_addr;
+	rte_pci_device_name;
+
+	local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index fbb4bc6..047121d 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -99,6 +99,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV)       += -lrte_eventdev
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL)        += -lrte_mempool
 _LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING)   += -lrte_mempool_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI)            += -lrte_pci
 _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
 _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
 _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
@@ -108,6 +109,8 @@ ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI)            += -lrte_kni
 endif
 
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PCI_BUS)        += -lrte_bus_pci
+
 ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
 # plugins (link only if static libraries)
 
diff --git a/test/test/test_kni.c b/test/test/test_kni.c
index 2450c9f..b956727 100644
--- a/test/test/test_kni.c
+++ b/test/test/test_kni.c
@@ -42,6 +42,7 @@
 #include <rte_string_fns.h>
 #include <rte_mempool.h>
 #include <rte_ethdev.h>
+#include <rte_bus_pci.h>
 #include <rte_cycles.h>
 #include <rte_kni.h>
 
diff --git a/test/test/virtual_pmd.c b/test/test/virtual_pmd.c
index 09daf6c..b57a949 100644
--- a/test/test/virtual_pmd.c
+++ b/test/test/virtual_pmd.c
@@ -34,6 +34,7 @@
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_memory.h>
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 24/25] doc: add notes on EAL PCI API update
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (22 preceding siblings ...)
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 23/25] pci: introduce PCI lib and bus Gaetan Rivet
@ 2017-10-26 10:06             ` Gaetan Rivet
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 25/25] maintainers: claim maintainership of PCI lib Gaetan Rivet
                               ` (2 subsequent siblings)
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:06 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Add a section related to EAL API changes to 17.11 release notes.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/rel_notes/release_17_11.rst | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 93f94fc..6619711 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -369,6 +369,34 @@ API Changes
   the backing device supports the operation or if the operation was
   successfully performed.
 
+* **PCI bus API moved outside of the EAL**
+
+  The PCI bus previously implemented within the EAL has been moved.
+  A first part has been added as an RTE library providing PCI helpers to
+  parse device locations or other such utilities.
+  A second part consisting in the actual bus driver has been moved to its
+  proper subdirectory, without changing its functionalities.
+
+  As such, several PCI-related functions are not proposed by the EAL anymore:
+
+  * rte_pci_detach
+  * rte_pci_dump
+  * rte_pci_ioport_map
+  * rte_pci_ioport_read
+  * rte_pci_ioport_unmap
+  * rte_pci_ioport_write
+  * rte_pci_map_device
+  * rte_pci_probe
+  * rte_pci_probe_one
+  * rte_pci_read_config
+  * rte_pci_register
+  * rte_pci_scan
+  * rte_pci_unmap_device
+  * rte_pci_unregister
+  * rte_pci_write_config
+
+  These functions are made available either as part of ``librte_pci`` or
+  ``librte_bus_pci``.
 
 ABI Changes
 -----------
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* [dpdk-dev] [PATCH v8 25/25] maintainers: claim maintainership of PCI lib
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (23 preceding siblings ...)
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 24/25] doc: add notes on EAL PCI API update Gaetan Rivet
@ 2017-10-26 10:06             ` Gaetan Rivet
  2017-10-26 21:23             ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Thomas Monjalon
  2017-10-29 16:47             ` Andrew Rybchenko
  26 siblings, 0 replies; 156+ messages in thread
From: Gaetan Rivet @ 2017-10-26 10:06 UTC (permalink / raw)
  To: dev; +Cc: Gaetan Rivet

Add also PCI bus as an orphan.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 04bdbae..597f2da 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -286,6 +286,11 @@ T: git://dpdk.org/next/dpdk-next-eventdev
 F: lib/librte_eventdev/*eth_rx_adapter*
 F: test/test/test_event_eth_rx_adapter.c
 
+Bus Drivers
+-----------
+
+PCI:
+F: drivers/bus/pci
 
 Networking Drivers
 ------------------
@@ -876,6 +881,10 @@ Latency statistics
 M: Reshma Pattan <reshma.pattan@intel.com>
 F: lib/librte_latencystats/
 
+PCI
+M: Gaetan Rivet <gaetan.rivet@6wind.com>
+F: lib/librte_pci/
+
 
 Test Applications
 -----------------
-- 
2.1.4

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v8 23/25] pci: introduce PCI lib and bus
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 23/25] pci: introduce PCI lib and bus Gaetan Rivet
@ 2017-10-26 15:56               ` Thomas Monjalon
  2017-10-26 17:44               ` Thomas Monjalon
  1 sibling, 0 replies; 156+ messages in thread
From: Thomas Monjalon @ 2017-10-26 15:56 UTC (permalink / raw)
  To: Gaetan Rivet; +Cc: dev

26/10/2017 12:06, Gaetan Rivet:
> Libraries, drivers, unit tests and applications are updated to use the
> new rte_bus_pci.h header when necessary.

Few compilation fixes:

--- a/drivers/crypto/qat/qat_crypto.c
+++ b/drivers/crypto/qat/qat_crypto.c
@@ -60,6 +60,7 @@
 #include <rte_crypto_sym.h>
 #include <rte_byteorder.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 
 #include <openssl/evp.h>
 
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -18,6 +18,7 @@
 
 #include <rte_byteorder.h>
 #include <rte_spinlock.h>
+#include <rte_bus_pci.h>
 #include <rte_io.h>
 
 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN

--- a/examples/ethtool/lib/rte_ethtool.c
+++ b/examples/ethtool/lib/rte_ethtool.c
@@ -37,6 +37,7 @@
 #include <rte_ethdev.h>
 #include <rte_ether.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #ifdef RTE_LIBRTE_IXGBE_PMD
 #include <rte_pmd_ixgbe.h>
 #endif

--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -49,6 +49,7 @@
 #include <rte_ip.h>
 #include <rte_eal.h>
 #include <rte_malloc.h>
+#include <rte_bus_pci.h>
 
 #include "app.h"
 #include "pipeline.h"

--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -62,6 +62,7 @@
 #include <rte_branch_prediction.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_debug.h>
 #include <rte_ether.h>
 #include <rte_ethdev.h>

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v8 23/25] pci: introduce PCI lib and bus
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 23/25] pci: introduce PCI lib and bus Gaetan Rivet
  2017-10-26 15:56               ` Thomas Monjalon
@ 2017-10-26 17:44               ` Thomas Monjalon
  1 sibling, 0 replies; 156+ messages in thread
From: Thomas Monjalon @ 2017-10-26 17:44 UTC (permalink / raw)
  To: Gaetan Rivet; +Cc: dev

26/10/2017 12:06, Gaetan Rivet:
>  lib/librte_pci/Makefile                      |  49 ++
>  lib/librte_pci/include/rte_pci.h             | 279 +++++++++
>  lib/librte_pci/rte_pci.c                     | 220 +++++++
>  lib/librte_pci/rte_pci_version.map           |  15 +

The include file is usually not in a sub-directory.
I will move it for consistency.

The lib needs also to be added in doc/api/doxy-api.conf and
doc/guides/rel_notes/release_17_11.rst

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (24 preceding siblings ...)
  2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 25/25] maintainers: claim maintainership of PCI lib Gaetan Rivet
@ 2017-10-26 21:23             ` Thomas Monjalon
  2017-10-29 16:47             ` Andrew Rybchenko
  26 siblings, 0 replies; 156+ messages in thread
From: Thomas Monjalon @ 2017-10-26 21:23 UTC (permalink / raw)
  To: Gaetan Rivet; +Cc: dev, Anatoly Burakov

26/10/2017 12:05, Gaetan Rivet:
> Here is a new version of the PCI bus move out of the EAL.
> 
> The EAL PCI implementation is divided in two parts:
> 
>   - librte_pci: library offering helpers to handle PCI objects
>   - librte_bus_pci: bus driver for PCI devices

Applied with few fixes, thanks for the huge work Gaetan

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL
  2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
                               ` (25 preceding siblings ...)
  2017-10-26 21:23             ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Thomas Monjalon
@ 2017-10-29 16:47             ` Andrew Rybchenko
  2017-10-30  5:16               ` Gaëtan Rivet
  26 siblings, 1 reply; 156+ messages in thread
From: Andrew Rybchenko @ 2017-10-29 16:47 UTC (permalink / raw)
  To: Gaetan Rivet, dev; +Cc: Anatoly Burakov

As I understand as the result of these changes VFIO_PRESENT is always 
undefined
when bus/pci sources are build (because eal_vfio.h is not included).
So, many things do not work if vfio-pci is used. In my case 
rte_pci_map_device() fails with -1.

Andrew.

^ permalink raw reply	[flat|nested] 156+ messages in thread

* Re: [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL
  2017-10-29 16:47             ` Andrew Rybchenko
@ 2017-10-30  5:16               ` Gaëtan Rivet
  0 siblings, 0 replies; 156+ messages in thread
From: Gaëtan Rivet @ 2017-10-30  5:16 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev, Anatoly Burakov

Hi Andrew,

You're right, sorry for the instability.
A fix has been proposed[1]. It needs to be discussed.

My opinion was that VFIO_PRESENT should stay internal to the EAL. There
should be no need to another library to depend on it.
I will discuss this in the other thread.

Regards,

[1]: http://dpdk.org/ml/archives/dev/2017-October/080746.html

On Sun, Oct 29, 2017 at 07:47:17PM +0300, Andrew Rybchenko wrote:
> As I understand as the result of these changes VFIO_PRESENT is always
> undefined
> when bus/pci sources are build (because eal_vfio.h is not included).
> So, many things do not work if vfio-pci is used. In my case
> rte_pci_map_device() fails with -1.
> 
> Andrew.

-- 
Gaëtan Rivet
6WIND

^ permalink raw reply	[flat|nested] 156+ messages in thread

end of thread, other threads:[~2017-10-30  5:16 UTC | newest]

Thread overview: 156+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-25  9:04 [dpdk-dev] [PATCH 00/13] Move PCI away from the EAL Gaetan Rivet
2017-08-25  9:04 ` [dpdk-dev] [PATCH 01/13] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
2017-09-04 13:24   ` Burakov, Anatoly
2017-08-25  9:04 ` [dpdk-dev] [PATCH 02/13] ethdev: remove useless PCI dependency Gaetan Rivet
2017-08-25  9:04 ` [dpdk-dev] [PATCH 03/13] bus: properly include rte_debug Gaetan Rivet
2017-08-25  9:04 ` [dpdk-dev] [PATCH 04/13] eal: remove references to PCI Gaetan Rivet
2017-08-25  9:04 ` [dpdk-dev] [PATCH 05/13] pci: introduce PCI lib and bus Gaetan Rivet
2017-08-25  9:31   ` Luca Boccassi
2017-08-25  9:34     ` Gaëtan Rivet
2017-08-25  9:04 ` [dpdk-dev] [PATCH 06/13] pci: avoid inlining functions Gaetan Rivet
2017-08-25  9:04 ` [dpdk-dev] [PATCH 07/13] pci: avoid over-complicated macro Gaetan Rivet
2017-08-25  9:04 ` [dpdk-dev] [PATCH 08/13] pci: deprecate misnamed functions Gaetan Rivet
2017-08-25  9:04 ` [dpdk-dev] [PATCH 09/13] lib: include rte_bus_pci Gaetan Rivet
2017-08-25  9:04 ` [dpdk-dev] [PATCH 10/13] drivers: " Gaetan Rivet
2017-08-25  9:04 ` [dpdk-dev] [PATCH 11/13] test: " Gaetan Rivet
2017-08-25  9:04 ` [dpdk-dev] [PATCH 12/13] app/testpmd: " Gaetan Rivet
2017-08-25  9:04 ` [dpdk-dev] [PATCH 13/13] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
2017-09-18  9:31 ` [dpdk-dev] [PATCH v2 00/14] Move PCI away from the EAL Gaetan Rivet
2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 01/14] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
2017-09-18 10:47     ` Shreyansh Jain
2017-09-18 11:37       ` Gaëtan Rivet
2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 02/14] ethdev: remove useless PCI dependency Gaetan Rivet
2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 03/14] bus: properly include rte_debug Gaetan Rivet
2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 04/14] eal: remove references to PCI Gaetan Rivet
2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 05/14] pci: introduce PCI lib and bus Gaetan Rivet
2017-09-18 11:53     ` Shreyansh Jain
2017-09-18 11:51       ` Gaëtan Rivet
2017-09-18 12:18         ` Shreyansh Jain
2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 06/14] lib: include rte_bus_pci Gaetan Rivet
2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 07/14] drivers: " Gaetan Rivet
2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 08/14] test: " Gaetan Rivet
2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 09/14] app/testpmd: " Gaetan Rivet
2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 10/14] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 11/14] pci: avoid inlining functions Gaetan Rivet
2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 12/14] pci: avoid over-complicated macro Gaetan Rivet
2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 13/14] pci: deprecate misnamed functions Gaetan Rivet
2017-09-18  9:31   ` [dpdk-dev] [PATCH v2 14/14] doc: add notes on EAL PCI API update Gaetan Rivet
2017-09-18 11:22     ` Mcnamara, John
2017-09-25 15:23   ` [dpdk-dev] [PATCH v3 00/13] Move PCI away from the EAL Gaetan Rivet
2017-09-25 15:23     ` [dpdk-dev] [PATCH v3 01/13] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
2017-09-25 15:23     ` [dpdk-dev] [PATCH v3 02/13] ethdev: remove useless PCI dependency Gaetan Rivet
2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 03/13] bus: properly include rte_debug Gaetan Rivet
2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 04/13] pci: introduce PCI lib and bus Gaetan Rivet
2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 05/13] lib: include rte_bus_pci Gaetan Rivet
2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 06/13] drivers: " Gaetan Rivet
2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 07/13] test: " Gaetan Rivet
2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 08/13] app/testpmd: " Gaetan Rivet
2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 09/13] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 10/13] pci: avoid inlining functions Gaetan Rivet
2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 11/13] pci: avoid over-complicated macro Gaetan Rivet
2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 12/13] pci: deprecate misnamed functions Gaetan Rivet
2017-09-25 15:24     ` [dpdk-dev] [PATCH v3 13/13] doc: add notes on EAL PCI API update Gaetan Rivet
2017-10-12  8:17     ` [dpdk-dev] [PATCH v4 00/16] Move PCI away from the EAL Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 01/16] eal: include debug header in bus source Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 02/16] ethdev: remove useless PCI dependency Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 03/16] pci: introduce PCI lib and bus Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 04/16] lib: include PCI bus header Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 05/16] drivers: " Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 06/16] test: " Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 07/16] app/testpmd: " Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 08/16] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 09/16] net/bonding: use local prefix for local function Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 10/16] pci: avoid inlining functions Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 11/16] pci: avoid over-complicated macro Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 12/16] pci: deprecate misnamed functions Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 13/16] pci: introduce PCI address parsing function Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 14/16] pci: make specialized parsing functions private Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 15/16] bus/pci: use new PCI addr parsing function Gaetan Rivet
2017-10-12  8:17       ` [dpdk-dev] [PATCH v4 16/16] doc: add notes on EAL PCI API update Gaetan Rivet
2017-10-12 10:45       ` [dpdk-dev] [PATCH v5 00/20] Move PCI away from the EAL Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 01/20] eal: include debug header in bus source Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 02/20] ethdev: remove useless PCI dependency Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 03/20] pci: introduce PCI lib and bus Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 04/20] lib: include PCI bus header Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 05/20] drivers: " Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 06/20] test: " Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 07/20] app/testpmd: " Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 08/20] cryptodev: move PCI specific helpers to drivers/crypto Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 09/20] net/bonding: use local prefix for local function Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 10/20] pci: avoid inlining functions Gaetan Rivet
2017-10-17 18:20           ` Aaron Conole
2017-10-18  8:54             ` Gaëtan Rivet
2017-10-18 14:30               ` Aaron Conole
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 11/20] pci: avoid over-complicated macro Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 12/20] pci: deprecate misnamed functions Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 13/20] pci: introduce PCI address parsing function Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 14/20] pci: make specialized parsing functions private Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 15/20] bus/pci: use new PCI addr parsing function Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 16/20] bus/pci: do not expose private functions Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 17/20] bus/pci: do not expose PCI match function Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 18/20] bus/pci: do not expose IOVA mode getter Gaetan Rivet
2017-10-12 10:54           ` Gaëtan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 19/20] doc: add notes on EAL PCI API update Gaetan Rivet
2017-10-12 10:45         ` [dpdk-dev] [PATCH v5 20/20] bus: rename scan policy as probe policy Gaetan Rivet
2017-10-12 10:55           ` Gaëtan Rivet
2017-10-25 22:38         ` [dpdk-dev] [PATCH v7 00/25] Move PCI away from the EAL Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 01/25] ethdev: remove useless PCI dependency Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 02/25] eal: include debug header in bus source Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 03/25] eal: include stdint in private header Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 04/25] eal: include common header Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 05/25] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 06/25] eal: expose internal config elements Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 07/25] eal: expose vfio symbols Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 08/25] vfio: remove useless PCI headers and add vfio one Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 09/25] vfio: check PCI dependency from within PCI code Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 10/25] vfio: move PCI-related functions out of vfio header Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 11/25] pci: avoid inlining functions Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 12/25] pci: avoid over-complicated macro Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 13/25] pci: deprecate misnamed functions Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 14/25] pci: introduce PCI address parsing function Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 15/25] pci: make specialized parsing functions private Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 16/25] pci: use new PCI addr comparison function Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 17/25] pci: use new PCI addr parsing function Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 18/25] pci: do not expose private functions Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 19/25] pci: do not expose PCI match function Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 20/25] pci: do not expose IOVA mode getter Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 21/25] pci: use EAL exposed configuration Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 22/25] net/bonding: use local prefix for local function Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 23/25] pci: introduce PCI lib and bus Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 24/25] doc: add notes on EAL PCI API update Gaetan Rivet
2017-10-25 22:38           ` [dpdk-dev] [PATCH v7 25/25] maintainers: claim maintainership of PCI lib Gaetan Rivet
2017-10-26 10:05           ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Gaetan Rivet
2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 01/25] ethdev: remove useless PCI dependency Gaetan Rivet
2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 02/25] eal: include debug header in bus source Gaetan Rivet
2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 03/25] eal: include stdint in private header Gaetan Rivet
2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 04/25] eal: include common header Gaetan Rivet
2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 05/25] eal: expose rte_eal_using_phys_addrs Gaetan Rivet
2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 06/25] eal: expose internal config elements Gaetan Rivet
2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 07/25] eal: expose vfio symbols Gaetan Rivet
2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 08/25] vfio: remove useless PCI headers Gaetan Rivet
2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 09/25] vfio: check PCI dependency from within PCI code Gaetan Rivet
2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 10/25] vfio: move PCI-related symbols out of vfio header Gaetan Rivet
2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 11/25] pci: avoid inlining functions Gaetan Rivet
2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 12/25] pci: avoid over-complicated macro Gaetan Rivet
2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 13/25] pci: deprecate misnamed functions Gaetan Rivet
2017-10-26 10:05             ` [dpdk-dev] [PATCH v8 14/25] pci: introduce PCI address parsing function Gaetan Rivet
2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 15/25] pci: make specialized parsing functions private Gaetan Rivet
2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 16/25] pci: use new PCI addr comparison function Gaetan Rivet
2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 17/25] pci: use new PCI addr parsing function Gaetan Rivet
2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 18/25] pci: do not expose private functions Gaetan Rivet
2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 19/25] pci: do not expose PCI match function Gaetan Rivet
2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 20/25] pci: do not expose IOVA mode getter Gaetan Rivet
2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 21/25] pci: use EAL exposed configuration Gaetan Rivet
2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 22/25] net/bonding: use local prefix for local function Gaetan Rivet
2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 23/25] pci: introduce PCI lib and bus Gaetan Rivet
2017-10-26 15:56               ` Thomas Monjalon
2017-10-26 17:44               ` Thomas Monjalon
2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 24/25] doc: add notes on EAL PCI API update Gaetan Rivet
2017-10-26 10:06             ` [dpdk-dev] [PATCH v8 25/25] maintainers: claim maintainership of PCI lib Gaetan Rivet
2017-10-26 21:23             ` [dpdk-dev] [PATCH v8 00/25] Move PCI away from the EAL Thomas Monjalon
2017-10-29 16:47             ` Andrew Rybchenko
2017-10-30  5:16               ` Gaëtan Rivet
2017-10-11 14:19   ` [dpdk-dev] [PATCH v2 00/14] " Doherty, Declan
2017-10-11 14:32     ` Gaëtan Rivet
2017-10-23  8:44       ` De Lara Guarch, Pablo
2017-10-23  8:49         ` Gaëtan Rivet

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).