Hi all,
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@xxxxxxxxxxxxx>
---
diff -r 6473fd010049 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c Wed Jun 23 11:06:36 2010 +0100
+++ b/tools/libxl/libxl.c Wed Jun 23 12:03:24 2010 +0100
@@ -2381,7 +2381,7 @@
/* 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 @@
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 -r 6473fd010049 tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c Wed Jun 23 11:06:36 2010 +0100
+++ b/tools/libxl/libxl_device.c Wed Jun 23 12:03:24 2010 +0100
@@ -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 @@
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;
+ char *reset = "/sys/bus/pci/drivers/pciback/do_flr";
+ int fd, rc;
- fd = fopen(do_flr, "w");
- if (fd != NULL) {
- fprintf(fd, PCI_BDF, domain, bus, dev, func);
- fclose(fd);
- return 0;
+ 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 -r 6473fd010049 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h Wed Jun 23 11:06:36 2010 +0100
+++ b/tools/libxl/libxl_internal.h Wed Jun 23 12:03:24 2010 +0100
@@ -162,8 +162,8 @@
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,
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|