diff options
Diffstat (limited to 'drivers/ata/libata-scsi.c')
| -rw-r--r-- | drivers/ata/libata-scsi.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 68d9132d8f6f..342316064e9f 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -2142,13 +2142,14 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf) | |||
| 2142 | 2142 | ||
| 2143 | static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf) | 2143 | static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf) |
| 2144 | { | 2144 | { |
| 2145 | int form_factor = ata_id_form_factor(args->id); | ||
| 2146 | int media_rotation_rate = ata_id_rotation_rate(args->id); | ||
| 2147 | |||
| 2145 | rbuf[1] = 0xb1; | 2148 | rbuf[1] = 0xb1; |
| 2146 | rbuf[3] = 0x3c; | 2149 | rbuf[3] = 0x3c; |
| 2147 | if (ata_id_major_version(args->id) > 7) { | 2150 | rbuf[4] = media_rotation_rate >> 8; |
| 2148 | rbuf[4] = args->id[217] >> 8; | 2151 | rbuf[5] = media_rotation_rate; |
| 2149 | rbuf[5] = args->id[217]; | 2152 | rbuf[7] = form_factor; |
| 2150 | rbuf[7] = args->id[168] & 0xf; | ||
| 2151 | } | ||
| 2152 | 2153 | ||
| 2153 | return 0; | 2154 | return 0; |
| 2154 | } | 2155 | } |
| @@ -2376,7 +2377,23 @@ saving_not_supp: | |||
| 2376 | */ | 2377 | */ |
| 2377 | static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) | 2378 | static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) |
| 2378 | { | 2379 | { |
| 2379 | u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */ | 2380 | struct ata_device *dev = args->dev; |
| 2381 | u64 last_lba = dev->n_sectors - 1; /* LBA of the last block */ | ||
| 2382 | u8 log_per_phys = 0; | ||
| 2383 | u16 lowest_aligned = 0; | ||
| 2384 | u16 word_106 = dev->id[106]; | ||
| 2385 | u16 word_209 = dev->id[209]; | ||
| 2386 | |||
| 2387 | if ((word_106 & 0xc000) == 0x4000) { | ||
| 2388 | /* Number and offset of logical sectors per physical sector */ | ||
| 2389 | if (word_106 & (1 << 13)) | ||
| 2390 | log_per_phys = word_106 & 0xf; | ||
| 2391 | if ((word_209 & 0xc000) == 0x4000) { | ||
| 2392 | u16 first = dev->id[209] & 0x3fff; | ||
| 2393 | if (first > 0) | ||
| 2394 | lowest_aligned = (1 << log_per_phys) - first; | ||
| 2395 | } | ||
| 2396 | } | ||
| 2380 | 2397 | ||
| 2381 | VPRINTK("ENTER\n"); | 2398 | VPRINTK("ENTER\n"); |
| 2382 | 2399 | ||
| @@ -2407,6 +2424,11 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) | |||
| 2407 | /* sector size */ | 2424 | /* sector size */ |
| 2408 | rbuf[10] = ATA_SECT_SIZE >> 8; | 2425 | rbuf[10] = ATA_SECT_SIZE >> 8; |
| 2409 | rbuf[11] = ATA_SECT_SIZE & 0xff; | 2426 | rbuf[11] = ATA_SECT_SIZE & 0xff; |
| 2427 | |||
| 2428 | rbuf[12] = 0; | ||
| 2429 | rbuf[13] = log_per_phys; | ||
| 2430 | rbuf[14] = (lowest_aligned >> 8) & 0x3f; | ||
| 2431 | rbuf[15] = lowest_aligned; | ||
| 2410 | } | 2432 | } |
| 2411 | 2433 | ||
| 2412 | return 0; | 2434 | return 0; |
