From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by dpdk.org (Postfix) with ESMTP id 7DF9EFA83 for ; 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 To: dev@dpdk.org Cc: Ben Walker 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-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 --- 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