summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2014-03-14 07:47:28 +0000
committermav <mav@FreeBSD.org>2014-03-14 07:47:28 +0000
commit855ff9ecbba0dce7a421af373c5053a33c48c9ea (patch)
treef765d60d393baa9c68cd209672c15024df85ea2a
parentf44e8da41c495d7b94e6500e31f89d8006e5aa04 (diff)
downloadFreeBSD-src-855ff9ecbba0dce7a421af373c5053a33c48c9ea.zip
FreeBSD-src-855ff9ecbba0dce7a421af373c5053a33c48c9ea.tar.gz
MFC r262886:
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>
-rw-r--r--sys/cam/ata/ata_all.c17
-rw-r--r--sys/sys/ata.h2
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 6dfbf4e..cdf9fa7 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];
OpenPOWER on IntegriCloud