--- ./block/genhd.c.orig	2006-11-05 16:51:18.000000000 -0600
+++ ./block/genhd.c	2006-11-05 19:41:46.000000000 -0600
@@ -13,9 +13,14 @@
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/kobj_map.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
 #include <linux/buffer_head.h>
 #include <linux/mutex.h>
 
+DECLARE_WAIT_QUEUE_HEAD(disk_wait_h);
+EXPORT_SYMBOL(disk_wait_h);
+
 struct subsystem block_subsys;
 static DEFINE_MUTEX(block_subsys_lock);
 
@@ -51,6 +56,49 @@ void blkdev_show(struct seq_file *f, off
 
 #endif /* CONFIG_PROC_FS */
 
+/*
+ * Returns an array of all the block device names and partitions.
+ */
+
+char **get_blkdevs(void)
+{
+	int i = 0;
+	int n = 0;
+	int len = 0;
+	struct list_head *p;
+	char **names = NULL;
+	struct gendisk *sgp;
+	char buf[BDEVNAME_SIZE];
+
+	down_read(&block_subsys.rwsem);
+	
+	list_for_each(p, &block_subsys.kset.list) {
+		len ++;
+	}
+	
+	names = kmalloc(sizeof(char *) * len + 1, GFP_KERNEL);
+
+	list_for_each(p, &block_subsys.kset.list) {
+		sgp = list_entry(p, struct gendisk, kobj.entry);
+		names[i] = kmalloc(strlen(disk_name(sgp, 0, buf)), GFP_KERNEL);
+		strcpy(names[i], disk_name(sgp, 0, buf));
+		
+		for (n = 0; n < sgp->minors - 1; n++) {
+			struct hd_struct *hd = sgp->part[n];
+			if (hd && hd->nr_sects) {
+				names[i] = kmalloc(strlen(disk_name(sgp, n+1, buf)), GFP_KERNEL);
+				strcpy(names[i], disk_name(sgp, n+1, buf));
+				i ++;
+			}
+		}
+	}
+	names[i] = NULL;
+	up_read(&block_subsys.rwsem);
+	return names;
+}
+
+EXPORT_SYMBOL(get_blkdevs);
+
 int register_blkdev(unsigned int major, const char *name)
 {
 	struct blk_major_name **n, *p;
@@ -185,6 +233,11 @@ void add_disk(struct gendisk *disk)
 			    disk->minors, NULL, exact_match, exact_lock, disk);
 	register_disk(disk);
 	blk_register_queue(disk);
+
+	/* Wake up queue in init/main.c. */
+	printk("Waking up queue on %s\n",
+	       disk->disk_name);
+	wake_up_interruptible(&disk_wait_h);
 }
 
 EXPORT_SYMBOL(add_disk);
--- ./drivers/usb/storage/usb.c.orig	2006-11-05 16:51:18.000000000 -0600
+++ ./drivers/usb/storage/usb.c	2006-11-05 19:43:47.000000000 -0600
@@ -1019,6 +1019,8 @@ static int storage_probe(struct usb_inte
 	atomic_inc(&total_threads);
 	wake_up_process(th);
 
+	wait_for_completion(&threads_gone);
+
 	return 0;
 
 	/* We come here if there are any problems */
--- ./include/linux/genhd.h.orig	2006-11-05 16:51:18.000000000 -0600
+++ ./include/linux/genhd.h	2006-11-05 19:43:47.000000000 -0600
@@ -60,6 +60,10 @@ struct partition {
 #include <linux/smp.h>
 #include <linux/string.h>
 #include <linux/fs.h>
+#include <linux/wait.h>
+
+/* Wait queue to wait on disks coming online. */
+extern wait_queue_head_t disk_wait_h;
 
 struct partition {
 	unsigned char boot_ind;		/* 0x80 - active */
@@ -229,6 +233,7 @@ extern struct gendisk *get_gendisk(dev_t
 
 extern void set_device_ro(struct block_device *bdev, int flag);
 extern void set_disk_ro(struct gendisk *disk, int flag);
+extern char **get_blkdevs(void);
 
 /* drivers/char/random.c */
 extern void add_disk_randomness(struct gendisk *disk);
--- ./init/do_mounts.c.orig	2006-11-05 16:51:18.000000000 -0600
+++ ./init/do_mounts.c	2006-11-05 19:51:12.000000000 -0600
@@ -13,6 +13,8 @@
 #include <linux/nfs_fs_sb.h>
 #include <linux/nfs_mount.h>
 
+#include <linux/genhd.h>
+
 #include "do_mounts.h"
 
 extern int get_filesystem_list(char * buf);
@@ -363,8 +365,35 @@ void __init change_floppy(char *fmt, ...
 }
 #endif
 
+/*
+ * match_root_name - Returns 1 if the root_device_name appears amongst
+ * the list of block devices, 0 otherwise.
+ */
+
+static int __init match_root_name(void) {
+	char **names = NULL;
+	int i = 0;
+	int match = 0;
+	
+	names = get_blkdevs();
+	while (names[i] != NULL) {
+		if (match == 0 && strncmp(names[i],
+					  root_device_name,
+					  strlen(root_device_name)) == 0) {
+			match = 1;
+			printk("Block device %s matches %s root_device_name, continuing\n",
+			       names[i], root_device_name);
+		}
+		kfree(names[i]);
+		i ++;
+	}
+	kfree(names);
+	return match;
+}
+
 void __init mount_root(void)
 {
+
 #ifdef CONFIG_ROOT_NFS
 	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
 		if (mount_nfs_root())
@@ -386,6 +415,14 @@ void __init mount_root(void)
 			change_floppy("root floppy");
 	}
 #endif
+
+	/* Here, we wait for the root device to show up, or if it's
+	 * already there, we just go on. */
+	while (!match_root_name()) {
+		printk("Waiting for root device to wake us up\n");
+		interruptible_sleep_on(&disk_wait_h);
+	}
+ 
 	create_dev("/dev/root", ROOT_DEV);
 	mount_block_root("/dev/root", root_mountflags);
 }
--- ./init/main.c.orig	2006-11-05 16:51:18.000000000 -0600
+++ ./init/main.c	2006-11-05 19:43:47.000000000 -0600
@@ -52,6 +52,11 @@
 #include <linux/debug_locks.h>
 #include <linux/lockdep.h>
 
+#include <linux/genhd.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+
+
 #include <asm/io.h>
 #include <asm/bugs.h>
 #include <asm/setup.h>
