diff options
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r-- | drivers/ata/libata-scsi.c | 23 |
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 | */ |
2377 | static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) | 2377 | static 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; |