[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Update xenbus driver code.



# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 1b837c5794ca16171bf34decdbf1a32f261e28ec
# Parent  b5e3b99075c6ab3b19a3bfa48a9b86016885fb81

Update xenbus driver code.
Signed-off-by: Rusty Russel <rusty@xxxxxxxxxxxxxxx>
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r b5e3b99075c6 -r 1b837c5794ca 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Tue Jul 12 
09:38:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Tue Jul 12 
09:51:37 2005
@@ -45,7 +45,6 @@
 
 static void *xs_in, *xs_out;
 static LIST_HEAD(watches);
-static DECLARE_MUTEX(watches_lock);
 DECLARE_MUTEX(xs_lock);
 
 static int get_error(const char *errorstring)
@@ -88,6 +87,21 @@
        if (len)
                *len = msg.len;
        return ret;
+}
+
+/* Emergency write. */
+void xs_debug_write(const char *str, unsigned int count)
+{
+       struct xsd_sockmsg msg;
+       void *out = (void *)xen_start_info.store_page;
+
+       msg.type = XS_DEBUG;
+       msg.len = sizeof("print") + count + 1;
+
+       xb_write(out, &msg, sizeof(msg));
+       xb_write(out, "print", sizeof("print"));
+       xb_write(out, str, count);
+       xb_write(out, "", 1);
 }
 
 /* Send message to xs, get kmalloc'ed reply.  ERR_PTR() on error. */
@@ -233,7 +247,7 @@
                if (!p)
                        break;
                *p++ = '/';
-       }
+       }
  out:
        return err;
 }
@@ -389,15 +403,11 @@
        int err;
 
        sprintf(token, "%lX", (long)watch);
-       down(&watches_lock);
        BUG_ON(find_watch(token));
 
-       down(&xs_lock);
        err = xs_watch(watch->node, token, watch->priority);
-       up(&xs_lock);
        if (!err)
                list_add(&watch->list, &watches);
-       up(&watches_lock);
        return err;
 }
 
@@ -407,14 +417,10 @@
        int err;
 
        sprintf(token, "%lX", (long)watch);
-       down(&watches_lock);
        BUG_ON(!find_watch(token));
 
-       down(&xs_lock);
        err = xs_unwatch(watch->node, token);
-       up(&xs_lock);
        list_del(&watch->list);
-       up(&watches_lock);
 
        if (err)
                printk(KERN_WARNING "XENBUS Failed to release watch %s: %i\n",
@@ -423,16 +429,6 @@
 
 static int watch_thread(void *unused)
 {
-       int err;
-       unsigned long mtu;
-
-       set_current_state(TASK_INTERRUPTIBLE);
-       schedule_timeout(HZ*10);
-       printk("watch_thread, doing read\n");
-       down(&xs_lock);
-       err = xenbus_read_long("", "mtu", &mtu);
-       up(&xs_lock);
-       printk("fake field read: %i (%lu)\n", err, mtu);
 
        for (;;) {
                char *token;
@@ -447,28 +443,25 @@
                down(&xs_lock);
                if (xs_input_avail(xs_in))
                        node = xs_read_watch(&token);
-               /* Release lock before calling callback. */
-               up(&xs_lock);
+
                if (node && !IS_ERR(node)) {
                        struct xenbus_watch *w;
                        int err;
 
-                       down(&watches_lock);
                        w = find_watch(token);
                        BUG_ON(!w);
                        w->callback(w, node);
-                       up(&watches_lock);
-                       down(&xs_lock);
+                       /* FIXME: Only ack if it wasn't deleted. */
                        err = xs_acknowledge_watch(token);
                        if (err)
                                printk(KERN_WARNING
                                       "XENBUS acknowledge %s failed %i\n",
                                       node, err);
-                       up(&xs_lock);
                        kfree(node);
                } else
                        printk(KERN_WARNING "XENBUS xs_read_watch: %li\n",
                               PTR_ERR(node));
+               up(&xs_lock);
        }
 }
 
diff -r b5e3b99075c6 -r 1b837c5794ca 
linux-2.6-xen-sparse/include/asm-xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Tue Jul 12 09:38:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Tue Jul 12 09:51:37 2005
@@ -38,6 +38,7 @@
        char *nodename;
        int id;
        struct device dev;
+       void *data;
 };
 
 static inline struct xenbus_device *to_xenbus_device(struct device *dev)
