aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2009-05-23 11:43:37 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-21 11:52:37 -0400
commitea09bcc9c298d3057270abd78a973fc678d55c4c (patch)
tree35764eeb8325f03c29b2da115290c06c9f8303ab /drivers/scsi
parentc277331d5fbaae5772ed19862feefa91f4e477d3 (diff)
sd: Physical block size and alignment support
Extract physical block size and lowest aligned LBA from READ CAPACITY(16) response and adjust queue parameters. Report physical block size and alignment when applicable. [jejb: fix up trailing whitespace] Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/sd.c23
-rw-r--r--drivers/scsi/sd.h1
2 files changed, 22 insertions, 2 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 878b17a9af30..a86064b6458d 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
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 708778cf5f06..8474b5bad3fe 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -45,6 +45,7 @@ struct scsi_disk {
45 unsigned int openers; /* protected by BKL for now, yuck */ 45 unsigned int openers; /* protected by BKL for now, yuck */
46 sector_t capacity; /* size in 512-byte sectors */ 46 sector_t capacity; /* size in 512-byte sectors */
47 u32 index; 47 u32 index;
48 unsigned short hw_sector_size;
48 u8 media_present; 49 u8 media_present;
49 u8 write_prot; 50 u8 write_prot;
50 u8 protection_type;/* Data Integrity Field */ 51 u8 protection_type;/* Data Integrity Field */