diff options
-rw-r--r-- | drivers/base/dd.c | 17 | ||||
-rw-r--r-- | include/linux/device.h | 2 | ||||
-rw-r--r-- | init/do_mounts.c | 13 | ||||
-rw-r--r-- | init/do_mounts_md.c | 5 |
4 files changed, 31 insertions, 6 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 315bed8d5e7f..135231239103 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -18,9 +18,11 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <linux/delay.h> | ||
21 | #include <linux/module.h> | 22 | #include <linux/module.h> |
22 | #include <linux/kthread.h> | 23 | #include <linux/kthread.h> |
23 | #include <linux/wait.h> | 24 | #include <linux/wait.h> |
25 | #include <linux/async.h> | ||
24 | 26 | ||
25 | #include "base.h" | 27 | #include "base.h" |
26 | #include "power/power.h" | 28 | #include "power/power.h" |
@@ -168,6 +170,21 @@ int driver_probe_done(void) | |||
168 | } | 170 | } |
169 | 171 | ||
170 | /** | 172 | /** |
173 | * wait_for_device_probe | ||
174 | * Wait for device probing to be completed. | ||
175 | * | ||
176 | * Note: this function polls at 100 msec intervals. | ||
177 | */ | ||
178 | int wait_for_device_probe(void) | ||
179 | { | ||
180 | /* wait for the known devices to complete their probing */ | ||
181 | while (driver_probe_done() != 0) | ||
182 | msleep(100); | ||
183 | async_synchronize_full(); | ||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | /** | ||
171 | * driver_probe_device - attempt to bind device & driver together | 188 | * driver_probe_device - attempt to bind device & driver together |
172 | * @drv: driver to bind a device to | 189 | * @drv: driver to bind a device to |
173 | * @dev: device to try to bind to the driver | 190 | * @dev: device to try to bind to the driver |
diff --git a/include/linux/device.h b/include/linux/device.h index 45e5b1921fbb..47f343c7bdda 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -147,6 +147,8 @@ extern void put_driver(struct device_driver *drv); | |||
147 | extern struct device_driver *driver_find(const char *name, | 147 | extern struct device_driver *driver_find(const char *name, |
148 | struct bus_type *bus); | 148 | struct bus_type *bus); |
149 | extern int driver_probe_done(void); | 149 | extern int driver_probe_done(void); |
150 | extern int wait_for_device_probe(void); | ||
151 | |||
150 | 152 | ||
151 | /* sysfs interface for exporting driver attributes */ | 153 | /* sysfs interface for exporting driver attributes */ |
152 | 154 | ||
diff --git a/init/do_mounts.c b/init/do_mounts.c index 708105e163df..8d4ff5afc1d8 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c | |||
@@ -370,10 +370,14 @@ void __init prepare_namespace(void) | |||
370 | ssleep(root_delay); | 370 | ssleep(root_delay); |
371 | } | 371 | } |
372 | 372 | ||
373 | /* wait for the known devices to complete their probing */ | 373 | /* |
374 | while (driver_probe_done() != 0) | 374 | * wait for the known devices to complete their probing |
375 | msleep(100); | 375 | * |
376 | async_synchronize_full(); | 376 | * Note: this is a potential source of long boot delays. |
377 | * For example, it is not atypical to wait 5 seconds here | ||
378 | * for the touchpad of a laptop to initialize. | ||
379 | */ | ||
380 | wait_for_device_probe(); | ||
377 | 381 | ||
378 | md_run_setup(); | 382 | md_run_setup(); |
379 | 383 | ||
@@ -399,6 +403,7 @@ void __init prepare_namespace(void) | |||
399 | while (driver_probe_done() != 0 || | 403 | while (driver_probe_done() != 0 || |
400 | (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0) | 404 | (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0) |
401 | msleep(100); | 405 | msleep(100); |
406 | async_synchronize_full(); | ||
402 | } | 407 | } |
403 | 408 | ||
404 | is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; | 409 | is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; |
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c index ff95e3192884..9bdddbcb3d6a 100644 --- a/init/do_mounts_md.c +++ b/init/do_mounts_md.c | |||
@@ -281,8 +281,9 @@ static void __init autodetect_raid(void) | |||
281 | */ | 281 | */ |
282 | printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n"); | 282 | printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n"); |
283 | printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n"); | 283 | printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n"); |
284 | while (driver_probe_done() < 0) | 284 | |
285 | msleep(100); | 285 | wait_for_device_probe(); |
286 | |||
286 | fd = sys_open("/dev/md0", 0, 0); | 287 | fd = sys_open("/dev/md0", 0, 0); |
287 | if (fd >= 0) { | 288 | if (fd >= 0) { |
288 | sys_ioctl(fd, RAID_AUTORUN, raid_autopart); | 289 | sys_ioctl(fd, RAID_AUTORUN, raid_autopart); |