@@ -97,7 +98,8 @@
 int xenbus_for_each_backend(struct xenbus_driver * start, void * data,
                             int (*fn)(struct xenbus_driver *, void *));
 
-/* Caller must hold this lock to call these functions. */
+/* Caller must hold this lock to call these functions: it's also held
+ * across watch callbacks. */
 extern struct semaphore xs_lock;
 
 char **xs_directory(const char *path, unsigned int *num);
@@ -124,6 +126,10 @@
 int register_xenbus_watch(struct xenbus_watch *watch);
 void unregister_xenbus_watch(struct xenbus_watch *watch);
 
+/* Generic read function: NULL-terminated triples of name,
+ * sprintf-style type string, and pointer. */
+int xenbus_gather(const char *dir, ...);
+
 char *xenbus_path(const char *dir, const char *name);
 char *xenbus_read(const char *dir, const char *name, unsigned int *data_n);
 int xenbus_write(const char *dir, const char *name,
@@ -135,9 +141,5 @@
 int xenbus_write_ulong(const char *dir, const char *name, unsigned long val);
 int xenbus_read_long(const char *dir, const char *name, long *val);
 int xenbus_write_long(const char *dir, const char *name, long val);
-int xenbus_read_mac(const char *dir, const char *name, unsigned char mac[6]);
-int xenbus_write_mac(const char *dir, const char *name, const unsigned char 
mac[6]);
-int xenbus_read_evtchn(const char *dir, const char *name, struct xenbus_evtchn 
*evtchn);
-int xenbus_message(const char *dir, const char *val, ...);
 
 #endif /* _ASM_XEN_XENBUS_H */
diff -r b5e3b99075c6 -r 1b837c5794ca 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Tue Jul 12 
09:38:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Tue Jul 12 
09:51:37 2005
@@ -36,19 +36,10 @@
 #include <stdarg.h>
 #include "xenbus_comms.h"
 
-/* Directory inside a domain containing devices. */
-#define XENBUS_DEVICE_DIR  "device"
-
-/* Directory inside a domain containing backends. */
-#define XENBUS_BACKEND_DIR  "backend"
-
-/* Name of field containing device id. */
-#define XENBUS_DEVICE_ID   "id"
-
 /* Name of field containing device type. */
 #define XENBUS_DEVICE_TYPE "type"
 
-//#define DEBUG
+#define DEBUG
 
 #ifdef DEBUG
 #define dprintf(_fmt, _args...) \
@@ -58,6 +49,32 @@
 #endif
 
 static int xs_init_done = 0;
+
+/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
+int xenbus_gather(const char *dir, ...)
+{
+       va_list ap;
+       const char *name;
+       int ret = 0;
+
+       va_start(ap, dir);
+       while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
+               const char *fmt = va_arg(ap, char *);
+               void *result = va_arg(ap, void *);
+               char *p;
+
+               p = xenbus_read(dir, name, NULL);
+               if (IS_ERR(p)) {
+                       ret = PTR_ERR(p);
+                       break;
+               }
+               if (sscanf(p, fmt, result) == 0)
+                       ret = -EINVAL;
+               kfree(p);
+       }
+       va_end(ap);
+       return ret;
+}
 
 /* Return the path to dir with /name appended.
  * If name is null or empty returns a copy of dir.
@@ -141,31 +158,7 @@
 
 int xenbus_read_ulong(const char *dir, const char *name, unsigned long *val)
 {
-       int err = 0;
-       char *data = NULL, *end = NULL;
-       unsigned int data_n = 0;
-
-       data = xenbus_read(dir, name, &data_n);
-       if (IS_ERR(data)) {
-               err = PTR_ERR(data);
-               goto out;
-       }
-       if (data_n <= 1) {
-               err = -ENOENT;
-               goto free_data;
-       }
-       *val = simple_strtoul(data, &end, 10);
-       if (end != data + data_n) {
-               printk("XENBUS: Path %s/%s, bad parse of '%s' as ulong\n",
-                      dir, name, data);
-               err = -EINVAL;
-       }
-  free_data:
-       kfree(data);
-  out:
-       if (err)
-               *val = 0;
-       return err;
+       return xenbus_gather(dir, name, "%lu", val, NULL);
 }
 
 int xenbus_write_ulong(const char *dir, const char *name, unsigned long val)
@@ -178,31 +171,7 @@
 
 int xenbus_read_long(const char *dir, const char *name, long *val)
 {
-       int err = 0;
-       char *data = NULL, *end = NULL;
-       unsigned int data_n = 0;
-
-       data = xenbus_read(dir, name, &data_n);
-       if (IS_ERR(data)) {
-               err = PTR_ERR(data);
-               goto out;
-       }
-       if (data_n <= 1) {
-               err = -ENOENT;
-               goto free_data;
-       }
-       *val = simple_strtol(data, &end, 10);
-       if (end != data + data_n) {
-               printk("XENBUS: Path %s/%s, bad parse of '%s' as long\n",
-                      dir, name, data);
-               err = -EINVAL;
-       }
-  free_data:
-       kfree(data);
-  out:
-       if (err)
-               *val = 0;
-       return err;
+       return xenbus_gather(dir, name, "%li", val, NULL);
 }
 
 int xenbus_write_long(const char *dir, const char *name, long val)
@@ -211,181 +180,6 @@
 
        snprintf(data, sizeof(data), "%li", val);
        return xenbus_write(dir, name, data, strlen(data));
-}
-
-/* Number of characters in string form of a MAC address. */
-#define MAC_LENGTH    17
-
-/** Convert a mac address from a string of the form
- * XX:XX:XX:XX:XX:XX to numerical form (an array of 6 unsigned chars).
- * Each X denotes a hex digit: 0..9, a..f, A..F.
- * Also supports using '-' as the separator instead of ':'.
- */
-static int mac_aton(const char *macstr, unsigned int n, unsigned char mac[6])
-{
-       int err = -EINVAL;
-       int i, j;
-       const char *p;
-       char sep = 0;
-       
-       if (!macstr || n != MAC_LENGTH)
-               goto exit;
-       for (i = 0, p = macstr; i < 6; i++) {
-               unsigned char d = 0;
-               if (i) {
-                       if (!sep && (*p == ':' || *p == '-'))
-                               sep = *p;
-                       if (sep && *p == sep)
-                               p++;
-                       else
-                               goto exit;
-               }
-               for (j = 0; j < 2; j++, p++) {
-                       if (j)
-                               d <<= 4;
-                       if (isdigit(*p))
-                               d += *p - '0';
-                       else if (isxdigit(*p))
-                               d += toupper(*p) - 'A' + 10;
-                       else
-                               goto exit;
-               }
-               mac[i] = d;
-       }
-       err = 0;
-  exit:
-       return err;
-}
-
-int xenbus_read_mac(const char *dir, const char *name, unsigned char mac[6])
-{
-       int err = 0;
-       char *data = 0;
-       unsigned int data_n = 0;
-
-       data = xenbus_read(dir, name, &data_n);
-       if (IS_ERR(data)) {
-               err = PTR_ERR(data);
-               goto out;
-       }
-       if (data_n <= 1) {
-               err = -ENOENT;
-               goto free_data;
-       }
-       err = mac_aton(data, data_n, mac);
-       if (err) {
-               printk("XENBUS: Path %s/%s, bad parse of '%s' as mac\n",
-                      dir, name, data);
-               err = -EINVAL;
-       }
-  free_data:
-       kfree(data);
-  out:
-       if (err)
-               memset(mac, 0, sizeof(mac));
-       return err;
-}
-
-int xenbus_write_mac(const char *dir, const char *name, const unsigned char 
mac[6])
-{
-       char buf[MAC_LENGTH] = {};
-       int buf_n = sizeof(buf);
-       
-       snprintf(buf, buf_n, "%02x:%02x:%02x:%02x:%02x:%02x",
-                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-       return xenbus_write(dir, name, buf, buf_n);
-}
-
-/* Read event channel information from xenstore.
- *
- * Event channel xenstore fields:
- * dom1                - backend domain id (int)
- * port1       - backend port (int)
- * dom2                - frontend domain id (int)
- * port2       - frontend port (int)
- */
-int xenbus_read_evtchn(const char *dir, const char *name, struct xenbus_evtchn 
*evtchn)
-{
-       int err = 0;
-       char *evtchn_path = xenbus_path(dir, name);
-
-       if (!evtchn_path) {
-               err = -ENOMEM;
-               goto out;
-       }
-       err = xenbus_read_ulong(evtchn_path, "dom1",  &evtchn->dom1);
-       if (err)
-               goto free_evtchn_path;
-       err = xenbus_read_ulong(evtchn_path, "port1", &evtchn->port1);
-       if (err)
-               goto free_evtchn_path;
-       err = xenbus_read_ulong(evtchn_path, "dom2",  &evtchn->dom2);
-       if (err)
-               goto free_evtchn_path;
-       err = xenbus_read_ulong(evtchn_path, "port2", &evtchn->port2);
-
-  free_evtchn_path:
-       kfree(evtchn_path);
-  out:
-       if (err)
-               *evtchn = (struct xenbus_evtchn){};
-       return err;
-}
-
-/* Write a message to 'dir'.
- * The data is 'val' followed by parameter names and values,
- * terminated by NULL.
- */
-int xenbus_message(const char *dir, const char *val, ...)
-{
-       static const char *mid_name = "@mid";
-       va_list args;
-       int err = 0;
-       char *mid_path = NULL; 
-       char *msg_path = NULL;
-       char mid_str[32] = {};
-       long mid = 0;
-       int i;
-
-       va_start(args, val);
-       mid_path = xenbus_path(dir, mid_name);
-       if (!mid_path) {
-               err = -ENOMEM;
-               goto out;
-       }
-       err = xenbus_read_long(dir, mid_name, &mid);
-       if (err != -ENOENT)
-               goto out;
-       mid++;
-       err = xenbus_write_long(dir, mid_name, mid);
-       if (err)
-               goto out;
-       sprintf(mid_str, "%li", mid);
-       msg_path = xenbus_path(dir, mid_str);
-       if (!mid_path) {
-               err = -ENOMEM;
-               goto out;
-       }
-
-       for (i = 0; i < 16; i++) {
-               char *k, *v;
-               k = va_arg(args, char *);
-               if (!k)
-                       break;
-               v = va_arg(args, char *);
-               if (!v)
-                       break;
-               err = xenbus_write_string(msg_path, k, v);
-               if (err)
-                       goto out;
-       }
-       err = xenbus_write_string(msg_path, NULL, val);
-
-  out:
-       kfree(msg_path);
-       kfree(mid_path);
-       va_end(args);
-       return err;
 }
 
 /* If something in array of ids matches this device, return it. */
@@ -488,12 +282,18 @@
        struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
        const struct xenbus_device_id *id;
 
-       if (!drv->probe)
+       printk("Probing device '%s'\n", _dev->bus_id);
+       if (!drv->probe) {
+               printk("'%s' no probefn\n", _dev->bus_id);
                return -ENODEV;
+       }
 
        id = match_device(drv->ids, dev);
-       if (!id)
+       if (!id) {
+               printk("'%s' no id match\n", _dev->bus_id);
                return -ENODEV;
+       }
+       printk("probing '%s' fn %p\n", _dev->bus_id, drv->probe);
        return drv->probe(dev, id);
 }
 
