This implements simple device probing.

I have discussed this with deraadt@ and then later with kettenis@
and mpi@ and we've decided that OpenFirmware emulation would be a
bit too much (at least for now).

This is a work in progress, it will improve a bit once we start
working on the Netfront network interface.

OK?

---
 sys/dev/pv/xen.c    | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/pv/xenvar.h |  6 +++++
 2 files changed, 73 insertions(+)

diff --git sys/dev/pv/xen.c sys/dev/pv/xen.c
index c78cc75..8523e03 100644
--- sys/dev/pv/xen.c
+++ sys/dev/pv/xen.c
@@ -47,10 +47,11 @@ void        xen_disable_emulated_devices(struct xen_softc 
*);
 int    xen_match(struct device *, void *, void *);
 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 *);
 
 struct cfdriver xen_cd = {
        NULL, "xen", DV_DULL
@@ -107,10 +108,12 @@ xen_attach(struct device *parent, struct device *self, 
void *aux)
        if (xs_attach(sc))
                return;
 
        xen_disable_emulated_devices(sc);
 
+       xen_probe_devices(sc);
+
        mountroothook_establish(xen_deferred, sc);
 }
 
 void
 xen_deferred(void *arg)
@@ -721,10 +724,74 @@ xen_intr_enable(void)
                                    sc->sc_dev.dv_xname, xi->xi_port);
                }
        }
 }
 
+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
 #define XMI_MAGIC              0x49d2
 #define XMI_UNPLUG_IDE         0x01
diff --git sys/dev/pv/xenvar.h sys/dev/pv/xenvar.h
index 9d73921..0e62dd9 100644
--- sys/dev/pv/xenvar.h
+++ sys/dev/pv/xenvar.h
@@ -55,10 +55,16 @@ struct xen_softc {
        struct xs_softc         *sc_xs;         /* xenstore softc */
 };
 
 extern struct xen_softc *xen_sc;
 
+struct xen_attach_args {
+       void                    *xa_parent;
+       char                     xa_name[16];
+       char                     xa_node[64];
+};
+
 /*
  *  Hypercalls
  */
 #define memory_op              12
 #define xen_version            17
-- 
2.6.3

Reply via email to