From mboxrd@z Thu Jan 1 00:00:00 1970 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) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 23 Nov 2016 11:36:47 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,539,1473145200"; d="scan'208";a="1072691979" Received: from bwalker-desk.ch.intel.com ([143.182.137.60]) by fmsmga001.fm.intel.com with ESMTP; 23 Nov 2016 11:36:47 -0800 From: Ben Walker To: dev@dpdk.org Cc: Ben Walker Date: Wed, 23 Nov 2016 12:36:41 -0700 Message-Id: <1479929804-19614-5-git-send-email-benjamin.walker@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1479929804-19614-1-git-send-email-benjamin.walker@intel.com> References: <1479929804-19614-1-git-send-email-benjamin.walker@intel.com> Subject: [dpdk-dev] [PATCH 4/7] 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: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Nov 2016 19:36:50 -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 --- 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