]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/sd.c
fastboot: make scsi probes asynchronous
[linux-2.6-omap-h63xx.git] / drivers / scsi / sd.c
index 62b28d58e65e0e0c15cf6bcff602708a240b5819..e035c11140104c1db29bdf5fa1f9664e5a9dabb3 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/string_helpers.h>
+#include <linux/async.h>
 #include <asm/uaccess.h>
 
 #include <scsi/scsi.h>
@@ -1802,6 +1803,71 @@ static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
        return 0;
 }
 
+/*
+ * The asynchronous part of sd_probe
+ */
+static void sd_probe_async(void *data, async_cookie_t cookie)
+{
+       struct scsi_disk *sdkp = data;
+       struct scsi_device *sdp;
+       struct gendisk *gd;
+       u32 index;
+       struct device *dev;
+
+       sdp = sdkp->device;
+       gd = sdkp->disk;
+       index = sdkp->index;
+       dev = &sdp->sdev_gendev;
+
+       if (!sdp->request_queue->rq_timeout) {
+               if (sdp->type != TYPE_MOD)
+                       blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT);
+               else
+                       blk_queue_rq_timeout(sdp->request_queue,
+                                            SD_MOD_TIMEOUT);
+       }
+
+       device_initialize(&sdkp->dev);
+       sdkp->dev.parent = &sdp->sdev_gendev;
+       sdkp->dev.class = &sd_disk_class;
+       strncpy(sdkp->dev.bus_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE);
+
+       if (device_add(&sdkp->dev))
+               goto out_free_index;
+
+       get_device(&sdp->sdev_gendev);
+
+       if (index < SD_MAX_DISKS) {
+               gd->major = sd_major((index & 0xf0) >> 4);
+               gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
+               gd->minors = SD_MINORS;
+       }
+       gd->fops = &sd_fops;
+       gd->private_data = &sdkp->driver;
+       gd->queue = sdkp->device->request_queue;
+
+       sd_revalidate_disk(gd);
+
+       blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
+
+       gd->driverfs_dev = &sdp->sdev_gendev;
+       gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS;
+       if (sdp->removable)
+               gd->flags |= GENHD_FL_REMOVABLE;
+
+       dev_set_drvdata(dev, sdkp);
+       add_disk(gd);
+       sd_dif_config_host(sdkp);
+
+       sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
+                 sdp->removable ? "removable " : "");
+
+       return;
+
+ out_free_index:
+       ida_remove(&sd_index_ida, index);
+}
+
 /**
  *     sd_probe - called during driver initialization and whenever a
  *     new scsi device is attached to the system. It is called once
@@ -1865,48 +1931,7 @@ static int sd_probe(struct device *dev)
        sdkp->openers = 0;
        sdkp->previous_state = 1;
 
-       if (!sdp->request_queue->rq_timeout) {
-               if (sdp->type != TYPE_MOD)
-                       blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT);
-               else
-                       blk_queue_rq_timeout(sdp->request_queue,
-                                            SD_MOD_TIMEOUT);
-       }
-
-       device_initialize(&sdkp->dev);
-       sdkp->dev.parent = &sdp->sdev_gendev;
-       sdkp->dev.class = &sd_disk_class;
-       strncpy(sdkp->dev.bus_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE);
-
-       if (device_add(&sdkp->dev))
-               goto out_free_index;
-
-       get_device(&sdp->sdev_gendev);
-
-       if (index < SD_MAX_DISKS) {
-               gd->major = sd_major((index & 0xf0) >> 4);
-               gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
-               gd->minors = SD_MINORS;
-       }
-       gd->fops = &sd_fops;
-       gd->private_data = &sdkp->driver;
-       gd->queue = sdkp->device->request_queue;
-
-       sd_revalidate_disk(gd);
-
-       blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
-
-       gd->driverfs_dev = &sdp->sdev_gendev;
-       gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS;
-       if (sdp->removable)
-               gd->flags |= GENHD_FL_REMOVABLE;
-
-       dev_set_drvdata(dev, sdkp);
-       add_disk(gd);
-       sd_dif_config_host(sdkp);
-
-       sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
-                 sdp->removable ? "removable " : "");
+       async_schedule(sd_probe_async, sdkp);
 
        return 0;