|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v2 10/10] plat/xen: Add Xenbus device probing
Extend the Xenbus bus driver with support for probing Xenbus
devices.
Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
---
plat/xen/include/xenbus/xenbus.h | 17 ++++-
plat/xen/xenbus/xenbus.c | 131 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 146 insertions(+), 2 deletions(-)
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/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
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |