diff options
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 120 |
1 files changed, 73 insertions, 47 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 5081b3981d3..d57566b8be0 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> |
@@ -884,7 +885,7 @@ static int sd_sync_cache(struct scsi_disk *sdkp) | |||
884 | * flush everything. | 885 | * flush everything. |
885 | */ | 886 | */ |
886 | res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, | 887 | res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, |
887 | SD_TIMEOUT, SD_MAX_RETRIES); | 888 | SD_TIMEOUT, SD_MAX_RETRIES, NULL); |
888 | if (res == 0) | 889 | if (res == 0) |
889 | break; | 890 | break; |
890 | } | 891 | } |
@@ -1134,7 +1135,7 @@ sd_spinup_disk(struct scsi_disk *sdkp) | |||
1134 | the_result = scsi_execute_req(sdkp->device, cmd, | 1135 | the_result = scsi_execute_req(sdkp->device, cmd, |
1135 | DMA_NONE, NULL, 0, | 1136 | DMA_NONE, NULL, 0, |
1136 | &sshdr, SD_TIMEOUT, | 1137 | &sshdr, SD_TIMEOUT, |
1137 | SD_MAX_RETRIES); | 1138 | SD_MAX_RETRIES, NULL); |
1138 | 1139 | ||
1139 | /* | 1140 | /* |
1140 | * If the drive has indicated to us that it | 1141 | * If the drive has indicated to us that it |
@@ -1192,7 +1193,8 @@ sd_spinup_disk(struct scsi_disk *sdkp) | |||
1192 | cmd[4] |= 1 << 4; | 1193 | cmd[4] |= 1 << 4; |
1193 | scsi_execute_req(sdkp->device, cmd, DMA_NONE, | 1194 | scsi_execute_req(sdkp->device, cmd, DMA_NONE, |
1194 | NULL, 0, &sshdr, | 1195 | NULL, 0, &sshdr, |
1195 | SD_TIMEOUT, SD_MAX_RETRIES); | 1196 | SD_TIMEOUT, SD_MAX_RETRIES, |
1197 | NULL); | ||
1196 | spintime_expire = jiffies + 100 * HZ; | 1198 | spintime_expire = jiffies + 100 * HZ; |
1197 | spintime = 1; | 1199 | spintime = 1; |
1198 | } | 1200 | } |
@@ -1306,7 +1308,7 @@ repeat: | |||
1306 | 1308 | ||
1307 | the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, | 1309 | the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, |
1308 | buffer, longrc ? 13 : 8, &sshdr, | 1310 | buffer, longrc ? 13 : 8, &sshdr, |
1309 | SD_TIMEOUT, SD_MAX_RETRIES); | 1311 | SD_TIMEOUT, SD_MAX_RETRIES, NULL); |
1310 | 1312 | ||
1311 | if (media_not_present(sdkp, &sshdr)) | 1313 | if (media_not_present(sdkp, &sshdr)) |
1312 | return; | 1314 | return; |
@@ -1801,6 +1803,71 @@ static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen) | |||
1801 | return 0; | 1803 | return 0; |
1802 | } | 1804 | } |
1803 | 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 | dev_set_name(&sdkp->dev, dev_name(&sdp->sdev_gendev)); | ||
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 | |||
1804 | /** | 1871 | /** |
1805 | * sd_probe - called during driver initialization and whenever a | 1872 | * sd_probe - called during driver initialization and whenever a |
1806 | * 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 |
@@ -1864,48 +1931,7 @@ static int sd_probe(struct device *dev) | |||
1864 | sdkp->openers = 0; | 1931 | sdkp->openers = 0; |
1865 | sdkp->previous_state = 1; | 1932 | sdkp->previous_state = 1; |
1866 | 1933 | ||
1867 | if (!sdp->request_queue->rq_timeout) { | 1934 | async_schedule(sd_probe_async, sdkp); |
1868 | if (sdp->type != TYPE_MOD) | ||
1869 | blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT); | ||
1870 | else | ||
1871 | blk_queue_rq_timeout(sdp->request_queue, | ||
1872 | SD_MOD_TIMEOUT); | ||
1873 | } | ||
1874 | |||
1875 | device_initialize(&sdkp->dev); | ||
1876 | sdkp->dev.parent = &sdp->sdev_gendev; | ||
1877 | sdkp->dev.class = &sd_disk_class; | ||
1878 | strncpy(sdkp->dev.bus_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE); | ||
1879 | |||
1880 | if (device_add(&sdkp->dev)) | ||
1881 | goto out_free_index; | ||
1882 | |||
1883 | get_device(&sdp->sdev_gendev); | ||
1884 | |||
1885 | if (index < SD_MAX_DISKS) { | ||
1886 | gd->major = sd_major((index & 0xf0) >> 4); | ||
1887 | gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); | ||
1888 | gd->minors = SD_MINORS; | ||
1889 | } | ||
1890 | gd->fops = &sd_fops; | ||
1891 | gd->private_data = &sdkp->driver; | ||
1892 | gd->queue = sdkp->device->request_queue; | ||
1893 | |||
1894 | sd_revalidate_disk(gd); | ||
1895 | |||
1896 | blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); | ||
1897 | |||
1898 | gd->driverfs_dev = &sdp->sdev_gendev; | ||
1899 | gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS; | ||
1900 | if (sdp->removable) | ||
1901 | gd->flags |= GENHD_FL_REMOVABLE; | ||
1902 | |||
1903 | dev_set_drvdata(dev, sdkp); | ||
1904 | add_disk(gd); | ||
1905 | sd_dif_config_host(sdkp); | ||
1906 | |||
1907 | sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", | ||
1908 | sdp->removable ? "removable " : ""); | ||
1909 | 1935 | ||
1910 | return 0; | 1936 | return 0; |
1911 | 1937 | ||
@@ -1986,7 +2012,7 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start) | |||
1986 | return -ENODEV; | 2012 | return -ENODEV; |
1987 | 2013 | ||
1988 | res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, | 2014 | res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, |
1989 | SD_TIMEOUT, SD_MAX_RETRIES); | 2015 | SD_TIMEOUT, SD_MAX_RETRIES, NULL); |
1990 | if (res) { | 2016 | if (res) { |
1991 | sd_printk(KERN_WARNING, sdkp, "START_STOP FAILED\n"); | 2017 | sd_printk(KERN_WARNING, sdkp, "START_STOP FAILED\n"); |
1992 | sd_print_result(sdkp, res); | 2018 | sd_print_result(sdkp, res); |