# 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
|