Description: backport of dpdk 16.04 fix for LP: #1570195

The whole infrastructure of 756ce64b1ecd eal: "introduce PCI ioport API" was
introduced post DPDK 2.2.

Old virtio is not using lib/librte_eal/linuxapp/eal/eal_pci.c:pci_map_device
New Code:
 vtpci_init
   First tries for modern device -> virtio_read_caps -> rte_eal_pci_map_device
   This detects and returns with "Not managed by a supported kernel driver"
   Then legacy_virtio_resource_init -> rte_eal_pci_ioport_mapi
   This is where the original patch added the check
 vtpci_init came in c52afa68 "virtio: move left PCI stuff in the right file"
 Old code was eth_virtio_dev_init -> virtio_resource_init(pci_dev)

The logic of the new patch isn't too complex, just the places don't exist
yet. So we add a semantically equivalent check just before virtio_resource_init.

Additionally I added a message to make it more clear what happened:
EAL: PCI device 0000:00:04.0 on NUMA socket -1
EAL:   probe driver: 1af4:1000 rte_virtio_pmd
=> PMD: device not available (in use by the kernel)
EAL: Error - exiting with code: 1
  Cause: Requested device 0000:00:04.0 cannot be used

Forwarded: n/a (already upstream)
Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Last-Update: 2016-04-19

From b8eb345378bdefc4c976eaaf5abb221e0aca3460 Mon Sep 17 00:00:00 2001
From: Huawei Xie <huawei.xie@intel.com>
Date: Tue, 8 Mar 2016 23:33:42 +0800
Subject: [PATCH] pci: ignore devices already managed in Linux when mapping x86
 ioport

call pci_ioport_map (on x86) only if the pci device is not bound
to a kernel driver.

Signed-off-by: Huawei Xie <huawei.xie@intel.com>
Acked-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Acked-by: David Marchand <david.marchand@6wind.com>
---
 lib/librte_eal/linuxapp/eal/eal_pci.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Index: dpdk/drivers/net/virtio/virtio_ethdev.c
===================================================================
--- dpdk.orig/drivers/net/virtio/virtio_ethdev.c
+++ dpdk/drivers/net/virtio/virtio_ethdev.c
@@ -1219,6 +1219,34 @@ static int virtio_resource_init(struct r
 }
 #endif
 
+static int virtio_resource_available(struct rte_pci_device *pci_dev)
+{
+	int ret = -1;
+
+	/* only use virtio devices if bound on a supported or no driver
+	 * backport of b8eb3453 "pci: ignore devices already managed in Linux
+	 * when mapping x86"
+	 * Fixes (LP #1570195) and avoids various workarounds and warnings
+	 * that formerly were needed */
+	switch (pci_dev->kdrv) {
+#ifdef VFIO_PRESENT
+	case RTE_KDRV_VFIO:
+#endif
+	case RTE_KDRV_IGB_UIO:
+	case RTE_KDRV_UIO_GENERIC:
+	case RTE_KDRV_NONE:
+		ret = 1;
+		break;
+	default:
+		RTE_LOG(ERR, PMD, "device not available for DPDK"
+			" (in use by kernel)\n");
+		ret = -1;
+	break;
+	}
+
+	return ret;
+}
+
 /*
  * Process Virtio Config changed interrupt and call the callback
  * if link state changed.
@@ -1289,6 +1317,9 @@ eth_virtio_dev_init(struct rte_eth_dev *
 
 	pci_dev = eth_dev->pci_dev;
 
+	if (virtio_resource_available(pci_dev) < 0)
+		return -1;
+
 	if (virtio_resource_init(pci_dev) < 0)
 		return -1;
 