@@ -533,33 +333,18 @@
        driver_unregister(&drv->driver);
 }
 
-static int xenbus_probe_device(const char *dir, const char *name)
+static int xenbus_probe_device(const char *dir, const char *name, const char 
*devicetype)
 {
        int err;
        struct xenbus_device *xendev;
        unsigned int xendev_n;
-       long id;
-       char *nodename, *devicetype;
-       unsigned int devicetype_n;
+       char *nodename;
 
        dprintf("> dir=%s name=%s\n", dir, name);
        nodename = xenbus_path(dir, name);
        if (!nodename)
                return -ENOMEM;
 
-       devicetype = xenbus_read(nodename, XENBUS_DEVICE_TYPE, &devicetype_n);
-       if (IS_ERR(devicetype)) {
-               err = PTR_ERR(devicetype);
-               goto free_nodename;
-       }
-
-       err = xenbus_read_long(nodename, XENBUS_DEVICE_ID, &id);
-       if (err == -ENOENT)
-               id = 0;
-       else if (err != 0)
-               goto free_devicetype;
-
-       dprintf("> devicetype='%s' name='%s' id=%ld\n", devicetype, name, id);
        /* FIXME: This could be a rescan. Don't re-register existing devices. */
 
        /* Add space for the strings. */
@@ -567,14 +352,14 @@
        xendev = kmalloc(xendev_n, GFP_KERNEL);
        if (!xendev) {
                err = -ENOMEM;
-               goto free_devicetype;
+               goto free_nodename;
        }
        memset(xendev, 0, xendev_n);
 
        snprintf(xendev->dev.bus_id, BUS_ID_SIZE, "%s-%s", devicetype, name);
        xendev->dev.bus = &xenbus_type;
 
-       xendev->id = id;
+       xendev->id = simple_strtol(name, NULL, 0);
 
        /* Copy the strings into the extra space. */
        xendev->nodename = (char *)(xendev + 1);
@@ -591,8 +376,6 @@
                kfree(xendev);
        }
 
