pci: Add helper functions for sriov devices

This patch adds the following helper functions:
pciDeviceIsVirtualFunction: Function to check if a pci device is a sriov VF
pciGetVirtualFunctionIndex: Function to get the VF index of a sriov VF
pciDeviceNetName: Function to get the network device name of a pci device
pciConfigAddressCompare: Function to compare pci config addresses

Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
This commit is contained in:
Roopa Prabhu 2011-08-15 21:28:48 -07:00 committed by Stefan Berger
parent 03172265d3
commit 17d64cab16
2 changed files with 154 additions and 0 deletions

View File

@ -1685,6 +1685,19 @@ int pciDeviceIsAssignable(pciDevice *dev,
return 1;
}
/*
* returns 1 if equal and 0 if not
*/
static int
pciConfigAddressEqual(struct pci_config_address *bdf1,
struct pci_config_address *bdf2)
{
return ((bdf1->domain == bdf2->domain) &&
(bdf1->bus == bdf2->bus) &&
(bdf1->slot == bdf2->slot) &&
(bdf1->function == bdf2->function));
}
static int
logStrToLong_ui(char const *s,
char **end_ptr,
@ -1889,6 +1902,112 @@ out:
return ret;
}
/*
* Returns 1 if vf device is a virtual function, 0 if not, -1 on error
*/
int
pciDeviceIsVirtualFunction(const char *vf_sysfs_device_link)
{
char *vf_sysfs_physfn_link = NULL;
int ret = -1;
if (virAsprintf(&vf_sysfs_physfn_link, "%s/physfn",
vf_sysfs_device_link) < 0) {
virReportOOMError();
return ret;
}
ret = virFileExists(vf_sysfs_physfn_link);
VIR_FREE(vf_sysfs_physfn_link);
return ret;
}
/*
* Returns the sriov virtual function index of vf given its pf
*/
int
pciGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
const char *vf_sysfs_device_link,
int *vf_index)
{
int ret = -1, i;
unsigned int num_virt_fns = 0;
struct pci_config_address *vf_bdf = NULL;
struct pci_config_address **virt_fns = NULL;
if (pciGetPciConfigAddressFromSysfsDeviceLink(vf_sysfs_device_link,
&vf_bdf))
return ret;
if (pciGetVirtualFunctions(pf_sysfs_device_link, &virt_fns,
&num_virt_fns)) {
pciReportError(VIR_ERR_INTERNAL_ERROR,
_("Error getting physical function's '%s' "
"virtual_functions"), pf_sysfs_device_link);
goto out;
}
for (i = 0; i < num_virt_fns; i++) {
if (pciConfigAddressEqual(vf_bdf, virt_fns[i])) {
*vf_index = i;
ret = 0;
break;
}
}
out:
/* free virtual functions */
for (i = 0; i < num_virt_fns; i++)
VIR_FREE(virt_fns[i]);
VIR_FREE(vf_bdf);
return ret;
}
/*
* Returns the network device name of a pci device
*/
int
pciDeviceNetName(char *device_link_sysfs_path, char **netname)
{
char *pcidev_sysfs_net_path = NULL;
int ret = -1;
DIR *dir = NULL;
struct dirent *entry = NULL;
if (virBuildPath(&pcidev_sysfs_net_path, device_link_sysfs_path,
"net") == -1) {
virReportOOMError();
return -1;
}
dir = opendir(pcidev_sysfs_net_path);
if (dir == NULL)
goto out;
while ((entry = readdir(dir))) {
if (STREQ(entry->d_name, ".") ||
STREQ(entry->d_name, ".."))
continue;
/* Assume a single directory entry */
*netname = strdup(entry->d_name);
ret = 0;
break;
}
closedir(dir);
out:
VIR_FREE(pcidev_sysfs_net_path);
return ret;
}
#else
int
pciGetPhysicalFunction(const char *vf_sysfs_path,
@ -1908,4 +2027,31 @@ pciGetVirtualFunctions(const char *sysfs_path,
"supported on non-linux platforms"));
return -1;
}
int
pciDeviceIsVirtualFunction(const char *vf_sysfs_device_link)
{
pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciDeviceIsVirtualFunction is "
"not supported on non-linux platforms"));
return -1;
}
int
pciGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
const char *vf_sysfs_device_link,
int *vf_index)
{
pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciGetVirtualFunctionIndex is "
"not supported on non-linux platforms"));
return -1;
}
int
pciDeviceNetName(char *device_link_sysfs_path, char **netname)
{
pciReportError(VIR_ERR_INTERNAL_ERROR, _("pciDeviceNetName is not "
"supported on non-linux platforms"));
return -1;
}
#endif /* __linux__ */

View File

@ -88,4 +88,12 @@ int pciGetVirtualFunctions(const char *sysfs_path,
struct pci_config_address ***virtual_functions,
unsigned int *num_virtual_functions);
int pciDeviceIsVirtualFunction(const char *vf_sysfs_device_link);
int pciGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
const char *vf_sysfs_device_link,
int *vf_index);
int pciDeviceNetName(char *device_link_sysfs_path, char **netname);
#endif /* __VIR_PCI_H__ */