diff options
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 95 |
1 files changed, 67 insertions, 28 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index af9e406a3ad8..a7b53be63367 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -87,6 +87,12 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK); | |||
87 | MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); | 87 | MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); |
88 | MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); | 88 | MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); |
89 | 89 | ||
90 | #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) | ||
91 | #define SD_MINORS 16 | ||
92 | #else | ||
93 | #define SD_MINORS 0 | ||
94 | #endif | ||
95 | |||
90 | static int sd_revalidate_disk(struct gendisk *); | 96 | static int sd_revalidate_disk(struct gendisk *); |
91 | static int sd_probe(struct device *); | 97 | static int sd_probe(struct device *); |
92 | static int sd_remove(struct device *); | 98 | static int sd_remove(struct device *); |
@@ -160,7 +166,7 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, | |||
160 | sd_print_sense_hdr(sdkp, &sshdr); | 166 | sd_print_sense_hdr(sdkp, &sshdr); |
161 | return -EINVAL; | 167 | return -EINVAL; |
162 | } | 168 | } |
163 | sd_revalidate_disk(sdkp->disk); | 169 | revalidate_disk(sdkp->disk); |
164 | return count; | 170 | return count; |
165 | } | 171 | } |
166 | 172 | ||
@@ -378,7 +384,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
378 | sector_t block = rq->sector; | 384 | sector_t block = rq->sector; |
379 | sector_t threshold; | 385 | sector_t threshold; |
380 | unsigned int this_count = rq->nr_sectors; | 386 | unsigned int this_count = rq->nr_sectors; |
381 | unsigned int timeout = sdp->timeout; | ||
382 | int ret; | 387 | int ret; |
383 | 388 | ||
384 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { | 389 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { |
@@ -579,7 +584,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
579 | SCpnt->transfersize = sdp->sector_size; | 584 | SCpnt->transfersize = sdp->sector_size; |
580 | SCpnt->underflow = this_count << 9; | 585 | SCpnt->underflow = this_count << 9; |
581 | SCpnt->allowed = SD_MAX_RETRIES; | 586 | SCpnt->allowed = SD_MAX_RETRIES; |
582 | SCpnt->timeout_per_command = timeout; | ||
583 | 587 | ||
584 | /* | 588 | /* |
585 | * This indicates that the command is ready from our end to be | 589 | * This indicates that the command is ready from our end to be |
@@ -911,7 +915,7 @@ static void sd_rescan(struct device *dev) | |||
911 | struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); | 915 | struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); |
912 | 916 | ||
913 | if (sdkp) { | 917 | if (sdkp) { |
914 | sd_revalidate_disk(sdkp->disk); | 918 | revalidate_disk(sdkp->disk); |
915 | scsi_disk_put(sdkp); | 919 | scsi_disk_put(sdkp); |
916 | } | 920 | } |
917 | } | 921 | } |
@@ -1759,6 +1763,52 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
1759 | } | 1763 | } |
1760 | 1764 | ||
1761 | /** | 1765 | /** |
1766 | * sd_format_disk_name - format disk name | ||
1767 | * @prefix: name prefix - ie. "sd" for SCSI disks | ||
1768 | * @index: index of the disk to format name for | ||
1769 | * @buf: output buffer | ||
1770 | * @buflen: length of the output buffer | ||
1771 | * | ||
1772 | * SCSI disk names starts at sda. The 26th device is sdz and the | ||
1773 | * 27th is sdaa. The last one for two lettered suffix is sdzz | ||
1774 | * which is followed by sdaaa. | ||
1775 | * | ||
1776 | * This is basically 26 base counting with one extra 'nil' entry | ||
1777 | * at the beggining from the second digit on and can be | ||
1778 | * determined using similar method as 26 base conversion with the | ||
1779 | * index shifted -1 after each digit is computed. | ||
1780 | * | ||
1781 | * CONTEXT: | ||
1782 | * Don't care. | ||
1783 | * | ||
1784 | * RETURNS: | ||
1785 | * 0 on success, -errno on failure. | ||
1786 | */ | ||
1787 | static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen) | ||
1788 | { | ||
1789 | const int base = 'z' - 'a' + 1; | ||
1790 | char *begin = buf + strlen(prefix); | ||
1791 | char *end = buf + buflen; | ||
1792 | char *p; | ||
1793 | int unit; | ||
1794 | |||
1795 | p = end - 1; | ||
1796 | *p = '\0'; | ||
1797 | unit = base; | ||
1798 | do { | ||
1799 | if (p == begin) | ||
1800 | return -EINVAL; | ||
1801 | *--p = 'a' + (index % unit); | ||
1802 | index = (index / unit) - 1; | ||
1803 | } while (index >= 0); | ||
1804 | |||
1805 | memmove(begin, p, end - p); | ||
1806 | memcpy(buf, prefix, strlen(prefix)); | ||
1807 | |||
1808 | return 0; | ||
1809 | } | ||
1810 | |||
1811 | /** | ||
1762 | * sd_probe - called during driver initialization and whenever a | 1812 | * sd_probe - called during driver initialization and whenever a |
1763 | * new scsi device is attached to the system. It is called once | 1813 | * new scsi device is attached to the system. It is called once |
1764 | * for each scsi device (not just disks) present. | 1814 | * for each scsi device (not just disks) present. |
@@ -1796,7 +1846,7 @@ static int sd_probe(struct device *dev) | |||
1796 | if (!sdkp) | 1846 | if (!sdkp) |
1797 | goto out; | 1847 | goto out; |
1798 | 1848 | ||
1799 | gd = alloc_disk(16); | 1849 | gd = alloc_disk(SD_MINORS); |
1800 | if (!gd) | 1850 | if (!gd) |
1801 | goto out_free; | 1851 | goto out_free; |
1802 | 1852 | ||
@@ -1810,8 +1860,8 @@ static int sd_probe(struct device *dev) | |||
1810 | if (error) | 1860 | if (error) |
1811 | goto out_put; | 1861 | goto out_put; |
1812 | 1862 | ||
1813 | error = -EBUSY; | 1863 | error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN); |
1814 | if (index >= SD_MAX_DISKS) | 1864 | if (error) |
1815 | goto out_free_index; | 1865 | goto out_free_index; |
1816 | 1866 | ||
1817 | sdkp->device = sdp; | 1867 | sdkp->device = sdp; |
@@ -1821,11 +1871,12 @@ static int sd_probe(struct device *dev) | |||
1821 | sdkp->openers = 0; | 1871 | sdkp->openers = 0; |
1822 | sdkp->previous_state = 1; | 1872 | sdkp->previous_state = 1; |
1823 | 1873 | ||
1824 | if (!sdp->timeout) { | 1874 | if (!sdp->request_queue->rq_timeout) { |
1825 | if (sdp->type != TYPE_MOD) | 1875 | if (sdp->type != TYPE_MOD) |
1826 | sdp->timeout = SD_TIMEOUT; | 1876 | blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT); |
1827 | else | 1877 | else |
1828 | sdp->timeout = SD_MOD_TIMEOUT; | 1878 | blk_queue_rq_timeout(sdp->request_queue, |
1879 | SD_MOD_TIMEOUT); | ||
1829 | } | 1880 | } |
1830 | 1881 | ||
1831 | device_initialize(&sdkp->dev); | 1882 | device_initialize(&sdkp->dev); |
@@ -1838,24 +1889,12 @@ static int sd_probe(struct device *dev) | |||
1838 | 1889 | ||
1839 | get_device(&sdp->sdev_gendev); | 1890 | get_device(&sdp->sdev_gendev); |
1840 | 1891 | ||
1841 | gd->major = sd_major((index & 0xf0) >> 4); | 1892 | if (index < SD_MAX_DISKS) { |
1842 | gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); | 1893 | gd->major = sd_major((index & 0xf0) >> 4); |
1843 | gd->minors = 16; | 1894 | gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); |
1844 | gd->fops = &sd_fops; | 1895 | gd->minors = SD_MINORS; |
1845 | |||
1846 | if (index < 26) { | ||
1847 | sprintf(gd->disk_name, "sd%c", 'a' + index % 26); | ||
1848 | } else if (index < (26 + 1) * 26) { | ||
1849 | sprintf(gd->disk_name, "sd%c%c", | ||
1850 | 'a' + index / 26 - 1,'a' + index % 26); | ||
1851 | } else { | ||
1852 | const unsigned int m1 = (index / 26 - 1) / 26 - 1; | ||
1853 | const unsigned int m2 = (index / 26 - 1) % 26; | ||
1854 | const unsigned int m3 = index % 26; | ||
1855 | sprintf(gd->disk_name, "sd%c%c%c", | ||
1856 | 'a' + m1, 'a' + m2, 'a' + m3); | ||
1857 | } | 1896 | } |
1858 | 1897 | gd->fops = &sd_fops; | |
1859 | gd->private_data = &sdkp->driver; | 1898 | gd->private_data = &sdkp->driver; |
1860 | gd->queue = sdkp->device->request_queue; | 1899 | gd->queue = sdkp->device->request_queue; |
1861 | 1900 | ||
@@ -1864,7 +1903,7 @@ static int sd_probe(struct device *dev) | |||
1864 | blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); | 1903 | blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); |
1865 | 1904 | ||
1866 | gd->driverfs_dev = &sdp->sdev_gendev; | 1905 | gd->driverfs_dev = &sdp->sdev_gendev; |
1867 | gd->flags = GENHD_FL_DRIVERFS; | 1906 | gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS; |
1868 | if (sdp->removable) | 1907 | if (sdp->removable) |
1869 | gd->flags |= GENHD_FL_REMOVABLE; | 1908 | gd->flags |= GENHD_FL_REMOVABLE; |
1870 | 1909 | ||