aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pci_caps.c51
1 files changed, 19 insertions, 32 deletions
diff --git a/lib/pci_caps.c b/lib/pci_caps.c
index cd91914..e9dc5ac 100644
--- a/lib/pci_caps.c
+++ b/lib/pci_caps.c
@@ -167,49 +167,36 @@ cap_write_pm(vfu_ctx_t *vfu_ctx, struct pci_cap *cap, char * buf,
}
static ssize_t
-handle_mxc_write(vfu_ctx_t *vfu_ctx, struct msixcap *msix,
- const struct mxc *const mxc)
+cap_write_msix(vfu_ctx_t *vfu_ctx, struct pci_cap *cap, char *buf,
+ size_t count, loff_t offset)
{
- assert(msix != NULL);
- assert(mxc != NULL);
+ struct msixcap *msix = cap_data(vfu_ctx, cap);
+ struct msixcap new_msix = *msix;
- if (mxc->mxe != msix->mxc.mxe) {
- vfu_log(vfu_ctx, LOG_DEBUG, "%s MSI-X",
- mxc->mxe ? "enable" : "disable");
- msix->mxc.mxe = mxc->mxe;
- }
+ memcpy((char *)&new_msix + offset - cap->off, buf, count);
+
+ /*
+ * Same as doing &= (PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE), but
+ * prefer to log what's changing.
+ */
- if (mxc->fm != msix->mxc.fm) {
- if (mxc->fm) {
+ if (msix->mxc.fm != new_msix.mxc.fm) {
+ if (new_msix.mxc.fm) {
vfu_log(vfu_ctx, LOG_DEBUG, "all MSI-X vectors masked");
} else {
vfu_log(vfu_ctx, LOG_DEBUG,
"vector's mask bit determines whether vector is masked");
}
- msix->mxc.fm = mxc->fm;
+ msix->mxc.fm = new_msix.mxc.fm;
}
- return sizeof(struct mxc);
-}
-
-static ssize_t
-cap_write_msix(vfu_ctx_t *vfu_ctx, struct pci_cap *cap, char *buf,
- size_t count, loff_t offset)
-{
- struct msixcap *msix = cap_data(vfu_ctx, cap);
-
- if (count == sizeof(struct mxc)) {
- switch (offset - cap->off) {
- case offsetof(struct msixcap, mxc):
- return handle_mxc_write(vfu_ctx, msix, (struct mxc *)buf);
- default:
- vfu_log(vfu_ctx, LOG_ERR,
- "invalid MSI-X write offset %ld", offset);
- return ERROR_INT(EINVAL);
- }
+ if (msix->mxc.mxe != new_msix.mxc.mxe) {
+ vfu_log(vfu_ctx, LOG_DEBUG, "%s MSI-X",
+ msix->mxc.mxe ? "enable" : "disable");
+ msix->mxc.mxe = new_msix.mxc.mxe;
}
- vfu_log(vfu_ctx, LOG_ERR, "invalid MSI-X write size %lu", count);
- return ERROR_INT(EINVAL);
+
+ return count;
}
static int