diff options
Diffstat (limited to 'src/vlib')
-rw-r--r-- | src/vlib/linux/pci.c | 124 | ||||
-rw-r--r-- | src/vlib/pci/pci.h | 4 |
2 files changed, 66 insertions, 62 deletions
diff --git a/src/vlib/linux/pci.c b/src/vlib/linux/pci.c index 9f0629f46bc..83e9dde2f16 100644 --- a/src/vlib/linux/pci.c +++ b/src/vlib/linux/pci.c @@ -453,8 +453,8 @@ directory_exists (char *path) } clib_error_t * -vlib_pci_bind_to_uio (vlib_main_t * vm, vlib_pci_addr_t * addr, - char *uio_drv_name) +vlib_pci_bind_to_uio (vlib_main_t *vm, vlib_pci_addr_t *addr, + char *uio_drv_name, int force) { clib_error_t *error = 0; u8 *s = 0, *driver_name = 0; @@ -523,76 +523,80 @@ vlib_pci_bind_to_uio (vlib_main_t * vm, vlib_pci_addr_t * addr, (strcmp ("igb_uio", (char *) driver_name) == 0))) goto done; - /* walk trough all linux interfaces and if interface belonging to - this device is founf check if interface is admin up */ - dir = opendir ("/sys/class/net"); - s = format (s, "%U%c", format_vlib_pci_addr, addr, 0); - - if (!dir) - { - error = clib_error_return (0, "Skipping PCI device %U: failed to " - "read /sys/class/net", - format_vlib_pci_addr, addr); - goto done; - } - - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd < 0) - { - error = clib_error_return_unix (0, "socket"); - goto done; - } - - while ((e = readdir (dir))) + if (!force) { - struct ifreq ifr; - struct ethtool_drvinfo drvinfo; + /* walk trough all linux interfaces and if interface belonging to + this device is found check if interface is admin up */ + dir = opendir ("/sys/class/net"); + s = format (s, "%U%c", format_vlib_pci_addr, addr, 0); - if (e->d_name[0] == '.') /* skip . and .. */ - continue; - - clib_memset (&ifr, 0, sizeof ifr); - clib_memset (&drvinfo, 0, sizeof drvinfo); - ifr.ifr_data = (char *) &drvinfo; - clib_strncpy (ifr.ifr_name, e->d_name, sizeof (ifr.ifr_name) - 1); - - drvinfo.cmd = ETHTOOL_GDRVINFO; - if (ioctl (fd, SIOCETHTOOL, &ifr) < 0) + if (!dir) { - /* Some interfaces (eg "lo") don't support this ioctl */ - if ((errno != ENOTSUP) && (errno != ENODEV)) - clib_unix_warning ("ioctl fetch intf %s bus info error", - e->d_name); - continue; + error = clib_error_return (0, + "Skipping PCI device %U: failed to " + "read /sys/class/net", + format_vlib_pci_addr, addr); + goto done; } - if (strcmp ((char *) s, drvinfo.bus_info)) - continue; - - clib_memset (&ifr, 0, sizeof (ifr)); - clib_strncpy (ifr.ifr_name, e->d_name, sizeof (ifr.ifr_name) - 1); - - if (ioctl (fd, SIOCGIFFLAGS, &ifr) < 0) + fd = socket (PF_INET, SOCK_DGRAM, 0); + if (fd < 0) { - error = clib_error_return_unix (0, "ioctl fetch intf %s flags", - e->d_name); - close (fd); + error = clib_error_return_unix (0, "socket"); goto done; } - if (ifr.ifr_flags & IFF_UP) + while ((e = readdir (dir))) { - vlib_log (VLIB_LOG_LEVEL_WARNING, pci_main.log_default, - "Skipping PCI device %U as host " - "interface %s is up", format_vlib_pci_addr, addr, - e->d_name); - close (fd); - goto done; + struct ifreq ifr; + struct ethtool_drvinfo drvinfo; + + if (e->d_name[0] == '.') /* skip . and .. */ + continue; + + clib_memset (&ifr, 0, sizeof ifr); + clib_memset (&drvinfo, 0, sizeof drvinfo); + ifr.ifr_data = (char *) &drvinfo; + clib_strncpy (ifr.ifr_name, e->d_name, sizeof (ifr.ifr_name) - 1); + + drvinfo.cmd = ETHTOOL_GDRVINFO; + if (ioctl (fd, SIOCETHTOOL, &ifr) < 0) + { + /* Some interfaces (eg "lo") don't support this ioctl */ + if ((errno != ENOTSUP) && (errno != ENODEV)) + clib_unix_warning ("ioctl fetch intf %s bus info error", + e->d_name); + continue; + } + + if (strcmp ((char *) s, drvinfo.bus_info)) + continue; + + clib_memset (&ifr, 0, sizeof (ifr)); + clib_strncpy (ifr.ifr_name, e->d_name, sizeof (ifr.ifr_name) - 1); + + if (ioctl (fd, SIOCGIFFLAGS, &ifr) < 0) + { + error = clib_error_return_unix (0, "ioctl fetch intf %s flags", + e->d_name); + close (fd); + goto done; + } + + if (ifr.ifr_flags & IFF_UP) + { + vlib_log (VLIB_LOG_LEVEL_WARNING, pci_main.log_default, + "Skipping PCI device %U as host " + "interface %s is up", + format_vlib_pci_addr, addr, e->d_name); + close (fd); + goto done; + } } - } - close (fd); - vec_reset_length (s); + close (fd); + vec_reset_length (s); + } s = format (s, "%v/driver/unbind%c", dev_dir_name, 0); clib_sysfs_write ((char *) s, "%U", format_vlib_pci_addr, addr); diff --git a/src/vlib/pci/pci.h b/src/vlib/pci/pci.h index 1dc4ce6ea36..4e9cf4aee9e 100644 --- a/src/vlib/pci/pci.h +++ b/src/vlib/pci/pci.h @@ -182,8 +182,8 @@ static void __vlib_rm_pci_device_registration_##x (void) \ } \ __VA_ARGS__ pci_device_registration_t x -clib_error_t *vlib_pci_bind_to_uio (vlib_main_t * vm, vlib_pci_addr_t * addr, - char *uio_driver_name); +clib_error_t *vlib_pci_bind_to_uio (vlib_main_t *vm, vlib_pci_addr_t *addr, + char *uio_driver_name, int force); /* Configuration space read/write. */ clib_error_t *vlib_pci_read_write_config (vlib_main_t * vm, |