diff options
author | mav <mav@FreeBSD.org> | 2014-03-07 09:45:40 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2014-03-07 09:45:40 +0000 |
commit | fe221d29bf0f99dc465137bf6fea3a92d8306375 (patch) | |
tree | 772aee9d2ed2b4cbb8217f7ae4d7f0fc507687a6 | |
parent | 37a7c0392e607849f0904c7d0ff0e3531d80505d (diff) | |
download | FreeBSD-src-fe221d29bf0f99dc465137bf6fea3a92d8306375.zip FreeBSD-src-fe221d29bf0f99dc465137bf6fea3a92d8306375.tar.gz |
Fix support for increased logical sector size (4K-native drives).
- Logical sector size is measured in words, not bytes.
- If physical sector is not bigger then logical sector, it does not mean
it should be set equal to 512 bytes, but set to logical sector.
PR: misc/187269
Submitted by: Ravi Pokala <rpokala@panasas.com>
MFC after: 1 week
-rw-r--r-- | sys/cam/ata/ata_all.c | 17 | ||||
-rw-r--r-- | sys/sys/ata.h | 2 |
2 files changed, 12 insertions, 7 deletions
diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c index b88fcd1..59d8400 100644 --- a/sys/cam/ata/ata_all.c +++ b/sys/cam/ata/ata_all.c @@ -338,10 +338,10 @@ semb_print_ident_short(struct sep_identify_data *ident_data) uint32_t ata_logical_sector_size(struct ata_params *ident_data) { - if ((ident_data->pss & 0xc000) == 0x4000 && + if ((ident_data->pss & ATA_PSS_VALID_MASK) == ATA_PSS_VALID_VALUE && (ident_data->pss & ATA_PSS_LSSABOVE512)) { - return ((u_int32_t)ident_data->lss_1 | - ((u_int32_t)ident_data->lss_2 << 16)); + return (((u_int32_t)ident_data->lss_1 | + ((u_int32_t)ident_data->lss_2 << 16)) * 2); } return (512); } @@ -349,10 +349,13 @@ ata_logical_sector_size(struct ata_params *ident_data) uint64_t ata_physical_sector_size(struct ata_params *ident_data) { - if ((ident_data->pss & 0xc000) == 0x4000 && - (ident_data->pss & ATA_PSS_MULTLS)) { - return ((uint64_t)ata_logical_sector_size(ident_data) * - (1 << (ident_data->pss & ATA_PSS_LSPPS))); + if ((ident_data->pss & ATA_PSS_VALID_MASK) == ATA_PSS_VALID_VALUE) { + if (ident_data->pss & ATA_PSS_MULTLS) { + return ((uint64_t)ata_logical_sector_size(ident_data) * + (1 << (ident_data->pss & ATA_PSS_LSPPS))); + } else { + return (uint64_t)ata_logical_sector_size(ident_data); + } } return (512); } diff --git a/sys/sys/ata.h b/sys/sys/ata.h index 2a46dba..5ed1bc0 100644 --- a/sys/sys/ata.h +++ b/sys/sys/ata.h @@ -214,6 +214,8 @@ struct ata_params { #define ATA_PSS_LSPPS 0x000F #define ATA_PSS_LSSABOVE512 0x1000 #define ATA_PSS_MULTLS 0x2000 +#define ATA_PSS_VALID_MASK 0xC000 +#define ATA_PSS_VALID_VALUE 0x4000 /*107*/ u_int16_t isd; /*108*/ u_int16_t wwn[4]; u_int16_t reserved112[5]; |