From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ben Walker Subject: [PATCH 4/7] pci: rte_eal_pci_scan now handles removal of PCI devices Date: Wed, 23 Nov 2016 12:36:41 -0700 Message-ID: <1479929804-19614-5-git-send-email-benjamin.walker@intel.com> References: <1479929804-19614-1-git-send-email-benjamin.walker@intel.com> Cc: Ben Walker To: dev@dpdk.org Return-path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id D422F5598 for ; Wed, 23 Nov 2016 20:36:49 +0100 (CET) In-Reply-To: <1479929804-19614-1-git-send-email-benjamin.walker@intel.com> List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- lib/librte_eal/linuxapp/eal/eal_pci.c | 58 +++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c index 073af5f..f237864 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c @@ -485,7 +485,65 @@ 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 from the system.\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.7.4