diff options
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 878b17a9af30..5616cd780ff3 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -1307,6 +1307,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, | |||
1307 | int sense_valid = 0; | 1307 | int sense_valid = 0; |
1308 | int the_result; | 1308 | int the_result; |
1309 | int retries = 3; | 1309 | int retries = 3; |
1310 | unsigned int alignment; | ||
1310 | unsigned long long lba; | 1311 | unsigned long long lba; |
1311 | unsigned sector_size; | 1312 | unsigned sector_size; |
1312 | 1313 | ||
@@ -1358,6 +1359,16 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, | |||
1358 | return -EOVERFLOW; | 1359 | return -EOVERFLOW; |
1359 | } | 1360 | } |
1360 | 1361 | ||
1362 | /* Logical blocks per physical block exponent */ | ||
1363 | sdkp->hw_sector_size = (1 << (buffer[13] & 0xf)) * sector_size; | ||
1364 | |||
1365 | /* Lowest aligned logical block */ | ||
1366 | alignment = ((buffer[14] & 0x3f) << 8 | buffer[15]) * sector_size; | ||
1367 | blk_queue_alignment_offset(sdp->request_queue, alignment); | ||
1368 | if (alignment && sdkp->first_scan) | ||
1369 | sd_printk(KERN_NOTICE, sdkp, | ||
1370 | "physical block alignment offset: %u\n", alignment); | ||
1371 | |||
1361 | sdkp->capacity = lba + 1; | 1372 | sdkp->capacity = lba + 1; |
1362 | return sector_size; | 1373 | return sector_size; |
1363 | } | 1374 | } |
@@ -1409,6 +1420,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, | |||
1409 | } | 1420 | } |
1410 | 1421 | ||
1411 | sdkp->capacity = lba + 1; | 1422 | sdkp->capacity = lba + 1; |
1423 | sdkp->hw_sector_size = sector_size; | ||
1412 | return sector_size; | 1424 | return sector_size; |
1413 | } | 1425 | } |
1414 | 1426 | ||
@@ -1521,11 +1533,17 @@ got_data: | |||
1521 | string_get_size(sz, STRING_UNITS_10, cap_str_10, | 1533 | string_get_size(sz, STRING_UNITS_10, cap_str_10, |
1522 | sizeof(cap_str_10)); | 1534 | sizeof(cap_str_10)); |
1523 | 1535 | ||
1524 | if (sdkp->first_scan || old_capacity != sdkp->capacity) | 1536 | if (sdkp->first_scan || old_capacity != sdkp->capacity) { |
1525 | sd_printk(KERN_NOTICE, sdkp, | 1537 | sd_printk(KERN_NOTICE, sdkp, |
1526 | "%llu %d-byte hardware sectors: (%s/%s)\n", | 1538 | "%llu %d-byte logical blocks: (%s/%s)\n", |
1527 | (unsigned long long)sdkp->capacity, | 1539 | (unsigned long long)sdkp->capacity, |
1528 | sector_size, cap_str_10, cap_str_2); | 1540 | sector_size, cap_str_10, cap_str_2); |
1541 | |||
1542 | if (sdkp->hw_sector_size != sector_size) | ||
1543 | sd_printk(KERN_NOTICE, sdkp, | ||
1544 | "%u-byte physical blocks\n", | ||
1545 | sdkp->hw_sector_size); | ||
1546 | } | ||
1529 | } | 1547 | } |
1530 | 1548 | ||
1531 | /* Rescale capacity to 512-byte units */ | 1549 | /* Rescale capacity to 512-byte units */ |
@@ -1538,6 +1556,7 @@ got_data: | |||
1538 | else if (sector_size == 256) | 1556 | else if (sector_size == 256) |
1539 | sdkp->capacity >>= 1; | 1557 | sdkp->capacity >>= 1; |
1540 | 1558 | ||
1559 | blk_queue_physical_block_size(sdp->request_queue, sdkp->hw_sector_size); | ||
1541 | sdkp->device->sector_size = sector_size; | 1560 | sdkp->device->sector_size = sector_size; |
1542 | } | 1561 | } |
1543 | 1562 | ||
@@ -1776,6 +1795,52 @@ void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) | |||
1776 | } | 1795 | } |
1777 | 1796 | ||
1778 | /** | 1797 | /** |
1798 | * sd_read_block_limits - Query disk device for preferred I/O sizes. | ||
1799 | * @disk: disk to query | ||
1800 | */ | ||
1801 | static void sd_read_block_limits(struct scsi_disk *sdkp) | ||
1802 | { | ||
1803 | unsigned int sector_sz = sdkp->device->sector_size; | ||
1804 | char *buffer; | ||
1805 | |||
1806 | /* Block Limits VPD */ | ||
1807 | buffer = scsi_get_vpd_page(sdkp->device, 0xb0); | ||
1808 | |||
1809 | if (buffer == NULL) | ||
1810 | return; | ||
1811 | |||
1812 | blk_queue_io_min(sdkp->disk->queue, | ||
1813 | get_unaligned_be16(&buffer[6]) * sector_sz); | ||
1814 | blk_queue_io_opt(sdkp->disk->queue, | ||
1815 | get_unaligned_be32(&buffer[12]) * sector_sz); | ||
1816 | |||
1817 | kfree(buffer); | ||
1818 | } | ||
1819 | |||
1820 | /** | ||
1821 | * sd_read_block_characteristics - Query block dev. characteristics | ||
1822 | * @disk: disk to query | ||
1823 | */ | ||
1824 | static void sd_read_block_characteristics(struct scsi_disk *sdkp) | ||
1825 | { | ||
1826 | char *buffer; | ||
1827 | u16 rot; | ||
1828 | |||
1829 | /* Block Device Characteristics VPD */ | ||
1830 | buffer = scsi_get_vpd_page(sdkp->device, 0xb1); | ||
1831 | |||
1832 | if (buffer == NULL) | ||
1833 | return; | ||
1834 | |||
1835 | rot = get_unaligned_be16(&buffer[4]); | ||
1836 | |||
1837 | if (rot == 1) | ||
1838 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sdkp->disk->queue); | ||
1839 | |||
1840 | kfree(buffer); | ||
1841 | } | ||
1842 | |||
1843 | /** | ||
1779 | * sd_revalidate_disk - called the first time a new disk is seen, | 1844 | * sd_revalidate_disk - called the first time a new disk is seen, |
1780 | * performs disk spin up, read_capacity, etc. | 1845 | * performs disk spin up, read_capacity, etc. |
1781 | * @disk: struct gendisk we care about | 1846 | * @disk: struct gendisk we care about |
@@ -1812,6 +1877,8 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
1812 | */ | 1877 | */ |
1813 | if (sdkp->media_present) { | 1878 | if (sdkp->media_present) { |
1814 | sd_read_capacity(sdkp, buffer); | 1879 | sd_read_capacity(sdkp, buffer); |
1880 | sd_read_block_limits(sdkp); | ||
1881 | sd_read_block_characteristics(sdkp); | ||
1815 | sd_read_write_protect_flag(sdkp, buffer); | 1882 | sd_read_write_protect_flag(sdkp, buffer); |
1816 | sd_read_cache_type(sdkp, buffer); | 1883 | sd_read_cache_type(sdkp, buffer); |
1817 | sd_read_app_tag_own(sdkp, buffer); | 1884 | sd_read_app_tag_own(sdkp, buffer); |
@@ -1934,6 +2001,8 @@ static void sd_probe_async(void *data, async_cookie_t cookie) | |||
1934 | add_disk(gd); | 2001 | add_disk(gd); |
1935 | sd_dif_config_host(sdkp); | 2002 | sd_dif_config_host(sdkp); |
1936 | 2003 | ||
2004 | sd_revalidate_disk(gd); | ||
2005 | |||
1937 | sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", | 2006 | sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", |
1938 | sdp->removable ? "removable " : ""); | 2007 | sdp->removable ? "removable " : ""); |
1939 | } | 2008 | } |
@@ -2054,6 +2123,7 @@ static int sd_remove(struct device *dev) | |||
2054 | 2123 | ||
2055 | async_synchronize_full(); | 2124 | async_synchronize_full(); |
2056 | sdkp = dev_get_drvdata(dev); | 2125 | sdkp = dev_get_drvdata(dev); |
2126 | blk_queue_prep_rq(sdkp->device->request_queue, scsi_prep_fn); | ||
2057 | device_del(&sdkp->dev); | 2127 | device_del(&sdkp->dev); |
2058 | del_gendisk(sdkp->disk); | 2128 | del_gendisk(sdkp->disk); |
2059 | sd_shutdown(dev); | 2129 | sd_shutdown(dev); |