aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/libxl/libxl.c4
-rw-r--r--tools/libxl/libxl_device.c38
-rw-r--r--tools/libxl/libxl_internal.h4
3 files changed, 31 insertions, 15 deletions
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index ebcdb3d040..2563c91cc6 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -2381,7 +2381,7 @@ int libxl_device_pci_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_pci
/* TODO: check if the device can be assigned */
- libxl_device_pci_flr(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+ libxl_device_pci_reset(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
stubdomid = libxl_get_stubdom_id(ctx, domid);
if (stubdomid != 0) {
@@ -2551,7 +2551,7 @@ skip1:
fclose(f);
}
out:
- libxl_device_pci_flr(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+ libxl_device_pci_reset(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
if (!libxl_is_stubdom(ctx, domid, NULL)) {
rc = xc_deassign_device(ctx->xch, domid, pcidev->value);
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index 13563e89d9..89c92db592 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -22,6 +22,8 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <fcntl.h>
+
#include "libxl.h"
#include "libxl_internal.h"
@@ -389,22 +391,36 @@ int libxl_device_del(struct libxl_ctx *ctx, libxl_device *dev, int wait)
return 0;
}
-int libxl_device_pci_flr(struct libxl_ctx *ctx, unsigned int domain, unsigned int bus,
+int libxl_device_pci_reset(struct libxl_ctx *ctx, unsigned int domain, unsigned int bus,
unsigned int dev, unsigned int func)
{
- char *do_flr = "/sys/bus/pci/drivers/pciback/do_flr";
- FILE *fd;
-
- fd = fopen(do_flr, "w");
- if (fd != NULL) {
- fprintf(fd, PCI_BDF, domain, bus, dev, func);
- fclose(fd);
- return 0;
+ char *reset = "/sys/bus/pci/drivers/pciback/do_flr";
+ int fd, rc;
+
+ fd = open(reset, O_WRONLY);
+ if (fd > 0) {
+ char *buf = libxl_sprintf(ctx, PCI_BDF, domain, bus, dev, func);
+ rc = write(fd, buf, strlen(buf));
+ if (rc < 0)
+ XL_LOG(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, rc);
+ close(fd);
+ return rc < 0 ? rc : 0;
+ }
+ if (errno != ENOENT)
+ XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access pciback path %s", reset);
+ reset = libxl_sprintf(ctx, "/sys/bus/pci/devices/"PCI_BDF"/reset", domain, bus, dev, func);
+ fd = open(reset, O_WRONLY);
+ if (fd > 0) {
+ rc = write(fd, "1", 1);
+ if (rc < 0)
+ XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, rc);
+ close(fd);
+ return rc < 0 ? rc : 0;
}
if (errno == ENOENT) {
- XL_LOG(ctx, XL_LOG_ERROR, "Pciback doesn't support do_flr, cannot flr the device");
+ XL_LOG(ctx, XL_LOG_ERROR, "The kernel doesn't support PCI device reset from sysfs");
} else {
- XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access pciback path %s", do_flr);
+ XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access reset path %s", reset);
}
return -1;
}
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 72ffd54a47..29dd2661a3 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -162,8 +162,8 @@ int libxl_wait_for_device_model(struct libxl_ctx *ctx,
void *userdata),
void *check_callback_userdata);
int libxl_wait_for_backend(struct libxl_ctx *ctx, char *be_path, char *state);
-int libxl_device_pci_flr(struct libxl_ctx *ctx, unsigned int domain, unsigned int bus,
- unsigned int dev, unsigned int func);
+int libxl_device_pci_reset(struct libxl_ctx *ctx, unsigned int domain, unsigned int bus,
+ unsigned int dev, unsigned int func);
/* from xenguest (helper */
int hvm_build_set_params(xc_interface *handle, uint32_t domid,