diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/libxl/libxl.c | 4 | ||||
-rw-r--r-- | tools/libxl/libxl_device.c | 38 | ||||
-rw-r--r-- | tools/libxl/libxl_internal.h | 4 |
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, |