[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [LINUX][XENBUS] Wait for devices to connect when frontend driver is loaded as a module.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxxx # Node ID 857854460d3695afd926d28c69c524d953539abe # Parent 457c427c28fcc65dc30c52c50662f404b3f6c475 [LINUX][XENBUS] Wait for devices to connect when frontend driver is loaded as a module. Thsi fixes problems where a driver is loaded from a script, and the following parts of the script depend on devices having connected by the time the modprobe/insmod returns. Based on a tested patch from Rik van Riel at Red Hat. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c | 67 ++++++++++++----- 1 files changed, 50 insertions(+), 17 deletions(-) diff -r 457c427c28fc -r 857854460d36 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Sat Aug 12 12:25:42 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Sat Aug 12 15:50:25 2006 +0100 @@ -58,6 +58,8 @@ extern struct mutex xenwatch_mutex; static struct notifier_block *xenstore_chain; +static void wait_for_devices(struct xenbus_driver *xendrv); + /* If something in array of ids matches this device, return it. */ static const struct xenbus_device_id * match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev) @@ -408,9 +410,18 @@ static int xenbus_register_driver_common int xenbus_register_frontend(struct xenbus_driver *drv) { + int ret; + drv->read_otherend_details = read_backend_details; - return xenbus_register_driver_common(drv, &xenbus_frontend); + ret = xenbus_register_driver_common(drv, &xenbus_frontend); + if (ret) + return ret; + + /* If this driver is loaded as a module wait for devices to attach. */ + wait_for_devices(drv); + + return 0; } EXPORT_SYMBOL_GPL(xenbus_register_frontend); @@ -1042,6 +1053,7 @@ static int is_disconnected_device(struct static int is_disconnected_device(struct device *dev, void *data) { struct xenbus_device *xendev = to_xenbus_device(dev); + struct device_driver *drv = data; /* * A device with no driver will never connect. We care only about @@ -1050,18 +1062,27 @@ static int is_disconnected_device(struct if (!dev->driver) return 0; + /* Is this search limited to a particular driver? */ + if (drv && (dev->driver != drv)) + return 0; + return (xendev->state != XenbusStateConnected); } -static int exists_disconnected_device(void) -{ - return bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, +static int exists_disconnected_device(struct device_driver *drv) +{ + return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, is_disconnected_device); } static int print_device_status(struct device *dev, void *data) { struct xenbus_device *xendev = to_xenbus_device(dev); + struct device_driver *drv = data; + + /* Is this operation limited to a particular driver? */ + if (drv && (dev->driver != drv)) + return 0; if (!dev->driver) { /* Information only: is this too noisy? */ @@ -1075,6 +1096,9 @@ static int print_device_status(struct de return 0; } + +/* We only wait for device setup after most initcalls have run. */ +static int ready_to_wait_for_devices; /* * On a 10 second timeout, wait for all devices currently configured. We need @@ -1090,20 +1114,29 @@ static int print_device_status(struct de * boot slightly, but of course needs tools or manual intervention to set up * those flags correctly. */ -static int __init wait_for_devices(void) +static void wait_for_devices(struct xenbus_driver *xendrv) { unsigned long timeout = jiffies + 10*HZ; - - if (!is_running_on_xen()) - return -ENODEV; - - while (time_before(jiffies, timeout) && exists_disconnected_device()) + struct device_driver *drv = xendrv ? &xendrv->driver : NULL; + + if (!ready_to_wait_for_devices || !is_running_on_xen()) + return; + + while (exists_disconnected_device(drv)) { + if (time_after(jiffies, timeout)) + break; schedule_timeout_interruptible(HZ/10); - - bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, + } + + bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, print_device_status); - - return 0; -} - -late_initcall(wait_for_devices); +} + +static int __init boot_wait_for_devices(void) +{ + ready_to_wait_for_devices = 1; + wait_for_devices(NULL); + return 0; +} + +late_initcall(boot_wait_for_devices); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |