aboutsummaryrefslogtreecommitdiff
path: root/lib/pci.c
diff options
context:
space:
mode:
authorJohn Levon <john.levon@nutanix.com>2021-01-04 17:53:10 +0000
committerGitHub <noreply@github.com>2021-01-04 17:53:10 +0000
commit1fa90d5abecd896362e551b2bd2ec987d8f60a6b (patch)
tree6bcb22c92d2bf52c1baf6786a644d4abbbd09604 /lib/pci.c
parent715b7963312002980b9eea5a695719cfdf2bf6e4 (diff)
downloadlibvfio-user-1fa90d5abecd896362e551b2bd2ec987d8f60a6b.zip
libvfio-user-1fa90d5abecd896362e551b2bd2ec987d8f60a6b.tar.gz
libvfio-user-1fa90d5abecd896362e551b2bd2ec987d8f60a6b.tar.bz2
re-work PCI config setup API (#198)
Split up vfu_pci_setup_config_hdr(): individual "helpers" like vfu_pci_set_id() are much simpler to use than making the user specify the values in header-formatted structs; and this way if we want to add additional helpers, we won't need to modify the existing functions. Signed-off-by: John Levon <john.levon@nutanix.com> Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib/pci.c')
-rw-r--r--lib/pci.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/lib/pci.c b/lib/pci.c
index f28e7b0..01b8a27 100644
--- a/lib/pci.c
+++ b/lib/pci.c
@@ -339,27 +339,15 @@ pci_config_space_access(vfu_ctx_t *vfu_ctx, char *buf, size_t count,
}
int
-vfu_pci_setup_config_hdr(vfu_ctx_t *vfu_ctx, vfu_pci_hdr_id_t id,
- vfu_pci_hdr_ss_t ss, vfu_pci_hdr_cc_t cc,
- vfu_pci_type_t pci_type,
- int revision __attribute__((unused)))
+vfu_pci_init(vfu_ctx_t *vfu_ctx, vfu_pci_type_t pci_type,
+ int hdr_type, int revision UNUSED)
{
vfu_pci_config_space_t *config_space;
size_t size;
assert(vfu_ctx != NULL);
- /*
- * TODO there no real reason why we shouldn't allow this, we should just
- * clean up and redo it.
- */
- if (vfu_ctx->pci.config_space != NULL) {
- vfu_log(vfu_ctx, LOG_ERR, "PCI configuration space header already setup");
- return ERROR(EEXIST);
- }
-
- vfu_ctx->pci.type = pci_type;
- switch (vfu_ctx->pci.type) {
+ switch (pci_type) {
case VFU_PCI_TYPE_CONVENTIONAL:
case VFU_PCI_TYPE_PCI_X_1:
size = PCI_CFG_SPACE_SIZE;
@@ -369,25 +357,56 @@ vfu_pci_setup_config_hdr(vfu_ctx_t *vfu_ctx, vfu_pci_hdr_id_t id,
size = PCI_CFG_SPACE_EXP_SIZE;
break;
default:
- vfu_log(vfu_ctx, LOG_ERR, "invalid PCI type %d", pci_type);
+ vfu_log(vfu_ctx, LOG_ERR, "invalid PCI type %u", pci_type);
return ERROR(EINVAL);
}
+ if (hdr_type != PCI_HEADER_TYPE_NORMAL) {
+ vfu_log(vfu_ctx, LOG_ERR, "invalid PCI header type %d", hdr_type);
+ return ERROR(EINVAL);
+ }
+
+ /*
+ * TODO there no real reason why we shouldn't allow this, we should just
+ * clean up and redo it.
+ */
+ if (vfu_ctx->pci.config_space != NULL) {
+ vfu_log(vfu_ctx, LOG_ERR,
+ "PCI configuration space header already setup");
+ return ERROR(EEXIST);
+ }
+
// Allocate a buffer for the config space.
config_space = calloc(1, size);
if (config_space == NULL) {
return ERROR(ENOMEM);
}
- config_space->hdr.id = id;
- config_space->hdr.ss = ss;
- config_space->hdr.cc = cc;
+ vfu_ctx->pci.type = pci_type;
vfu_ctx->pci.config_space = config_space;
vfu_ctx->reg_info[VFU_PCI_DEV_CFG_REGION_IDX].size = size;
return 0;
}
+void
+vfu_pci_set_id(vfu_ctx_t *vfu_ctx, uint16_t vid, uint16_t did,
+ uint16_t ssvid, uint16_t ssid)
+{
+ vfu_ctx->pci.config_space->hdr.id.vid = vid;
+ vfu_ctx->pci.config_space->hdr.id.did = did;
+ vfu_ctx->pci.config_space->hdr.ss.vid = ssvid;
+ vfu_ctx->pci.config_space->hdr.ss.sid = ssid;
+}
+
+void
+vfu_pci_set_class(vfu_ctx_t *vfu_ctx, uint8_t base, uint8_t sub, uint8_t pi)
+{
+ vfu_ctx->pci.config_space->hdr.cc.bcc = base;
+ vfu_ctx->pci.config_space->hdr.cc.scc = sub;
+ vfu_ctx->pci.config_space->hdr.cc.pi = pi;
+}
+
int
vfu_pci_setup_caps(vfu_ctx_t *vfu_ctx, vfu_cap_t **caps, int nr_caps)
{