summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2014-03-07 09:45:40 +0000
committermav <mav@FreeBSD.org>2014-03-07 09:45:40 +0000
commitfe221d29bf0f99dc465137bf6fea3a92d8306375 (patch)
tree772aee9d2ed2b4cbb8217f7ae4d7f0fc507687a6
parent37a7c0392e607849f0904c7d0ff0e3531d80505d (diff)
downloadFreeBSD-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.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 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];
OpenPOWER on IntegriCloud