diff options
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 109 |
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 | */ | ||
1809 | static 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 | ||