From fceb072b09d27f10c7cf74dc901b1a30d2913ad0 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Mon, 11 Jan 2016 15:49:17 -0700 Subject: [PATCH] pci: refactor Linux pci_device_has_non_uio_driver() Use /sys/bus/pci/devices/.../driver to determine which driver is loaded for a particular device. Change-Id: I5859a776e524033e1c6d6ec3796b7e11bdcf0bc4 Signed-off-by: Daniel Verkamp --- lib/util/pci.c | 55 +++++++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/lib/util/pci.c b/lib/util/pci.c index 12c5989cf..9dc39ecfe 100644 --- a/lib/util/pci.c +++ b/lib/util/pci.c @@ -96,39 +96,36 @@ pci_device_get_serial_number(struct pci_device *dev, char *sn, int len) } #ifdef __linux__ -static int -pci_device_has_uio_driver(struct pci_device *dev) +int +pci_device_has_non_uio_driver(struct pci_device *dev) { - struct dirent *e; - DIR *dir; - char dirname[SPDK_PCI_PATH_MAX]; + char linkname[SPDK_PCI_PATH_MAX]; + char driver[SPDK_PCI_PATH_MAX]; + ssize_t driver_len; + char *driver_begin; - snprintf(dirname, sizeof(dirname), - SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/uio", + snprintf(linkname, sizeof(linkname), + SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/driver", dev->domain, dev->bus, dev->dev, dev->func); - dir = opendir(dirname); - if (!dir) { - snprintf(dirname, sizeof(dirname), - SYSFS_PCI_DEVICES "/" PCI_PRI_FMT, - dev->domain, dev->bus, dev->dev, dev->func); - dir = opendir(dirname); - if (!dir) - return 0; - } + driver_len = readlink(linkname, driver, sizeof(driver)); - while ((e = readdir(dir)) != NULL) { - if (strncmp(e->d_name, "uio", 3) == 0) { - break; - } - } - - closedir(dir); - - if (!e) + if (driver_len < 0 || driver_len >= SPDK_PCI_PATH_MAX) { return 0; + } - return 1; + driver[driver_len] = '\0'; /* readlink() doesn't null terminate, so we have to */ + + driver_begin = strrchr(driver, '/'); + if (driver_begin) { + /* Advance to the character after the slash */ + driver_begin++; + } else { + /* This shouldn't normally happen - driver should be a relative path with slashes */ + driver_begin = driver; + } + + return strcmp(driver_begin, "uio_pci_generic") != 0; } #endif @@ -183,12 +180,6 @@ pci_device_has_non_uio_driver(struct pci_device *dev) return 1; } } -#else -int -pci_device_has_non_uio_driver(struct pci_device *dev) -{ - return pci_device_has_kernel_driver(dev) && !pci_device_has_uio_driver(dev); -} #endif int