[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH v4 6/7] plat/xen: Add Xenbus device probing
Reviewed-by: Yuri Volchkov <yuri.volchkov@xxxxxxxxx> Costin Lupu <costin.lupu@xxxxxxxxx> writes: > Extend the Xenbus bus driver with support for probing Xenbus > devices. > > Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx> > --- > plat/xen/include/xenbus/client.h | 12 ++++ > plat/xen/include/xenbus/xenbus.h | 17 ++++- > plat/xen/xenbus/client.c | 12 ++++ > plat/xen/xenbus/exportsyms.uk | 1 + > plat/xen/xenbus/xenbus.c | 131 > ++++++++++++++++++++++++++++++++++++++- > 5 files changed, 171 insertions(+), 2 deletions(-) > > diff --git a/plat/xen/include/xenbus/client.h > b/plat/xen/include/xenbus/client.h > index f3540b7..8b7e8c1 100644 > --- a/plat/xen/include/xenbus/client.h > +++ b/plat/xen/include/xenbus/client.h > @@ -86,4 +86,16 @@ int xenbus_watch_wait_event(struct xenbus_watch *watch); > */ > int xenbus_watch_notify_event(struct xenbus_watch *watch); > > +/* > + * Driver states > + */ > + > +/* > + * Returns the driver state found at the given Xenstore path. > + * > + * @param path Xenstore path > + * @return The Xenbus driver state > + */ > +XenbusState xenbus_read_driver_state(const char *path); > + > #endif /* __XENBUS_CLIENT_H__ */ > diff --git a/plat/xen/include/xenbus/xenbus.h > b/plat/xen/include/xenbus/xenbus.h > index 230dcd4..3d3b540 100644 > --- a/plat/xen/include/xenbus/xenbus.h > +++ b/plat/xen/include/xenbus/xenbus.h > @@ -110,7 +110,22 @@ UK_TAILQ_HEAD(xenbus_watch_list, struct xenbus_watch); > */ > > struct xenbus_device { > - > + /**< in use by Xenbus handler */ > + UK_TAILQ_ENTRY(struct xenbus_device) next; > + /**< Device state */ > + XenbusState state; > + /**< Device type */ > + enum xenbus_dev_type devtype; > + /**< Xenstore path of the device */ > + char *nodename; > + /**< Xenstore path of the device peer (e.g. backend for frontend) */ > + char *otherend; > + /**< Domain id of the other end */ > + domid_t otherend_id; > + /**< Watch for monitoring changes on other end */ > + struct xenbus_watch *otherend_watch; > + /**< Xenbus driver */ > + struct xenbus_driver *drv; > }; > UK_TAILQ_HEAD(xenbus_device_list, struct xenbus_device); > > diff --git a/plat/xen/xenbus/client.c b/plat/xen/xenbus/client.c > index 3dbca0f..274e6e7 100644 > --- a/plat/xen/xenbus/client.c > +++ b/plat/xen/xenbus/client.c > @@ -44,6 +44,7 @@ > #include <string.h> > #include <uk/errptr.h> > #include <uk/wait.h> > +#include <xenbus/xs.h> > #include <xenbus/client.h> > > > @@ -130,3 +131,14 @@ int xenbus_watch_notify_event(struct xenbus_watch *watch) > > return 0; > } > + > +XenbusState xenbus_read_driver_state(const char *path) > +{ > + char state_path[strlen(path) + sizeof("/state")]; > + XenbusState state = XenbusStateUnknown; > + > + sprintf(state_path, "%s/state", path); > + xs_read_integer(XBT_NIL, state_path, (int *) &state); > + > + return state; > +} > diff --git a/plat/xen/xenbus/exportsyms.uk b/plat/xen/xenbus/exportsyms.uk > index a424fd9..d57a2a5 100644 > --- a/plat/xen/xenbus/exportsyms.uk > +++ b/plat/xen/xenbus/exportsyms.uk > @@ -27,3 +27,4 @@ xenbus_state_to_str > xenbus_devtype_to_str > xenbus_str_to_devtype > xenbus_watch_wait_event > +xenbus_read_driver_state > diff --git a/plat/xen/xenbus/xenbus.c b/plat/xen/xenbus/xenbus.c > index a20546b..28f0cfd 100644 > --- a/plat/xen/xenbus/xenbus.c > +++ b/plat/xen/xenbus/xenbus.c > @@ -43,8 +43,12 @@ > #include <uk/errptr.h> > #include <uk/assert.h> > #include <xenbus/xenbus.h> > +#include <xenbus/xs.h> > +#include <xenbus/client.h> > #include "xs_comms.h" > > +#define XS_DEV_PATH "device" > + > static struct xenbus_handler xbh; > > > @@ -67,13 +71,138 @@ void uk_xb_free(void *ptr) > uk_free(xbh.a, ptr); > } > > + > +static struct xenbus_driver *xenbus_find_driver(xenbus_dev_type_t devtype) > +{ > + struct xenbus_driver *drv; > + const xenbus_dev_type_t *pdevtype; > + > + UK_TAILQ_FOREACH(drv, &xbh.drv_list, next) { > + for (pdevtype = drv->device_types; > + *pdevtype != xenbus_dev_none; pdevtype++) { > + if (*pdevtype == devtype) > + return drv; > + } > + } > + > + return NULL; /* no driver found */ > +} > + > +static int xenbus_probe_device(struct xenbus_driver *drv, > + xenbus_dev_type_t type, const char *name) > +{ > + int err; > + struct xenbus_device *dev; > + char *nodename = NULL; > + XenbusState state; > + > + /* device/type/name */ > + err = asprintf(&nodename, "%s/%s/%s", > + XS_DEV_PATH, xenbus_devtype_to_str(type), name); > + if (err < 0) > + goto out; > + > + state = xenbus_read_driver_state(nodename); > + if (state != XenbusStateInitialising) > + return 0; > + > + uk_printd(DLVL_INFO, "Xenbus device: %s\n", nodename); > + > + dev = uk_xb_calloc(1, sizeof(*dev) + strlen(nodename) + 1); > + if (!dev) { > + uk_printd(DLVL_ERR, "Failed to initialize: Out of memory!\n"); > + err = -ENOMEM; > + goto out; > + } > + > + dev->state = XenbusStateInitialising; > + dev->devtype = type; > + dev->nodename = (char *) (dev + 1); > + strcpy(dev->nodename, nodename); > + > + err = drv->add_dev(dev); > + if (err) { > + uk_printd(DLVL_ERR, "Failed to add device.\n"); > + uk_xb_free(dev); > + } > + > +out: > + if (nodename) > + free(nodename); > + > + return err; > +} > + > +static int xenbus_probe_device_type(const char *devtype_str) > +{ > + struct xenbus_driver *drv; > + xenbus_dev_type_t devtype; > + char dirname[sizeof(XS_DEV_PATH) + strlen(devtype_str)]; > + char **devices = NULL; > + int err = 0; > + > + devtype = xenbus_str_to_devtype(devtype_str); > + if (!devtype) { > + uk_printd(DLVL_WARN, > + "Unsupported device type: %s\n", devtype_str); > + goto out; > + } > + > + drv = xenbus_find_driver(devtype); > + if (!drv) { > + uk_printd(DLVL_WARN, > + "No driver for device type: %s\n", devtype_str); > + goto out; > + } > + > + sprintf(dirname, "%s/%s", XS_DEV_PATH, devtype_str); > + > + /* Get device list */ > + devices = xs_ls(XBT_NIL, dirname); > + if (PTRISERR(devices)) { > + err = PTR2ERR(devices); > + uk_printd(DLVL_ERR, > + "Error reading %s devices: %d\n", devtype_str, err); > + goto out; > + } > + > + for (int i = 0; devices[i] != NULL; i++) { > + /* Probe only if no prior error */ > + if (err == 0) > + err = xenbus_probe_device(drv, devtype, devices[i]); > + } > + > +out: > + if (!PTRISERR(devices)) > + free(devices); > + > + return err; > +} > + > static int xenbus_probe(void) > { > + char **devtypes; > int err = 0; > > uk_printd(DLVL_INFO, "Probe Xenbus\n"); > > - /* TODO */ > + /* Get device types list */ > + devtypes = xs_ls(XBT_NIL, XS_DEV_PATH); > + if (PTRISERR(devtypes)) { > + err = PTR2ERR(devtypes); > + uk_printd(DLVL_ERR, "Error reading device types: %d\n", err); > + goto out; > + } > + > + for (int i = 0; devtypes[i] != NULL; i++) { > + /* Probe only if no previous error */ > + if (err == 0) > + err = xenbus_probe_device_type(devtypes[i]); > + } > + > +out: > + if (!PTRISERR(devtypes)) > + free(devtypes); > > return err; > } > -- > 2.11.0 > -- Yuri Volchkov Software Specialist NEC Europe Ltd Kurfürsten-Anlage 36 D-69115 Heidelberg _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |