aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r--drivers/ata/libata-scsi.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 68d9132d8f6f..d1718a1f278a 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2376,7 +2376,23 @@ saving_not_supp:
2376 */ 2376 */
2377static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) 2377static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
2378{ 2378{
2379 u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */ 2379 struct ata_device *dev = args->dev;
2380 u64 last_lba = dev->n_sectors - 1; /* LBA of the last block */
2381 u8 log_per_phys = 0;
2382 u16 lowest_aligned = 0;
2383 u16 word_106 = dev->id[106];
2384 u16 word_209 = dev->id[209];
2385
2386 if ((word_106 & 0xc000) == 0x4000) {
2387 /* Number and offset of logical sectors per physical sector */
2388 if (word_106 & (1 << 13))
2389 log_per_phys = word_106 & 0xf;
2390 if ((word_209 & 0xc000) == 0x4000) {
2391 u16 first = dev->id[209] & 0x3fff;
2392 if (first > 0)
2393 lowest_aligned = (1 << log_per_phys) - first;
2394 }
2395 }
2380 2396
2381 VPRINTK("ENTER\n"); 2397 VPRINTK("ENTER\n");
2382 2398
@@ -2407,6 +2423,11 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
2407 /* sector size */ 2423 /* sector size */
2408 rbuf[10] = ATA_SECT_SIZE >> 8; 2424 rbuf[10] = ATA_SECT_SIZE >> 8;
2409 rbuf[11] = ATA_SECT_SIZE & 0xff; 2425 rbuf[11] = ATA_SECT_SIZE & 0xff;
2426
2427 rbuf[12] = 0;
2428 rbuf[13] = log_per_phys;
2429 rbuf[14] = (lowest_aligned >> 8) & 0x3f;
2430 rbuf[15] = lowest_aligned;
2410 } 2431 }
2411 2432
2412 return 0; 2433 return 0;