|
@@ -2376,7 +2376,23 @@ saving_not_supp:
|
|
*/
|
|
*/
|
|
static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
|
|
static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
|
|
{
|
|
{
|
|
- u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */
|
|
|
|
|
|
+ struct ata_device *dev = args->dev;
|
|
|
|
+ u64 last_lba = dev->n_sectors - 1; /* LBA of the last block */
|
|
|
|
+ u8 log_per_phys = 0;
|
|
|
|
+ u16 lowest_aligned = 0;
|
|
|
|
+ u16 word_106 = dev->id[106];
|
|
|
|
+ u16 word_209 = dev->id[209];
|
|
|
|
+
|
|
|
|
+ if ((word_106 & 0xc000) == 0x4000) {
|
|
|
|
+ /* Number and offset of logical sectors per physical sector */
|
|
|
|
+ if (word_106 & (1 << 13))
|
|
|
|
+ log_per_phys = word_106 & 0xf;
|
|
|
|
+ if ((word_209 & 0xc000) == 0x4000) {
|
|
|
|
+ u16 first = dev->id[209] & 0x3fff;
|
|
|
|
+ if (first > 0)
|
|
|
|
+ lowest_aligned = (1 << log_per_phys) - first;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
VPRINTK("ENTER\n");
|
|
VPRINTK("ENTER\n");
|
|
|
|
|
|
@@ -2407,6 +2423,11 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
|
|
/* sector size */
|
|
/* sector size */
|
|
rbuf[10] = ATA_SECT_SIZE >> 8;
|
|
rbuf[10] = ATA_SECT_SIZE >> 8;
|
|
rbuf[11] = ATA_SECT_SIZE & 0xff;
|
|
rbuf[11] = ATA_SECT_SIZE & 0xff;
|
|
|
|
+
|
|
|
|
+ rbuf[12] = 0;
|
|
|
|
+ rbuf[13] = log_per_phys;
|
|
|
|
+ rbuf[14] = (lowest_aligned >> 8) & 0x3f;
|
|
|
|
+ rbuf[15] = lowest_aligned;
|
|
}
|
|
}
|
|
|
|
|
|
return 0;
|
|
return 0;
|