Commit ea09bcc9 authored by Martin K. Petersen's avatar Martin K. Petersen Committed by James Bottomley

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: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent c277331d
...@@ -1307,6 +1307,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, ...@@ -1307,6 +1307,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
int sense_valid = 0; int sense_valid = 0;
int the_result; int the_result;
int retries = 3; int retries = 3;
unsigned int alignment;
unsigned long long lba; unsigned long long lba;
unsigned sector_size; unsigned sector_size;
...@@ -1358,6 +1359,16 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, ...@@ -1358,6 +1359,16 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
return -EOVERFLOW; return -EOVERFLOW;
} }
/* Logical blocks per physical block exponent */
sdkp->hw_sector_size = (1 << (buffer[13] & 0xf)) * sector_size;
/* Lowest aligned logical block */
alignment = ((buffer[14] & 0x3f) << 8 | buffer[15]) * sector_size;
blk_queue_alignment_offset(sdp->request_queue, alignment);
if (alignment && sdkp->first_scan)
sd_printk(KERN_NOTICE, sdkp,
"physical block alignment offset: %u\n", alignment);
sdkp->capacity = lba + 1; sdkp->capacity = lba + 1;
return sector_size; return sector_size;
} }
...@@ -1409,6 +1420,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, ...@@ -1409,6 +1420,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
} }
sdkp->capacity = lba + 1; sdkp->capacity = lba + 1;
sdkp->hw_sector_size = sector_size;
return sector_size; return sector_size;
} }
...@@ -1521,11 +1533,17 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) ...@@ -1521,11 +1533,17 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
string_get_size(sz, STRING_UNITS_10, cap_str_10, string_get_size(sz, STRING_UNITS_10, cap_str_10,
sizeof(cap_str_10)); sizeof(cap_str_10));
if (sdkp->first_scan || old_capacity != sdkp->capacity) if (sdkp->first_scan || old_capacity != sdkp->capacity) {
sd_printk(KERN_NOTICE, sdkp, sd_printk(KERN_NOTICE, sdkp,
"%llu %d-byte hardware sectors: (%s/%s)\n", "%llu %d-byte logical blocks: (%s/%s)\n",
(unsigned long long)sdkp->capacity, (unsigned long long)sdkp->capacity,
sector_size, cap_str_10, cap_str_2); sector_size, cap_str_10, cap_str_2);
if (sdkp->hw_sector_size != sector_size)
sd_printk(KERN_NOTICE, sdkp,
"%u-byte physical blocks\n",
sdkp->hw_sector_size);
}
} }
/* Rescale capacity to 512-byte units */ /* Rescale capacity to 512-byte units */
...@@ -1538,6 +1556,7 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) ...@@ -1538,6 +1556,7 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
else if (sector_size == 256) else if (sector_size == 256)
sdkp->capacity >>= 1; sdkp->capacity >>= 1;
blk_queue_physical_block_size(sdp->request_queue, sdkp->hw_sector_size);
sdkp->device->sector_size = sector_size; sdkp->device->sector_size = sector_size;
} }
......
...@@ -45,6 +45,7 @@ struct scsi_disk { ...@@ -45,6 +45,7 @@ struct scsi_disk {
unsigned int openers; /* protected by BKL for now, yuck */ unsigned int openers; /* protected by BKL for now, yuck */
sector_t capacity; /* size in 512-byte sectors */ sector_t capacity; /* size in 512-byte sectors */
u32 index; u32 index;
unsigned short hw_sector_size;
u8 media_present; u8 media_present;
u8 write_prot; u8 write_prot;
u8 protection_type;/* Data Integrity Field */ u8 protection_type;/* Data Integrity Field */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment