]> xenbits.xensource.com Git - xen.git/commitdiff
libxl: support reset file on sysfs
authorIan Jackson <Ian.Jackson@eu.citrix.com>
Wed, 23 Jun 2010 16:05:31 +0000 (17:05 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Wed, 23 Jun 2010 16:05:31 +0000 (17:05 +0100)
Recent kernels have a reset file on sysfs per PCI device, to allow PCI
device reset from userspace.
This patch adds support to libxl for resetting PCI devices using the
reset file on sysfs, in case the do_flr file is not preset.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
tools/libxl/libxl.c
tools/libxl/libxl_device.c
tools/libxl/libxl_internal.h

index ebcdb3d0406878dcc549fc80471ad39b3049c33d..2563c91cc60967aed70342b02cda477c28838cbd 100644 (file)
@@ -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);
index 13563e89d948011ff44682320221f5b293ff7dbe..89c92db592d3cd14002009965eec6a32220e5b79 100644 (file)
@@ -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;
 }
index 72ffd54a477a08ccfd6a98665c6e54d54af46298..29dd2661a3bd91706a53aec2513ff398b0be5d39 100644 (file)
@@ -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,