vlib: retrieve the root bus of a given pci device
Added a function to parse sysfs, determine the root bus & domain of a given pci device. Type: improvement Signed-off-by: Ray Kinsella <mdr@ashroe.eu> Change-Id: I36778116ecaa2d591617450fe5ae0bdb46b4424b
This commit is contained in:

committed by
Damjan Marion

parent
6efe025ce5
commit
5714a49f14
@ -55,6 +55,7 @@
|
|||||||
#include <linux/vfio.h>
|
#include <linux/vfio.h>
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
|
|
||||||
|
#define SYSFS_DEVICES_PCI "/sys/devices/pci"
|
||||||
static const char *sysfs_pci_dev_path = "/sys/bus/pci/devices";
|
static const char *sysfs_pci_dev_path = "/sys/bus/pci/devices";
|
||||||
static const char *sysfs_pci_drv_path = "/sys/bus/pci/drivers";
|
static const char *sysfs_pci_drv_path = "/sys/bus/pci/drivers";
|
||||||
static char *sysfs_mod_vfio_noiommu =
|
static char *sysfs_mod_vfio_noiommu =
|
||||||
@ -383,6 +384,64 @@ done:
|
|||||||
return di;
|
return di;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clib_error_t *__attribute__ ((weak))
|
||||||
|
vlib_pci_get_device_root_bus (vlib_pci_addr_t *addr, vlib_pci_addr_t *root_bus)
|
||||||
|
{
|
||||||
|
u8 *rel_path = 0, *abs_path = 0, *link_path = 0;
|
||||||
|
unformat_input_t input;
|
||||||
|
u32 fd = open (sysfs_pci_dev_path, O_RDONLY);
|
||||||
|
u32 size = 0;
|
||||||
|
u32 domain = 0, bus;
|
||||||
|
clib_error_t *err = NULL;
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
return clib_error_return_unix (0, "failed to open %s", sysfs_pci_dev_path);
|
||||||
|
|
||||||
|
vec_alloc (rel_path, PATH_MAX);
|
||||||
|
vec_alloc (abs_path, PATH_MAX);
|
||||||
|
|
||||||
|
link_path =
|
||||||
|
format (0, "%s/%U", sysfs_pci_dev_path, format_vlib_pci_addr, addr);
|
||||||
|
size = readlinkat (fd, (char *) link_path, (char *) rel_path, PATH_MAX);
|
||||||
|
if (size < 0)
|
||||||
|
{
|
||||||
|
err = clib_error_return_unix (0, "failed to read %s", rel_path);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
rel_path[size] = '\0';
|
||||||
|
vec_free (link_path);
|
||||||
|
|
||||||
|
link_path = format (0, "%s/%s", sysfs_pci_dev_path, rel_path);
|
||||||
|
if (!realpath ((char *) link_path, (char *) abs_path))
|
||||||
|
{
|
||||||
|
err = clib_error_return_unix (0, "failed to resolve %s", link_path);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
unformat_init_string (&input, (char *) abs_path,
|
||||||
|
clib_strnlen ((char *) abs_path, PATH_MAX));
|
||||||
|
|
||||||
|
if (!unformat (&input, SYSFS_DEVICES_PCI "%x:%x/%s", &domain, &bus,
|
||||||
|
link_path))
|
||||||
|
{
|
||||||
|
err = clib_error_return (0, "unknown input '%U'", format_unformat_error,
|
||||||
|
input);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
root_bus->domain = domain;
|
||||||
|
root_bus->bus = bus;
|
||||||
|
|
||||||
|
done:
|
||||||
|
vec_free (abs_path);
|
||||||
|
vec_free (link_path);
|
||||||
|
vec_free (rel_path);
|
||||||
|
close (fd);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
directory_exists (char *path)
|
directory_exists (char *path)
|
||||||
{
|
{
|
||||||
|
@ -61,6 +61,12 @@ vlib_pci_get_device_info (vlib_main_t * vm, vlib_pci_addr_t * addr,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clib_error_t *__attribute__ ((weak))
|
||||||
|
vlib_pci_get_device_root_bus (vlib_pci_addr_t *addr, vlib_pci_addr_t *root_bus)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
vlib_pci_addr_t * __attribute__ ((weak)) vlib_pci_get_all_dev_addrs ()
|
vlib_pci_addr_t * __attribute__ ((weak)) vlib_pci_get_all_dev_addrs ()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -96,9 +96,11 @@ typedef struct vlib_pci_device_info
|
|||||||
|
|
||||||
typedef u32 vlib_pci_dev_handle_t;
|
typedef u32 vlib_pci_dev_handle_t;
|
||||||
|
|
||||||
vlib_pci_device_info_t *vlib_pci_get_device_info (vlib_main_t * vm,
|
vlib_pci_device_info_t *vlib_pci_get_device_info (vlib_main_t *vm,
|
||||||
vlib_pci_addr_t * addr,
|
vlib_pci_addr_t *addr,
|
||||||
clib_error_t ** error);
|
clib_error_t **error);
|
||||||
|
clib_error_t *vlib_pci_get_device_root_bus (vlib_pci_addr_t *addr,
|
||||||
|
vlib_pci_addr_t *root_bus);
|
||||||
vlib_pci_addr_t *vlib_pci_get_all_dev_addrs ();
|
vlib_pci_addr_t *vlib_pci_get_all_dev_addrs ();
|
||||||
vlib_pci_addr_t *vlib_pci_get_addr (vlib_main_t * vm,
|
vlib_pci_addr_t *vlib_pci_get_addr (vlib_main_t * vm,
|
||||||
vlib_pci_dev_handle_t h);
|
vlib_pci_dev_handle_t h);
|
||||||
|
Reference in New Issue
Block a user