aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c109
1 files changed, 67 insertions, 42 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 62b28d58e65e..e035c1114010 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -48,6 +48,7 @@
48#include <linux/delay.h> 48#include <linux/delay.h>
49#include <linux/mutex.h> 49#include <linux/mutex.h>
50#include <linux/string_helpers.h> 50#include <linux/string_helpers.h>
51#include <linux/async.h>
51#include <asm/uaccess.h> 52#include <asm/uaccess.h>
52 53
53#include <scsi/scsi.h> 54#include <scsi/scsi.h>
@@ -1802,6 +1803,71 @@ static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
1802 return 0; 1803 return 0;
1803} 1804}
1804 1805
1806/*
1807 * The asynchronous part of sd_probe
1808 */
1809static void sd_probe_async(void *data, async_cookie_t cookie)
1810{
1811 struct scsi_disk *sdkp = data;
1812 struct scsi_device *sdp;
1813 struct gendisk *gd;
1814 u32 index;
1815 struct device *dev;
1816
1817 sdp = sdkp->device;
1818 gd = sdkp->disk;
1819 index = sdkp->index;
1820 dev = &sdp->sdev_gendev;
1821
1822 if (!sdp->request_queue->rq_timeout) {
1823 if (sdp->type != TYPE_MOD)
1824 blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT);
1825 else
1826 blk_queue_rq_timeout(sdp->request_queue,
1827 SD_MOD_TIMEOUT);
1828 }
1829
1830 device_initialize(&sdkp->dev);
1831 sdkp->dev.parent = &sdp->sdev_gendev;
1832 sdkp->dev.class = &sd_disk_class;
1833 strncpy(sdkp->dev.bus_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE);
1834
1835 if (device_add(&sdkp->dev))
1836 goto out_free_index;
1837
1838 get_device(&sdp->sdev_gendev);
1839
1840 if (index < SD_MAX_DISKS) {
1841 gd->major = sd_major((index & 0xf0) >> 4);
1842 gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
1843 gd->minors = SD_MINORS;
1844 }
1845 gd->fops = &sd_fops;
1846 gd->private_data = &sdkp->driver;
1847 gd->queue = sdkp->device->request_queue;
1848
1849 sd_revalidate_disk(gd);
1850
1851 blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
1852
1853 gd->driverfs_dev = &sdp->sdev_gendev;
1854 gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS;
1855 if (sdp->removable)
1856 gd->flags |= GENHD_FL_REMOVABLE;
1857
1858 dev_set_drvdata(dev, sdkp);
1859 add_disk(gd);
1860 sd_dif_config_host(sdkp);
1861
1862 sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
1863 sdp->removable ? "removable " : "");
1864
1865 return;
1866
1867 out_free_index:
1868 ida_remove(&sd_index_ida, index);
1869}
1870
1805/** 1871/**
1806 * sd_probe - called during driver initialization and whenever a 1872 * sd_probe - called during driver initialization and whenever a
1807 * new scsi device is attached to the system. It is called once 1873 * new scsi device is attached to the system. It is called once
@@ -1865,48 +1931,7 @@ static int sd_probe(struct device *dev)
1865 sdkp->openers = 0; 1931 sdkp->openers = 0;
1866 sdkp->previous_state = 1; 1932 sdkp->previous_state = 1;
1867 1933
1868 if (!sdp->request_queue->rq_timeout) { 1934 async_schedule(sd_probe_async, sdkp);
1869 if (sdp->type != TYPE_MOD)
1870 blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT);
1871 else
1872 blk_queue_rq_timeout(sdp->request_queue,
1873 SD_MOD_TIMEOUT);
1874 }
1875
1876 device_initialize(&sdkp->dev);
1877 sdkp->dev.parent = &sdp->sdev_gendev;
1878 sdkp->dev.class = &sd_disk_class;
1879 strncpy(sdkp->dev.bus_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE);
1880
1881 if (device_add(&sdkp->dev))
1882 goto out_free_index;
1883
1884 get_device(&sdp->sdev_gendev);
1885
1886 if (index < SD_MAX_DISKS) {
1887 gd->major = sd_major((index & 0xf0) >> 4);
1888 gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
1889 gd->minors = SD_MINORS;
1890 }
1891 gd->fops = &sd_fops;
1892 gd->private_data = &sdkp->driver;
1893 gd->queue = sdkp->device->request_queue;
1894
1895 sd_revalidate_disk(gd);
1896
1897 blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
1898
1899 gd->driverfs_dev = &sdp->sdev_gendev;
1900 gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS;
1901 if (sdp->removable)
1902 gd->flags |= GENHD_FL_REMOVABLE;
1903
1904 dev_set_drvdata(dev, sdkp);
1905 add_disk(gd);
1906 sd_dif_config_host(sdkp);
1907
1908 sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
1909 sdp->removable ? "removable " : "");
1910 1935
1911 return 0; 1936 return 0;
1912 1937