From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <benjamin.walker@intel.com>
Received: from mga07.intel.com (mga07.intel.com [134.134.136.100])
 by dpdk.org (Postfix) with ESMTP id 7DF9EFA83
 for <dev@dpdk.org>; Thu,  9 Feb 2017 18:00:06 +0100 (CET)
Received: from orsmga001.jf.intel.com ([10.7.209.18])
 by orsmga105.jf.intel.com with ESMTP; 09 Feb 2017 09:00:05 -0800
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.35,137,1484035200"; d="scan'208";a="1092813762"
Received: from bwalker-desk.ch.intel.com ([143.182.136.68])
 by orsmga001.jf.intel.com with ESMTP; 09 Feb 2017 09:00:03 -0800
From: Ben Walker <benjamin.walker@intel.com>
To: dev@dpdk.org
Cc: Ben Walker <benjamin.walker@intel.com>
Date: Thu,  9 Feb 2017 09:59:57 -0700
Message-Id: <20170209165959.28082-1-benjamin.walker@intel.com>
X-Mailer: git-send-email 2.9.3
In-Reply-To: <1479931644-78960-4-git-send-email-benjamin.walker@intel.com>
References: <1479931644-78960-4-git-send-email-benjamin.walker@intel.com>
Subject: [dpdk-dev] [PATCH v3 1/3] pci: rte_eal_pci_scan now handles removal
	of PCI devices
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <http://dpdk.org/ml/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://dpdk.org/ml/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <http://dpdk.org/ml/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Thu, 09 Feb 2017 17:00:06 -0000

rte_eal_pci_scan can be called repeatedly to re-scan the PCI
bus. If a device was removed from the system, the associated
driver will automatically be unloaded.

Signed-off-by: Ben Walker <benjamin.walker@intel.com>
---

Only code style changes compared to last submission. It is also rebased
onto the latest from master, which had no conflicts.

 lib/librte_eal/linuxapp/eal/eal_pci.c | 70 +++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index e2fc219..2eed405 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -446,7 +446,77 @@ rte_eal_pci_scan(void)
 	DIR *dir;
 	char dirname[PATH_MAX];
 	struct rte_pci_addr addr;
+	struct rte_pci_device *dev, *tmp;
+
+	/* Search the device list for devices that are no longer present
+	 * on the system and remove them.
+	 */
+	TAILQ_FOREACH_SAFE(dev, &pci_device_list, next, tmp) {
+		int found = 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;
+
+			if (rte_eal_compare_pci_addr(&addr, &dev->addr) == 0) {
+				found = 1;
+				break;
+			}
+		}
+
+		if (!found) {
+
+			RTE_LOG(DEBUG, EAL,
+				"PCI device "PCI_PRI_FMT" was removed.\n",
+				addr.domain, addr.bus, addr.devid,
+				addr.function);
+
+			if (dev->driver) {
+				/* A driver was loaded against this device.
+				 * Unload it.
+				 */
+				RTE_LOG(DEBUG, EAL,
+					"  Unload driver: %x:%x %s\n",
+					dev->id.vendor_id, dev->id.device_id,
+					dev->driver->driver.name);
+
+				if (dev->driver->remove) {
+					/* It doesn't matter what remove
+					 * returns - we're removing the
+					 * device either way.
+					 */
+					dev->driver->remove(dev);
+				}
+
+				/* clear driver structure */
+				dev->driver = NULL;
+
+				if (dev->driver->drv_flags &
+				    RTE_PCI_DRV_NEED_MAPPING)
+					rte_eal_pci_unmap_device(dev);
+			}
+
+			TAILQ_REMOVE(&pci_device_list, dev, next);
+			free(dev);
+		}
+
+		closedir(dir);
+	}
 
+	/* Search sysfs for all PCI devices and add them to the
+	 * device list
+	 */
 	dir = opendir(pci_get_sysfs_path());
 	if (dir == NULL) {
 		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
-- 
2.9.3