diff options
author | John Levon <john.levon@nutanix.com> | 2021-01-20 10:44:49 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-20 10:44:49 +0000 |
commit | 53cc29bc8ca5083b9b6075f151824d65557af6f0 (patch) | |
tree | e7ae6ef44eb87c81f74f1740d0da69614606d247 /samples | |
parent | fa5104150bca4182f8a38d39fa50f7e61982568e (diff) | |
download | libvfio-user-53cc29bc8ca5083b9b6075f151824d65557af6f0.zip libvfio-user-53cc29bc8ca5083b9b6075f151824d65557af6f0.tar.gz libvfio-user-53cc29bc8ca5083b9b6075f151824d65557af6f0.tar.bz2 |
support extended capabilities (#226)
Provide initial support for extended capabilities, and implement handlers for
the Device Serial Number and Vendor-Specific capabilities.
Signed-off-by: John Levon <john.levon@nutanix.com>
Reviewed-by: Swapnil Ingle <swapnil.ingle@nutanix.com>
Diffstat (limited to 'samples')
-rw-r--r-- | samples/lspci.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/samples/lspci.c b/samples/lspci.c index 9484042..358fefe 100644 --- a/samples/lspci.c +++ b/samples/lspci.c @@ -44,7 +44,13 @@ int main(void) char *buf; const int bytes_per_line = 0x10; struct vsc *vsc = alloca(sizeof(*vsc) + 0xd); + struct pcie_ext_cap_vsc_hdr *evsc = alloca(sizeof(*evsc) + 0xd); + struct dsncap dsn = { .hdr.id = PCI_EXT_CAP_ID_DSN, + .sn_lo = 0xdeadbeef, + .sn_hi = 0xcafebabe }; struct pmcap pm = { .hdr.id = PCI_CAP_ID_PM, .pmcs.nsfrst = 0x1 }; + /* Required for lspci to report extended caps. */ + struct pxcap px = { .hdr.id = PCI_CAP_ID_EXP }; vfu_ctx_t *vfu_ctx = vfu_create_ctx(VFU_TRANS_SOCK, "", LIBVFIO_USER_FLAG_ATTACH_NB, NULL, @@ -52,7 +58,7 @@ int main(void) if (vfu_ctx == NULL) { err(EXIT_FAILURE, "failed to create libvfio-user context"); } - if (vfu_pci_init(vfu_ctx, VFU_PCI_TYPE_CONVENTIONAL, + if (vfu_pci_init(vfu_ctx, VFU_PCI_TYPE_EXPRESS, PCI_HEADER_TYPE_NORMAL, 0) < 0) { err(EXIT_FAILURE, "vfu_pci_init() failed"); } @@ -70,12 +76,38 @@ int main(void) err(EXIT_FAILURE, "vfu_pci_add_capability() failed"); } + if (vfu_pci_add_capability(vfu_ctx, 0, 0, &px) < 0) { + err(EXIT_FAILURE, "vfu_pci_add_capability() failed"); + } + + if (vfu_pci_add_capability(vfu_ctx, 0, VFU_CAP_FLAG_EXTENDED, &dsn) < 0) { + err(EXIT_FAILURE, "vfu_pci_add_capability() failed"); + } + + memset(evsc, 0, sizeof(*evsc) + 0xd); + evsc->hdr.id = PCI_EXT_CAP_ID_VNDR; + evsc->id = 1; + evsc->rev = 1; + evsc->len = sizeof(*evsc) + 0xd; + + if (vfu_pci_add_capability(vfu_ctx, 0, VFU_CAP_FLAG_EXTENDED, evsc) < 0) { + err(EXIT_FAILURE, "vfu_pci_add_capability() failed"); + } + + evsc->id = 2; + evsc->rev = 2; + + if (vfu_pci_add_capability(vfu_ctx, 0x400, + VFU_CAP_FLAG_EXTENDED, evsc) < 0) { + err(EXIT_FAILURE, "vfu_pci_add_capability() failed"); + } + if (vfu_realize_ctx(vfu_ctx) < 0) { err(EXIT_FAILURE, "failed to realize device"); } buf = (char*)vfu_pci_get_config_space(vfu_ctx); printf("00:00.0 bogus PCI device\n"); - for (i = 0; i < PCI_CFG_SPACE_SIZE / bytes_per_line; i++) { + for (i = 0; i < PCI_CFG_SPACE_EXP_SIZE / bytes_per_line; i++) { printf("%02x:", i * bytes_per_line); for (j = 0; j < bytes_per_line; j++) { printf(" %02x", buf[i * bytes_per_line + j] & 0xff); |