Signed-off-by: Shivaprasad G Bhat <sbhat(a)linux.vnet.ibm.com>
---
src/libvirt_private.syms | 1 +
src/node_device/node_device_udev.c | 2 +-
src/util/virhostdev.c | 2 +-
src/util/virpci.c | 20 ++++++++++++++++++--
src/util/virpci.h | 3 ++-
5 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e1bdaa127e..53e174a223 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2462,6 +2462,7 @@ virPCIDeviceGetUnbindFromStub;
virPCIDeviceGetUsedBy;
virPCIDeviceHasPCIExpressLink;
virPCIDeviceIsAssignable;
+virPCIDeviceIsMultifunction;
virPCIDeviceIsPCIExpress;
virPCIDeviceListAdd;
virPCIDeviceListAddCopy;
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index e87eb32a85..99b936bb5c 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -455,7 +455,7 @@ udevProcessPCI(struct udev_device *device,
/* We need to be root to read PCI device configs */
if (privileged) {
- if (virPCIGetHeaderType(pciDev, &pci_dev->hdrType) < 0)
+ if (virPCIGetHeaderType(pciDev, &pci_dev->hdrType, NULL) < 0)
goto cleanup;
if (virPCIDeviceIsPCIExpress(pciDev) > 0) {
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index e0133cdeec..807caf567a 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -693,7 +693,7 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr mgr,
struct virHostdevIsPCINodeDeviceUsedData data = { mgr, dom_name, usesVFIO };
int hdrType = -1;
- if (virPCIGetHeaderType(pci, &hdrType) < 0)
+ if (virPCIGetHeaderType(pci, &hdrType, NULL) < 0)
goto cleanup;
if (hdrType != VIR_PCI_HEADER_ENDPOINT) {
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 55e4c3e492..a827b3bc0f 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -936,7 +936,7 @@ virPCIDeviceReset(virPCIDevicePtr dev,
int fd = -1;
int hdrType = -1;
- if (virPCIGetHeaderType(dev, &hdrType) < 0)
+ if (virPCIGetHeaderType(dev, &hdrType, NULL) < 0)
return -1;
if (hdrType != VIR_PCI_HEADER_ENDPOINT) {
@@ -3169,6 +3169,18 @@ virPCIGetMdevTypes(const char *sysfspath ATTRIBUTE_UNUSED,
}
#endif /* __linux__ */
+bool
+virPCIDeviceIsMultifunction(virPCIDevicePtr dev)
+{
+ bool multifunction = false;
+ int hdrType = -1;
+
+ if (virPCIGetHeaderType(dev, &hdrType, &multifunction) < 0)
+ return false;
+
+ return multifunction;
+}
+
int
virPCIDeviceIsPCIExpress(virPCIDevicePtr dev)
{
@@ -3254,10 +3266,11 @@ virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev,
}
-int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType)
+int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType, bool *multiFunc)
{
int fd;
uint8_t type;
+ bool multi = false;
*hdrType = -1;
@@ -3268,6 +3281,7 @@ int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType)
virPCIDeviceConfigClose(dev, fd);
+ multi = type & PCI_HEADER_TYPE_MULTI;
type &= PCI_HEADER_TYPE_MASK;
if (type >= VIR_PCI_HEADER_LAST) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -3276,6 +3290,8 @@ int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType)
}
*hdrType = type;
+ if (multiFunc)
+ *multiFunc = multi;
return 0;
}
diff --git a/src/util/virpci.h b/src/util/virpci.h
index 794b7e59db..179249677a 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -199,6 +199,7 @@ int virPCIGetVirtualFunctions(const char *sysfs_path,
size_t *num_virtual_functions,
unsigned int *max_virtual_functions);
+bool virPCIDeviceIsMultifunction(virPCIDevicePtr dev);
int virPCIIsVirtualFunction(const char *vf_sysfs_device_link);
int virPCIGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
@@ -246,7 +247,7 @@ int virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev,
unsigned int *sta_speed,
unsigned int *sta_width);
-int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType);
+int virPCIGetHeaderType(virPCIDevicePtr dev, int *hdrType, bool *multiFunc);
void virPCIEDeviceInfoFree(virPCIEDeviceInfoPtr dev);