-free_devicetype:
-       kfree(devicetype);
 free_nodename:
        kfree(nodename);
        dprintf("< err=%i\n", err);
@@ -619,7 +402,7 @@
        }
 
        for (i = 0; i < dir_n; i++) {
-               err = xenbus_probe_device(path, dir[i]);
+               err = xenbus_probe_device(path, dir[i], typename);
                if (err)
                        break;
        }
@@ -778,26 +561,6 @@
                                &for_data, for_drv);
 }
 
-static void test_callback(struct xenbus_watch *w, const char *node)
-{
-       printk("test_callback: got watch hit for %s\n", node);
-}
-
-static void test_watch(void)
-{
-       static int init_done = 0;
-       static struct xenbus_watch watch = { .node = "/", 
-                                            .priority = 0, 
-                                            .callback = test_callback };
-
-       if (init_done)
-               return;
-       printk("registering watch %lX = %i\n",
-              (long)&watch,
-              register_xenbus_watch(&watch));
-       init_done = 1;
-}
-
 static int xenbus_driver_connect(struct xenbus_driver *drv, void *data)
 {
        printk("%s> driver %p %s\n", __FUNCTION__, drv, drv->name);
@@ -810,7 +573,9 @@
        return 0;
 }
 
-int do_xenbus_connect(void *unused)
+
+/* called from a thread in privcmd/privcmd.c */
+int do_xenbus_probe(void *unused)
 {
        int err = 0;
 
@@ -828,15 +593,14 @@
        xs_init_done = 1;
 
        /* Notify drivers that xenstore has connected. */
-       test_watch();
        printk("%s> connect drivers...\n", __FUNCTION__);
        xenbus_for_each_drv(NULL, NULL, xenbus_driver_connect);
        printk("%s> connect backends...\n", __FUNCTION__);
        xenbus_for_each_backend(NULL, NULL, xenbus_driver_connect);
        
        /* Enumerate devices and backends in xenstore. */
-       xenbus_probe_devices(XENBUS_DEVICE_DIR);
-       xenbus_probe_backends(XENBUS_BACKEND_DIR);
+       xenbus_probe_devices("device");
+       xenbus_probe_backends("backend");
 
 exit:
        printk("%s< err=%d\n", __FUNCTION__, err);
@@ -851,7 +615,7 @@
        if (!xen_start_info.store_evtchn)
                return 0;
 
-       do_xenbus_connect(NULL);
+       do_xenbus_probe(NULL);
        return 0;
 }
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.