mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 19:41:16 +00:00
virpci: Introduce virPCIDeviceIsPCIExpress and friends
These functions will handle PCIe devices and their link capabilities to query some info about it. Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
3e3c6ff10f
commit
a22a7a5ef3
@ -1697,6 +1697,7 @@ virPCIDeviceFree;
|
|||||||
virPCIDeviceGetDriverPathAndName;
|
virPCIDeviceGetDriverPathAndName;
|
||||||
virPCIDeviceGetIOMMUGroupDev;
|
virPCIDeviceGetIOMMUGroupDev;
|
||||||
virPCIDeviceGetIOMMUGroupList;
|
virPCIDeviceGetIOMMUGroupList;
|
||||||
|
virPCIDeviceGetLinkCapSta;
|
||||||
virPCIDeviceGetManaged;
|
virPCIDeviceGetManaged;
|
||||||
virPCIDeviceGetName;
|
virPCIDeviceGetName;
|
||||||
virPCIDeviceGetRemoveSlot;
|
virPCIDeviceGetRemoveSlot;
|
||||||
@ -1704,7 +1705,9 @@ virPCIDeviceGetReprobe;
|
|||||||
virPCIDeviceGetStubDriver;
|
virPCIDeviceGetStubDriver;
|
||||||
virPCIDeviceGetUnbindFromStub;
|
virPCIDeviceGetUnbindFromStub;
|
||||||
virPCIDeviceGetUsedBy;
|
virPCIDeviceGetUsedBy;
|
||||||
|
virPCIDeviceHasPCIExpressLink;
|
||||||
virPCIDeviceIsAssignable;
|
virPCIDeviceIsAssignable;
|
||||||
|
virPCIDeviceIsPCIExpress;
|
||||||
virPCIDeviceListAdd;
|
virPCIDeviceListAdd;
|
||||||
virPCIDeviceListAddCopy;
|
virPCIDeviceListAddCopy;
|
||||||
virPCIDeviceListCount;
|
virPCIDeviceListCount;
|
||||||
|
@ -120,6 +120,7 @@ struct _virPCIDeviceList {
|
|||||||
|
|
||||||
/* PCI30 6.7 Capabilities List */
|
/* PCI30 6.7 Capabilities List */
|
||||||
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
|
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
|
||||||
|
#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
|
||||||
|
|
||||||
/* PM12 3.2.1 Capability Identifier */
|
/* PM12 3.2.1 Capability Identifier */
|
||||||
#define PCI_CAP_ID_PM 0x01 /* Power Management */
|
#define PCI_CAP_ID_PM 0x01 /* Power Management */
|
||||||
@ -130,7 +131,13 @@ struct _virPCIDeviceList {
|
|||||||
|
|
||||||
/* PCIe20 7.8.3 Device Capabilities Register (Offset 04h) */
|
/* PCIe20 7.8.3 Device Capabilities Register (Offset 04h) */
|
||||||
#define PCI_EXP_DEVCAP 0x4 /* Device capabilities */
|
#define PCI_EXP_DEVCAP 0x4 /* Device capabilities */
|
||||||
#define PCI_EXP_DEVCAP_FLR (1<<28) /* Function Level Reset */
|
#define PCI_EXP_DEVCAP_FLR (1<<28) /* Function Level Reset */
|
||||||
|
#define PCI_EXP_LNKCAP 0xc /* Link Capabilities */
|
||||||
|
#define PCI_EXP_LNKCAP_SPEED 0x0000f /* Maximum Link Speed */
|
||||||
|
#define PCI_EXP_LNKCAP_WIDTH 0x003f0 /* Maximum Link Width */
|
||||||
|
#define PCI_EXP_LNKSTA 0x12 /* Link Status */
|
||||||
|
#define PCI_EXP_LNKSTA_SPEED 0x000f /* Negotiated Link Speed */
|
||||||
|
#define PCI_EXP_LNKSTA_WIDTH 0x03f0 /* Negotiated Link Width */
|
||||||
|
|
||||||
/* Header type 1 BR12 3.2 PCI-to-PCI Bridge Configuration Space Header Format */
|
/* Header type 1 BR12 3.2 PCI-to-PCI Bridge Configuration Space Header Format */
|
||||||
#define PCI_PRIMARY_BUS 0x18 /* BR12 3.2.5.2 Primary bus number */
|
#define PCI_PRIMARY_BUS 0x18 /* BR12 3.2.5.2 Primary bus number */
|
||||||
@ -173,6 +180,9 @@ struct _virPCIDeviceList {
|
|||||||
PCI_EXT_CAP_ACS_CR | \
|
PCI_EXT_CAP_ACS_CR | \
|
||||||
PCI_EXT_CAP_ACS_UF)
|
PCI_EXT_CAP_ACS_UF)
|
||||||
|
|
||||||
|
#define PCI_EXP_TYPE_ROOT_INT_EP 0x9 /* Root Complex Integrated Endpoint */
|
||||||
|
#define PCI_EXP_TYPE_ROOT_EC 0xa /* Root Complex Event Collector */
|
||||||
|
|
||||||
static virClassPtr virPCIDeviceListClass;
|
static virClassPtr virPCIDeviceListClass;
|
||||||
|
|
||||||
static void virPCIDeviceListDispose(void *obj);
|
static void virPCIDeviceListDispose(void *obj);
|
||||||
@ -2750,3 +2760,87 @@ virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path ATTRIBUTE_UNUSED,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /* __linux__ */
|
#endif /* __linux__ */
|
||||||
|
|
||||||
|
int
|
||||||
|
virPCIDeviceIsPCIExpress(virPCIDevicePtr dev)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if ((fd = virPCIDeviceConfigOpen(dev, true)) < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (virPCIDeviceInit(dev, fd) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = dev->pcie_cap_pos != 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virPCIDeviceConfigClose(dev, fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virPCIDeviceHasPCIExpressLink(virPCIDevicePtr dev)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int ret = -1;
|
||||||
|
uint16_t cap, type;
|
||||||
|
|
||||||
|
if ((fd = virPCIDeviceConfigOpen(dev, true)) < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (virPCIDeviceInit(dev, fd) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
cap = virPCIDeviceRead16(dev, fd, dev->pcie_cap_pos + PCI_CAP_FLAGS);
|
||||||
|
type = (cap & PCI_EXP_FLAGS_TYPE) >> 4;
|
||||||
|
|
||||||
|
ret = type != PCI_EXP_TYPE_ROOT_INT_EP && type != PCI_EXP_TYPE_ROOT_EC;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virPCIDeviceConfigClose(dev, fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev,
|
||||||
|
int *cap_port,
|
||||||
|
unsigned int *cap_speed,
|
||||||
|
unsigned int *cap_width,
|
||||||
|
unsigned int *sta_speed,
|
||||||
|
unsigned int *sta_width)
|
||||||
|
{
|
||||||
|
uint32_t t;
|
||||||
|
int fd;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if ((fd = virPCIDeviceConfigOpen(dev, true)) < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (virPCIDeviceInit(dev, fd) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!dev->pcie_cap_pos) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("pci device %s is not a PCI-Express device"),
|
||||||
|
dev->name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = virPCIDeviceRead32(dev, fd, dev->pcie_cap_pos + PCI_EXP_LNKCAP);
|
||||||
|
|
||||||
|
*cap_port = t >> 24;
|
||||||
|
*cap_speed = t & PCI_EXP_LNKCAP_SPEED;
|
||||||
|
*cap_width = (t & PCI_EXP_LNKCAP_WIDTH) >> 4;
|
||||||
|
|
||||||
|
t = virPCIDeviceRead16(dev, fd, dev->pcie_cap_pos + PCI_EXP_LNKSTA);
|
||||||
|
|
||||||
|
*sta_speed = t & PCI_EXP_LNKSTA_SPEED;
|
||||||
|
*sta_width = (t & PCI_EXP_LNKSTA_WIDTH) >> 4;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virPCIDeviceConfigClose(dev, fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -176,4 +176,12 @@ int virPCIDeviceGetDriverPathAndName(virPCIDevicePtr dev,
|
|||||||
char **path,
|
char **path,
|
||||||
char **name);
|
char **name);
|
||||||
|
|
||||||
|
int virPCIDeviceIsPCIExpress(virPCIDevicePtr dev);
|
||||||
|
int virPCIDeviceHasPCIExpressLink(virPCIDevicePtr dev);
|
||||||
|
int virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev,
|
||||||
|
int *ca_port,
|
||||||
|
unsigned int *cap_speed,
|
||||||
|
unsigned int *cap_width,
|
||||||
|
unsigned int *sta_speed,
|
||||||
|
unsigned int *sta_width);
|
||||||
#endif /* __VIR_PCI_H__ */
|
#endif /* __VIR_PCI_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user