ia64/xen-unstable

changeset 5747:1b837c5794ca

Update xenbus driver code.
Signed-off-by: Rusty Russel <rusty@rustcorp.com.au>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Tue Jul 12 09:51:37 2005 +0000 (2005-07-12)
parents b5e3b99075c6
children 739ba7204123
files linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c linux-2.6-xen-sparse/include/asm-xen/xenbus.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Tue Jul 12 09:38:02 2005 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Tue Jul 12 09:51:37 2005 +0000
     1.3 @@ -36,19 +36,10 @@
     1.4  #include <stdarg.h>
     1.5  #include "xenbus_comms.h"
     1.6  
     1.7 -/* Directory inside a domain containing devices. */
     1.8 -#define XENBUS_DEVICE_DIR  "device"
     1.9 -
    1.10 -/* Directory inside a domain containing backends. */
    1.11 -#define XENBUS_BACKEND_DIR  "backend"
    1.12 -
    1.13 -/* Name of field containing device id. */
    1.14 -#define XENBUS_DEVICE_ID   "id"
    1.15 -
    1.16  /* Name of field containing device type. */
    1.17  #define XENBUS_DEVICE_TYPE "type"
    1.18  
    1.19 -//#define DEBUG
    1.20 +#define DEBUG
    1.21  
    1.22  #ifdef DEBUG
    1.23  #define dprintf(_fmt, _args...) \
    1.24 @@ -59,6 +50,32 @@ printk(KERN_INFO __stringify(KBUILD_MODN
    1.25  
    1.26  static int xs_init_done = 0;
    1.27  
    1.28 +/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
    1.29 +int xenbus_gather(const char *dir, ...)
    1.30 +{
    1.31 +	va_list ap;
    1.32 +	const char *name;
    1.33 +	int ret = 0;
    1.34 +
    1.35 +	va_start(ap, dir);
    1.36 +	while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
    1.37 +		const char *fmt = va_arg(ap, char *);
    1.38 +		void *result = va_arg(ap, void *);
    1.39 +		char *p;
    1.40 +
    1.41 +		p = xenbus_read(dir, name, NULL);
    1.42 +		if (IS_ERR(p)) {
    1.43 +			ret = PTR_ERR(p);
    1.44 +			break;
    1.45 +		}
    1.46 +		if (sscanf(p, fmt, result) == 0)
    1.47 +			ret = -EINVAL;
    1.48 +		kfree(p);
    1.49 +	}
    1.50 +	va_end(ap);
    1.51 +	return ret;
    1.52 +}
    1.53 +
    1.54  /* Return the path to dir with /name appended.
    1.55   * If name is null or empty returns a copy of dir.
    1.56   */ 
    1.57 @@ -141,31 +158,7 @@ int xenbus_write_string(const char *dir,
    1.58  
    1.59  int xenbus_read_ulong(const char *dir, const char *name, unsigned long *val)
    1.60  {
    1.61 -	int err = 0;
    1.62 -	char *data = NULL, *end = NULL;
    1.63 -	unsigned int data_n = 0;
    1.64 -
    1.65 -	data = xenbus_read(dir, name, &data_n);
    1.66 -	if (IS_ERR(data)) {
    1.67 -		err = PTR_ERR(data);
    1.68 -		goto out;
    1.69 -	}
    1.70 -	if (data_n <= 1) {
    1.71 -		err = -ENOENT;
    1.72 -		goto free_data;
    1.73 -	}
    1.74 -	*val = simple_strtoul(data, &end, 10);
    1.75 -	if (end != data + data_n) {
    1.76 -		printk("XENBUS: Path %s/%s, bad parse of '%s' as ulong\n",
    1.77 -		       dir, name, data);
    1.78 -		err = -EINVAL;
    1.79 -	}
    1.80 -  free_data:
    1.81 -	kfree(data);
    1.82 -  out:
    1.83 -	if (err)
    1.84 -		*val = 0;
    1.85 -	return err;
    1.86 +	return xenbus_gather(dir, name, "%lu", val, NULL);
    1.87  }
    1.88  
    1.89  int xenbus_write_ulong(const char *dir, const char *name, unsigned long val)
    1.90 @@ -178,31 +171,7 @@ int xenbus_write_ulong(const char *dir, 
    1.91  
    1.92  int xenbus_read_long(const char *dir, const char *name, long *val)
    1.93  {
    1.94 -	int err = 0;
    1.95 -	char *data = NULL, *end = NULL;
    1.96 -	unsigned int data_n = 0;
    1.97 -
    1.98 -	data = xenbus_read(dir, name, &data_n);
    1.99 -	if (IS_ERR(data)) {
   1.100 -		err = PTR_ERR(data);
   1.101 -		goto out;
   1.102 -	}
   1.103 -	if (data_n <= 1) {
   1.104 -		err = -ENOENT;
   1.105 -		goto free_data;
   1.106 -	}
   1.107 -	*val = simple_strtol(data, &end, 10);
   1.108 -	if (end != data + data_n) {
   1.109 -		printk("XENBUS: Path %s/%s, bad parse of '%s' as long\n",
   1.110 -		       dir, name, data);
   1.111 -		err = -EINVAL;
   1.112 -	}
   1.113 -  free_data:
   1.114 -	kfree(data);
   1.115 -  out:
   1.116 -	if (err)
   1.117 -		*val = 0;
   1.118 -	return err;
   1.119 +	return xenbus_gather(dir, name, "%li", val, NULL);
   1.120  }
   1.121  
   1.122  int xenbus_write_long(const char *dir, const char *name, long val)
   1.123 @@ -213,181 +182,6 @@ int xenbus_write_long(const char *dir, c
   1.124  	return xenbus_write(dir, name, data, strlen(data));
   1.125  }
   1.126  
   1.127 -/* Number of characters in string form of a MAC address. */
   1.128 -#define MAC_LENGTH    17
   1.129 -
   1.130 -/** Convert a mac address from a string of the form
   1.131 - * XX:XX:XX:XX:XX:XX to numerical form (an array of 6 unsigned chars).
   1.132 - * Each X denotes a hex digit: 0..9, a..f, A..F.
   1.133 - * Also supports using '-' as the separator instead of ':'.
   1.134 - */
   1.135 -static int mac_aton(const char *macstr, unsigned int n, unsigned char mac[6])
   1.136 -{
   1.137 -	int err = -EINVAL;
   1.138 -	int i, j;
   1.139 -	const char *p;
   1.140 -	char sep = 0;
   1.141 -	
   1.142 -	if (!macstr || n != MAC_LENGTH)
   1.143 -		goto exit;
   1.144 -	for (i = 0, p = macstr; i < 6; i++) {
   1.145 -		unsigned char d = 0;
   1.146 -		if (i) {
   1.147 -			if (!sep && (*p == ':' || *p == '-'))
   1.148 -				sep = *p;
   1.149 -			if (sep && *p == sep)
   1.150 -				p++;
   1.151 -			else
   1.152 -				goto exit;
   1.153 -		}
   1.154 -		for (j = 0; j < 2; j++, p++) {
   1.155 -			if (j)
   1.156 -				d <<= 4;
   1.157 -			if (isdigit(*p))
   1.158 -				d += *p - '0';
   1.159 -			else if (isxdigit(*p))
   1.160 -				d += toupper(*p) - 'A' + 10;
   1.161 -			else
   1.162 -				goto exit;
   1.163 -		}
   1.164 -		mac[i] = d;
   1.165 -	}
   1.166 -	err = 0;
   1.167 -  exit:
   1.168 -	return err;
   1.169 -}
   1.170 -
   1.171 -int xenbus_read_mac(const char *dir, const char *name, unsigned char mac[6])
   1.172 -{
   1.173 -	int err = 0;
   1.174 -	char *data = 0;
   1.175 -	unsigned int data_n = 0;
   1.176 -
   1.177 -	data = xenbus_read(dir, name, &data_n);
   1.178 -	if (IS_ERR(data)) {
   1.179 -		err = PTR_ERR(data);
   1.180 -		goto out;
   1.181 -	}
   1.182 -	if (data_n <= 1) {
   1.183 -		err = -ENOENT;
   1.184 -		goto free_data;
   1.185 -	}
   1.186 -	err = mac_aton(data, data_n, mac);
   1.187 -	if (err) {
   1.188 -		printk("XENBUS: Path %s/%s, bad parse of '%s' as mac\n",
   1.189 -		       dir, name, data);
   1.190 -		err = -EINVAL;
   1.191 -	}
   1.192 -  free_data:
   1.193 -	kfree(data);
   1.194 -  out:
   1.195 -	if (err)
   1.196 -		memset(mac, 0, sizeof(mac));
   1.197 -	return err;
   1.198 -}
   1.199 -
   1.200 -int xenbus_write_mac(const char *dir, const char *name, const unsigned char mac[6])
   1.201 -{
   1.202 -	char buf[MAC_LENGTH] = {};
   1.203 -	int buf_n = sizeof(buf);
   1.204 -	
   1.205 -	snprintf(buf, buf_n, "%02x:%02x:%02x:%02x:%02x:%02x",
   1.206 -		 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
   1.207 -	return xenbus_write(dir, name, buf, buf_n);
   1.208 -}
   1.209 -
   1.210 -/* Read event channel information from xenstore.
   1.211 - *
   1.212 - * Event channel xenstore fields:
   1.213 - * dom1		- backend domain id (int)
   1.214 - * port1	- backend port (int)
   1.215 - * dom2		- frontend domain id (int)
   1.216 - * port2	- frontend port (int)
   1.217 - */
   1.218 -int xenbus_read_evtchn(const char *dir, const char *name, struct xenbus_evtchn *evtchn)
   1.219 -{
   1.220 -	int err = 0;
   1.221 -	char *evtchn_path = xenbus_path(dir, name);
   1.222 -
   1.223 -	if (!evtchn_path) {
   1.224 -		err = -ENOMEM;
   1.225 -		goto out;
   1.226 -	}
   1.227 -	err = xenbus_read_ulong(evtchn_path, "dom1",  &evtchn->dom1);
   1.228 -	if (err)
   1.229 -		goto free_evtchn_path;
   1.230 -	err = xenbus_read_ulong(evtchn_path, "port1", &evtchn->port1);
   1.231 -	if (err)
   1.232 -		goto free_evtchn_path;
   1.233 -	err = xenbus_read_ulong(evtchn_path, "dom2",  &evtchn->dom2);
   1.234 -	if (err)
   1.235 -		goto free_evtchn_path;
   1.236 -	err = xenbus_read_ulong(evtchn_path, "port2", &evtchn->port2);
   1.237 -
   1.238 -  free_evtchn_path:
   1.239 -	kfree(evtchn_path);
   1.240 -  out:
   1.241 -	if (err)
   1.242 -		*evtchn = (struct xenbus_evtchn){};
   1.243 -	return err;
   1.244 -}
   1.245 -
   1.246 -/* Write a message to 'dir'.
   1.247 - * The data is 'val' followed by parameter names and values,
   1.248 - * terminated by NULL.
   1.249 - */
   1.250 -int xenbus_message(const char *dir, const char *val, ...)
   1.251 -{
   1.252 -	static const char *mid_name = "@mid";
   1.253 -	va_list args;
   1.254 -	int err = 0;
   1.255 -	char *mid_path = NULL; 
   1.256 -	char *msg_path = NULL;
   1.257 -	char mid_str[32] = {};
   1.258 -	long mid = 0;
   1.259 -	int i;
   1.260 -
   1.261 -	va_start(args, val);
   1.262 -	mid_path = xenbus_path(dir, mid_name);
   1.263 -	if (!mid_path) {
   1.264 -		err = -ENOMEM;
   1.265 -		goto out;
   1.266 -	}
   1.267 -	err = xenbus_read_long(dir, mid_name, &mid);
   1.268 -	if (err != -ENOENT)
   1.269 -		goto out;
   1.270 -	mid++;
   1.271 -	err = xenbus_write_long(dir, mid_name, mid);
   1.272 -	if (err)
   1.273 -		goto out;
   1.274 -	sprintf(mid_str, "%li", mid);
   1.275 -	msg_path = xenbus_path(dir, mid_str);
   1.276 -	if (!mid_path) {
   1.277 -		err = -ENOMEM;
   1.278 -		goto out;
   1.279 -	}
   1.280 -
   1.281 -	for (i = 0; i < 16; i++) {
   1.282 -		char *k, *v;
   1.283 -		k = va_arg(args, char *);
   1.284 -		if (!k)
   1.285 -			break;
   1.286 -		v = va_arg(args, char *);
   1.287 -		if (!v)
   1.288 -			break;
   1.289 -		err = xenbus_write_string(msg_path, k, v);
   1.290 -		if (err)
   1.291 -			goto out;
   1.292 -	}
   1.293 -	err = xenbus_write_string(msg_path, NULL, val);
   1.294 -
   1.295 -  out:
   1.296 -	kfree(msg_path);
   1.297 -	kfree(mid_path);
   1.298 -	va_end(args);
   1.299 -	return err;
   1.300 -}
   1.301 -
   1.302  /* If something in array of ids matches this device, return it. */
   1.303  static const struct xenbus_device_id *
   1.304  match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev)
   1.305 @@ -488,12 +282,18 @@ static int xenbus_dev_probe(struct devic
   1.306  	struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
   1.307  	const struct xenbus_device_id *id;
   1.308  
   1.309 -	if (!drv->probe)
   1.310 +	printk("Probing device '%s'\n", _dev->bus_id);
   1.311 +	if (!drv->probe) {
   1.312 +		printk("'%s' no probefn\n", _dev->bus_id);
   1.313  		return -ENODEV;
   1.314 +	}
   1.315  
   1.316  	id = match_device(drv->ids, dev);
   1.317 -	if (!id)
   1.318 +	if (!id) {
   1.319 +		printk("'%s' no id match\n", _dev->bus_id);
   1.320  		return -ENODEV;
   1.321 +	}
   1.322 +	printk("probing '%s' fn %p\n", _dev->bus_id, drv->probe);
   1.323  	return drv->probe(dev, id);
   1.324  }
   1.325  
   1.326 @@ -533,33 +333,18 @@ void xenbus_unregister_driver(struct xen
   1.327  	driver_unregister(&drv->driver);
   1.328  }
   1.329  
   1.330 -static int xenbus_probe_device(const char *dir, const char *name)
   1.331 +static int xenbus_probe_device(const char *dir, const char *name, const char *devicetype)
   1.332  {
   1.333  	int err;
   1.334  	struct xenbus_device *xendev;
   1.335  	unsigned int xendev_n;
   1.336 -	long id;
   1.337 -	char *nodename, *devicetype;
   1.338 -	unsigned int devicetype_n;
   1.339 +	char *nodename;
   1.340  
   1.341  	dprintf("> dir=%s name=%s\n", dir, name);
   1.342  	nodename = xenbus_path(dir, name);
   1.343  	if (!nodename)
   1.344  		return -ENOMEM;
   1.345  
   1.346 -	devicetype = xenbus_read(nodename, XENBUS_DEVICE_TYPE, &devicetype_n);
   1.347 -	if (IS_ERR(devicetype)) {
   1.348 -		err = PTR_ERR(devicetype);
   1.349 -		goto free_nodename;
   1.350 -	}
   1.351 -
   1.352 -	err = xenbus_read_long(nodename, XENBUS_DEVICE_ID, &id);
   1.353 -	if (err == -ENOENT)
   1.354 -		id = 0;
   1.355 -	else if (err != 0)
   1.356 -		goto free_devicetype;
   1.357 -
   1.358 -	dprintf("> devicetype='%s' name='%s' id=%ld\n", devicetype, name, id);
   1.359  	/* FIXME: This could be a rescan. Don't re-register existing devices. */
   1.360  
   1.361  	/* Add space for the strings. */
   1.362 @@ -567,14 +352,14 @@ static int xenbus_probe_device(const cha
   1.363  	xendev = kmalloc(xendev_n, GFP_KERNEL);
   1.364  	if (!xendev) {
   1.365  		err = -ENOMEM;
   1.366 -		goto free_devicetype;
   1.367 +		goto free_nodename;
   1.368  	}
   1.369  	memset(xendev, 0, xendev_n);
   1.370  
   1.371  	snprintf(xendev->dev.bus_id, BUS_ID_SIZE, "%s-%s", devicetype, name);
   1.372  	xendev->dev.bus = &xenbus_type;
   1.373  
   1.374 -	xendev->id = id;
   1.375 +	xendev->id = simple_strtol(name, NULL, 0);
   1.376  
   1.377  	/* Copy the strings into the extra space. */
   1.378  	xendev->nodename = (char *)(xendev + 1);
   1.379 @@ -591,8 +376,6 @@ static int xenbus_probe_device(const cha
   1.380  		kfree(xendev);
   1.381  	}
   1.382  
   1.383 -free_devicetype:
   1.384 -	kfree(devicetype);
   1.385  free_nodename:
   1.386  	kfree(nodename);
   1.387  	dprintf("< err=%i\n", err);
   1.388 @@ -619,7 +402,7 @@ static int xenbus_probe_device_type(cons
   1.389  	}
   1.390  
   1.391  	for (i = 0; i < dir_n; i++) {
   1.392 -		err = xenbus_probe_device(path, dir[i]);
   1.393 +		err = xenbus_probe_device(path, dir[i], typename);
   1.394  		if (err)
   1.395  			break;
   1.396  	}
   1.397 @@ -778,26 +561,6 @@ int xenbus_for_each_backend(struct xenbu
   1.398  				&for_data, for_drv);
   1.399  }
   1.400  
   1.401 -static void test_callback(struct xenbus_watch *w, const char *node)
   1.402 -{
   1.403 -	printk("test_callback: got watch hit for %s\n", node);
   1.404 -}
   1.405 -
   1.406 -static void test_watch(void)
   1.407 -{
   1.408 -	static int init_done = 0;
   1.409 -	static struct xenbus_watch watch = { .node = "/", 
   1.410 -					     .priority = 0, 
   1.411 -					     .callback = test_callback };
   1.412 -
   1.413 -	if (init_done)
   1.414 -		return;
   1.415 -	printk("registering watch %lX = %i\n",
   1.416 -	       (long)&watch,
   1.417 -	       register_xenbus_watch(&watch));
   1.418 -	init_done = 1;
   1.419 -}
   1.420 -
   1.421  static int xenbus_driver_connect(struct xenbus_driver *drv, void *data)
   1.422  {
   1.423  	printk("%s> driver %p %s\n", __FUNCTION__, drv, drv->name);
   1.424 @@ -810,7 +573,9 @@ static int xenbus_driver_connect(struct 
   1.425  	return 0;
   1.426  }
   1.427  
   1.428 -int do_xenbus_connect(void *unused)
   1.429 +
   1.430 +/* called from a thread in privcmd/privcmd.c */
   1.431 +int do_xenbus_probe(void *unused)
   1.432  {
   1.433  	int err = 0;
   1.434  
   1.435 @@ -828,15 +593,14 @@ int do_xenbus_connect(void *unused)
   1.436  	xs_init_done = 1;
   1.437  
   1.438  	/* Notify drivers that xenstore has connected. */
   1.439 -	test_watch();
   1.440  	printk("%s> connect drivers...\n", __FUNCTION__);
   1.441  	xenbus_for_each_drv(NULL, NULL, xenbus_driver_connect);
   1.442  	printk("%s> connect backends...\n", __FUNCTION__);
   1.443  	xenbus_for_each_backend(NULL, NULL, xenbus_driver_connect);
   1.444  	
   1.445  	/* Enumerate devices and backends in xenstore. */
   1.446 -	xenbus_probe_devices(XENBUS_DEVICE_DIR);
   1.447 -	xenbus_probe_backends(XENBUS_BACKEND_DIR);
   1.448 +	xenbus_probe_devices("device");
   1.449 +	xenbus_probe_backends("backend");
   1.450  
   1.451  exit:
   1.452  	printk("%s< err=%d\n", __FUNCTION__, err);
   1.453 @@ -851,7 +615,7 @@ static int __init xenbus_probe_init(void
   1.454  	if (!xen_start_info.store_evtchn)
   1.455  		return 0;
   1.456  
   1.457 -	do_xenbus_connect(NULL);
   1.458 +	do_xenbus_probe(NULL);
   1.459  	return 0;
   1.460  }
   1.461  
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Tue Jul 12 09:38:02 2005 +0000
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Tue Jul 12 09:51:37 2005 +0000
     2.3 @@ -45,7 +45,6 @@
     2.4  
     2.5  static void *xs_in, *xs_out;
     2.6  static LIST_HEAD(watches);
     2.7 -static DECLARE_MUTEX(watches_lock);
     2.8  DECLARE_MUTEX(xs_lock);
     2.9  
    2.10  static int get_error(const char *errorstring)
    2.11 @@ -90,6 +89,21 @@ static void *read_reply(enum xsd_sockmsg
    2.12  	return ret;
    2.13  }
    2.14  
    2.15 +/* Emergency write. */
    2.16 +void xs_debug_write(const char *str, unsigned int count)
    2.17 +{
    2.18 +	struct xsd_sockmsg msg;
    2.19 +	void *out = (void *)xen_start_info.store_page;
    2.20 +
    2.21 +	msg.type = XS_DEBUG;
    2.22 +	msg.len = sizeof("print") + count + 1;
    2.23 +
    2.24 +	xb_write(out, &msg, sizeof(msg));
    2.25 +	xb_write(out, "print", sizeof("print"));
    2.26 +	xb_write(out, str, count);
    2.27 +	xb_write(out, "", 1);
    2.28 +}
    2.29 +
    2.30  /* Send message to xs, get kmalloc'ed reply.  ERR_PTR() on error. */
    2.31  static void *xs_talkv(enum xsd_sockmsg_type type,
    2.32  		      const struct kvec *iovec,
    2.33 @@ -233,7 +247,7 @@ int xs_mkdirs(const char *path)
    2.34  		if (!p)
    2.35  			break;
    2.36  		*p++ = '/';
    2.37 -       }
    2.38 +	}
    2.39   out:
    2.40  	return err;
    2.41  }
    2.42 @@ -389,15 +403,11 @@ int register_xenbus_watch(struct xenbus_
    2.43  	int err;
    2.44  
    2.45  	sprintf(token, "%lX", (long)watch);
    2.46 -	down(&watches_lock);
    2.47  	BUG_ON(find_watch(token));
    2.48  
    2.49 -	down(&xs_lock);
    2.50  	err = xs_watch(watch->node, token, watch->priority);
    2.51 -	up(&xs_lock);
    2.52  	if (!err)
    2.53  		list_add(&watch->list, &watches);
    2.54 -	up(&watches_lock);
    2.55  	return err;
    2.56  }
    2.57  
    2.58 @@ -407,14 +417,10 @@ void unregister_xenbus_watch(struct xenb
    2.59  	int err;
    2.60  
    2.61  	sprintf(token, "%lX", (long)watch);
    2.62 -	down(&watches_lock);
    2.63  	BUG_ON(!find_watch(token));
    2.64  
    2.65 -	down(&xs_lock);
    2.66  	err = xs_unwatch(watch->node, token);
    2.67 -	up(&xs_lock);
    2.68  	list_del(&watch->list);
    2.69 -	up(&watches_lock);
    2.70  
    2.71  	if (err)
    2.72  		printk(KERN_WARNING "XENBUS Failed to release watch %s: %i\n",
    2.73 @@ -423,16 +429,6 @@ void unregister_xenbus_watch(struct xenb
    2.74  
    2.75  static int watch_thread(void *unused)
    2.76  {
    2.77 -	int err;
    2.78 -	unsigned long mtu;
    2.79 -
    2.80 -	set_current_state(TASK_INTERRUPTIBLE);
    2.81 -	schedule_timeout(HZ*10);
    2.82 -	printk("watch_thread, doing read\n");
    2.83 -	down(&xs_lock);
    2.84 -	err = xenbus_read_long("", "mtu", &mtu);
    2.85 -	up(&xs_lock);
    2.86 -	printk("fake field read: %i (%lu)\n", err, mtu);
    2.87  
    2.88  	for (;;) {
    2.89  		char *token;
    2.90 @@ -447,28 +443,25 @@ static int watch_thread(void *unused)
    2.91  		down(&xs_lock);
    2.92  		if (xs_input_avail(xs_in))
    2.93  			node = xs_read_watch(&token);
    2.94 -		/* Release lock before calling callback. */
    2.95 -		up(&xs_lock);
    2.96 +
    2.97  		if (node && !IS_ERR(node)) {
    2.98  			struct xenbus_watch *w;
    2.99  			int err;
   2.100  
   2.101 -			down(&watches_lock);
   2.102  			w = find_watch(token);
   2.103  			BUG_ON(!w);
   2.104  			w->callback(w, node);
   2.105 -			up(&watches_lock);
   2.106 -			down(&xs_lock);
   2.107 +			/* FIXME: Only ack if it wasn't deleted. */
   2.108  			err = xs_acknowledge_watch(token);
   2.109  			if (err)
   2.110  				printk(KERN_WARNING
   2.111  				       "XENBUS acknowledge %s failed %i\n",
   2.112  				       node, err);
   2.113 -			up(&xs_lock);
   2.114  			kfree(node);
   2.115  		} else
   2.116  			printk(KERN_WARNING "XENBUS xs_read_watch: %li\n",
   2.117  			       PTR_ERR(node));
   2.118 +		up(&xs_lock);
   2.119  	}
   2.120  }
   2.121  
     3.1 --- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h	Tue Jul 12 09:38:02 2005 +0000
     3.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h	Tue Jul 12 09:51:37 2005 +0000
     3.3 @@ -38,6 +38,7 @@ struct xenbus_device {
     3.4  	char *nodename;
     3.5  	int id;
     3.6  	struct device dev;
     3.7 +	void *data;
     3.8  };
     3.9  
    3.10  static inline struct xenbus_device *to_xenbus_device(struct device *dev)
    3.11 @@ -97,7 +98,8 @@ int xenbus_for_each_drv(struct xenbus_dr
    3.12  int xenbus_for_each_backend(struct xenbus_driver * start, void * data,
    3.13                              int (*fn)(struct xenbus_driver *, void *));
    3.14  
    3.15 -/* Caller must hold this lock to call these functions. */
    3.16 +/* Caller must hold this lock to call these functions: it's also held
    3.17 + * across watch callbacks. */
    3.18  extern struct semaphore xs_lock;
    3.19  
    3.20  char **xs_directory(const char *path, unsigned int *num);
    3.21 @@ -124,6 +126,10 @@ struct xenbus_watch
    3.22  int register_xenbus_watch(struct xenbus_watch *watch);
    3.23  void unregister_xenbus_watch(struct xenbus_watch *watch);
    3.24  
    3.25 +/* Generic read function: NULL-terminated triples of name,
    3.26 + * sprintf-style type string, and pointer. */
    3.27 +int xenbus_gather(const char *dir, ...);
    3.28 +
    3.29  char *xenbus_path(const char *dir, const char *name);
    3.30  char *xenbus_read(const char *dir, const char *name, unsigned int *data_n);
    3.31  int xenbus_write(const char *dir, const char *name,
    3.32 @@ -135,9 +141,5 @@ int xenbus_read_ulong(const char *dir, c
    3.33  int xenbus_write_ulong(const char *dir, const char *name, unsigned long val);
    3.34  int xenbus_read_long(const char *dir, const char *name, long *val);
    3.35  int xenbus_write_long(const char *dir, const char *name, long val);
    3.36 -int xenbus_read_mac(const char *dir, const char *name, unsigned char mac[6]);
    3.37 -int xenbus_write_mac(const char *dir, const char *name, const unsigned char mac[6]);
    3.38 -int xenbus_read_evtchn(const char *dir, const char *name, struct xenbus_evtchn *evtchn);
    3.39 -int xenbus_message(const char *dir, const char *val, ...);
    3.40  
    3.41  #endif /* _ASM_XEN_XENBUS_H */