ia64/xen-unstable

changeset 5881:bd0ff9b1ea14

Add watch for dynamic add/remove of devices.
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 26 17:07:05 2005 +0000 (2005-07-26)
parents 42e8937a93f0
children aeb3b64ea40e
files linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Tue Jul 26 17:04:33 2005 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Tue Jul 26 17:07:05 2005 +0000
     1.3 @@ -121,8 +121,6 @@ static int xenbus_probe_device(const cha
     1.4  	struct xenbus_device *xendev;
     1.5  	unsigned int stringlen;
     1.6  
     1.7 -	/* FIXME: This could be a rescan. Don't re-register existing devices. */
     1.8 -
     1.9  	/* Nodename: /device/<typename>/<name>/ */
    1.10  	stringlen = strlen(dirpath) + strlen(devicetype) + strlen(name) + 3;
    1.11  	/* Typename */
    1.12 @@ -195,6 +193,58 @@ unlock:
    1.13  	return err;
    1.14  }
    1.15  
    1.16 +/* FIXME: When all tools use transactions, we can ignore events on
    1.17 + * subpaths. */
    1.18 +static void dev_changed(struct xenbus_watch *watch, const char *node)
    1.19 +{
    1.20 +	char busid[BUS_ID_SIZE];
    1.21 +	unsigned int typelen, idlen;
    1.22 +	int exists;
    1.23 +	struct device *dev;
    1.24 +	char *type;
    1.25 +
    1.26 +	/* Node is of form device/<type>/<identifier>[/...] */
    1.27 +	type = strchr(node, '/');
    1.28 +	if (!type)
    1.29 +		return;
    1.30 +	type++;
    1.31 +
    1.32 +	typelen = strcspn(type, "/");
    1.33 +	if (!typelen)
    1.34 +		return;
    1.35 +	idlen = strcspn(type + typelen + 1, "/");
    1.36 +	if (!idlen)
    1.37 +		return;
    1.38 +	if (typelen + strlen("-") + idlen + 1 > BUS_ID_SIZE) {
    1.39 +		printk("Device for node %s is too big!\n", node);
    1.40 +		return;
    1.41 +	}
    1.42 +
    1.43 +	/* Create it with a / so we can see if it exists. */
    1.44 +	sprintf(busid, "%.*s/%.*s", typelen, type, idlen, type + typelen + 1);
    1.45 +	exists = xenbus_exists("device", busid);
    1.46 +	busid[typelen] = '-';
    1.47 +
    1.48 +	dev = device_find(busid, &xenbus_type);
    1.49 +	if (dev && !exists) {
    1.50 +		printk("xenbus: Unregistering device %s\n", busid);
    1.51 +		/* FIXME: free? */
    1.52 +		device_unregister(dev);
    1.53 +	}
    1.54 +	if (!dev && exists) {
    1.55 +		printk("xenbus: Adding device %s\n", busid);
    1.56 +		busid[typelen] = '\0';
    1.57 +		xenbus_probe_device("device", busid, busid+typelen+1);
    1.58 +	}
    1.59 +}
    1.60 +
    1.61 +/* We watch for devices appearing and vanishing. */
    1.62 +static struct xenbus_watch dev_watch = {
    1.63 +	/* FIXME: Ideally we'd only watch for changes 2 levels deep... */
    1.64 +	.node = "device",
    1.65 +	.callback = dev_changed,
    1.66 +};
    1.67 +
    1.68  /* called from a thread in privcmd/privcmd.c */
    1.69  int do_xenbus_probe(void *unused)
    1.70  {
    1.71 @@ -211,6 +261,8 @@ int do_xenbus_probe(void *unused)
    1.72  
    1.73  	/* Enumerate devices in xenstore. */
    1.74  	xenbus_probe_devices("device");
    1.75 +
    1.76 +	register_xenbus_watch(&dev_watch);
    1.77  	return 0;
    1.78  }
    1.79