Add pci_device_has_non_null_driver().

This helps enable FreeBSD, where pciaccess pci_device_has_kernel_driver()
is not functional.  The function will return 0 if there is no driver
attached, or the Linux uio or FreeBSD nic_uio driver is attached.  It will
return 1 otherwise.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: I0921e61c9040b1e0411b5dc40b36fc7f2721c8c5
This commit is contained in:
Jim Harris 2015-09-25 09:13:02 -07:00
parent ae2c3152c4
commit 4ba47234f3
5 changed files with 70 additions and 9 deletions

View File

@ -467,9 +467,8 @@ int main(int argc, char **argv)
while ((pci_dev = pci_device_next(pci_dev_iter))) { while ((pci_dev = pci_device_next(pci_dev_iter))) {
struct nvme_controller *ctrlr; struct nvme_controller *ctrlr;
if (pci_device_has_kernel_driver(pci_dev) && if (pci_device_has_non_null_driver(pci_dev)) {
!pci_device_has_uio_driver(pci_dev)) { fprintf(stderr, "non-null kernel driver attached to nvme\n");
fprintf(stderr, "non-uio kernel driver attached to nvme\n");
fprintf(stderr, " controller at pci bdf %d:%d:%d\n", fprintf(stderr, " controller at pci bdf %d:%d:%d\n",
pci_dev->bus, pci_dev->dev, pci_dev->func); pci_dev->bus, pci_dev->dev, pci_dev->func);
fprintf(stderr, " skipping...\n"); fprintf(stderr, " skipping...\n");

View File

@ -432,9 +432,8 @@ register_controllers(void)
while ((pci_dev = pci_device_next(pci_dev_iter))) { while ((pci_dev = pci_device_next(pci_dev_iter))) {
struct nvme_controller *ctrlr; struct nvme_controller *ctrlr;
if (pci_device_has_kernel_driver(pci_dev) && if (pci_device_has_non_null_driver(pci_dev)) {
!pci_device_has_uio_driver(pci_dev)) { fprintf(stderr, "non-null kernel driver attached to nvme\n");
fprintf(stderr, "non-uio kernel driver attached to nvme\n");
fprintf(stderr, " controller at pci bdf %d:%d:%d\n", fprintf(stderr, " controller at pci bdf %d:%d:%d\n",
pci_dev->bus, pci_dev->dev, pci_dev->func); pci_dev->bus, pci_dev->dev, pci_dev->func);
fprintf(stderr, " skipping...\n"); fprintf(stderr, " skipping...\n");

View File

@ -40,6 +40,7 @@
int pci_device_get_serial_number(struct pci_device *dev, char *sn, int len); int pci_device_get_serial_number(struct pci_device *dev, char *sn, int len);
int pci_device_has_uio_driver(struct pci_device *dev); int pci_device_has_uio_driver(struct pci_device *dev);
int pci_device_has_non_null_driver(struct pci_device *dev);
int pci_device_unbind_kernel_driver(struct pci_device *dev); int pci_device_unbind_kernel_driver(struct pci_device *dev);
int pci_device_bind_uio_driver(struct pci_device *dev, char *driver_name); int pci_device_bind_uio_driver(struct pci_device *dev, char *driver_name);
int pci_device_switch_to_uio_driver(struct pci_device *pci_dev); int pci_device_switch_to_uio_driver(struct pci_device *pci_dev);

View File

@ -43,6 +43,10 @@
#include <pciaccess.h> #include <pciaccess.h>
#ifdef __FreeBSD__
#include <sys/pciio.h>
#endif
#include "spdk/pci.h" #include "spdk/pci.h"
#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices" #define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
@ -126,6 +130,65 @@ pci_device_has_uio_driver(struct pci_device *dev)
return 1; return 1;
} }
#ifdef __FreeBSD__
int
pci_device_has_non_null_driver(struct pci_device *dev)
{
struct pci_conf_io configsel;
struct pci_match_conf pattern;
struct pci_conf conf;
int fd;
memset(&pattern, 0, sizeof(pattern));
pattern.pc_sel.pc_domain = dev->domain;
pattern.pc_sel.pc_bus = dev->bus;
pattern.pc_sel.pc_dev = dev->dev;
pattern.pc_sel.pc_func = dev->func;
pattern.flags = PCI_GETCONF_MATCH_DOMAIN |
PCI_GETCONF_MATCH_BUS |
PCI_GETCONF_MATCH_DEV |
PCI_GETCONF_MATCH_FUNC;
memset(&configsel, 0, sizeof(configsel));
configsel.match_buf_len = sizeof(conf);
configsel.matches = &conf;
configsel.num_patterns = 1;
configsel.pat_buf_len = sizeof(pattern);
configsel.patterns = &pattern;
fd = open("/dev/pci", O_RDONLY, 0);
if (fd < 0) {
fprintf(stderr, "could not open /dev/pci\n");
return -1;
}
if (ioctl(fd, PCIOCGETCONF, &configsel) == -1) {
fprintf(stderr, "ioctl(PCIOCGETCONF) failed\n");
close(fd);
return -1;
}
close(fd);
if (configsel.num_matches != 1) {
fprintf(stderr, "could not find specified device\n");
return -1;
}
if (conf.pd_name[0] == '\0' || !strcmp(conf.pd_name, "nic_uio")) {
return 0;
} else {
return 1;
}
}
#else
int
pci_device_has_non_null_driver(struct pci_device *dev)
{
return pci_device_has_kernel_driver(dev) && !pci_device_has_uio_driver(dev);
}
#endif
int int
pci_device_unbind_kernel_driver(struct pci_device *dev) pci_device_unbind_kernel_driver(struct pci_device *dev)
{ {

View File

@ -225,9 +225,8 @@ int main(int argc, char **argv)
while ((pci_dev = pci_device_next(pci_dev_iter))) { while ((pci_dev = pci_device_next(pci_dev_iter))) {
struct dev *dev; struct dev *dev;
if (pci_device_has_kernel_driver(pci_dev) && if (pci_device_has_non_null_driver(pci_dev)) {
!pci_device_has_uio_driver(pci_dev)) { fprintf(stderr, "non-null kernel driver attached to nvme\n");
fprintf(stderr, "non-uio kernel driver attached to nvme\n");
fprintf(stderr, " controller at pci bdf %d:%d:%d\n", fprintf(stderr, " controller at pci bdf %d:%d:%d\n",
pci_dev->bus, pci_dev->dev, pci_dev->func); pci_dev->bus, pci_dev->dev, pci_dev->func);
fprintf(stderr, " skipping...\n"); fprintf(stderr, " skipping...\n");