summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormikeb <mikeb@openbsd.org>2015-12-08 22:23:30 +0000
committermikeb <mikeb@openbsd.org>2015-12-08 22:23:30 +0000
commit6ebc03979ad7c6301ee4ec6f747304ae90cb6c18 (patch)
treecc2acb0d0a083b2e828ca05668a00a34a243e9bd
parentImplement a function to detach emulated devices (such as an em(4) (diff)
downloadwireguard-openbsd-6ebc03979ad7c6301ee4ec6f747304ae90cb6c18.tar.xz
wireguard-openbsd-6ebc03979ad7c6301ee4ec6f747304ae90cb6c18.zip
Implements simple virtual device probing routine
Discussed with deraadt@, kettenis@, mpi@, OK mlarkin, mpi
-rw-r--r--sys/dev/pv/xen.c67
-rw-r--r--sys/dev/pv/xenvar.h6
2 files changed, 73 insertions, 0 deletions
diff --git a/sys/dev/pv/xen.c b/sys/dev/pv/xen.c
index 63f8c2825f1..7f2a5964a66 100644
--- a/sys/dev/pv/xen.c
+++ b/sys/dev/pv/xen.c
@@ -48,6 +48,7 @@ void xen_attach(struct device *, struct device *, void *);
void xen_deferred(void *);
void xen_resume(struct device *);
int xen_activate(struct device *, int);
+int xen_probe_devices(struct xen_softc *);
int xs_attach(struct xen_softc *);
@@ -106,6 +107,8 @@ xen_attach(struct device *parent, struct device *self, void *aux)
xen_disable_emulated_devices(sc);
+ xen_probe_devices(sc);
+
mountroothook_establish(xen_deferred, sc);
}
@@ -704,6 +707,70 @@ xen_intr_enable(void)
}
}
+static int
+xen_attach_print(void *aux, const char *name)
+{
+ struct xen_attach_args *xa = aux;
+
+ if (name)
+ printf("\"%s\" at %s: %s", xa->xa_name, name, xa->xa_node);
+
+ return (UNCONF);
+}
+
+int
+xen_probe_devices(struct xen_softc *sc)
+{
+ struct xen_attach_args xa;
+ struct xs_transaction xst;
+ struct iovec *iovp1, *iovp2;
+ int error = 0, iov1_cnt, iov2_cnt, i, j;
+ char path[64];
+
+ memset(&xst, 0, sizeof(xst));
+ xst.xst_id = 0;
+ xst.xst_sc = sc->sc_xs;
+ xst.xst_flags |= XST_POLL;
+
+ if ((error = xs_cmd(&xst, XS_DIRECTORY, "device", &iovp1,
+ &iov1_cnt)) != 0)
+ return (error);
+
+ for (i = 0; i < iov1_cnt; i++) {
+ /* Special handling */
+ if (!strcmp("suspend", (char *)iovp1[i].iov_base)) {
+ xa.xa_parent = sc;
+ strlcpy(xa.xa_name, (char *)iovp1[i].iov_base,
+ sizeof(xa.xa_name));
+ snprintf(xa.xa_node, sizeof(xa.xa_node), "device/%s",
+ (char *)iovp1[i].iov_base);
+ config_found((struct device *)sc, &xa,
+ xen_attach_print);
+ continue;
+ }
+ snprintf(path, sizeof(path), "device/%s",
+ (char *)iovp1[i].iov_base);
+ if ((error = xs_cmd(&xst, XS_DIRECTORY, path, &iovp2,
+ &iov2_cnt)) != 0) {
+ xs_resfree(&xst, iovp1, iov1_cnt);
+ return (error);
+ }
+ for (j = 0; j < iov2_cnt; j++) {
+ xa.xa_parent = sc;
+ strlcpy(xa.xa_name, (char *)iovp1[i].iov_base,
+ sizeof(xa.xa_name));
+ snprintf(xa.xa_node, sizeof(xa.xa_node), "device/%s/%s",
+ (char *)iovp1[i].iov_base,
+ (char *)iovp2[j].iov_base);
+ config_found((struct device *)sc, &xa,
+ xen_attach_print);
+ }
+ xs_resfree(&xst, iovp2, iov2_cnt);
+ }
+
+ return (error);
+}
+
#include <machine/pio.h>
#define XMI_PORT 0x10
diff --git a/sys/dev/pv/xenvar.h b/sys/dev/pv/xenvar.h
index 9d73921606c..0e62dd9a8d6 100644
--- a/sys/dev/pv/xenvar.h
+++ b/sys/dev/pv/xenvar.h
@@ -57,6 +57,12 @@ struct xen_softc {
extern struct xen_softc *xen_sc;
+struct xen_attach_args {
+ void *xa_parent;
+ char xa_name[16];
+ char xa_node[64];
+};
+
/*
* Hypercalls
*/