diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index d2880b013c88..eb9709864a21 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -915,7 +915,8 @@ static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors) *max_sectors = ata_tf_to_lba48(&tf); else *max_sectors = ata_tf_to_lba(&tf); - + if (dev->horkage & ATA_HORKAGE_HPA_SIZE) + (*max_sectors)--; return 0; } @@ -3905,6 +3906,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "WDC WD2500JD-00HBB0", "WD-WMAL71490727", ATA_HORKAGE_BROKEN_HPA }, { "MAXTOR 6L080L4", "A93.0500", ATA_HORKAGE_BROKEN_HPA }, + /* Devices which report 1 sector over size HPA */ + { "ST340823A", NULL, ATA_HORKAGE_HPA_SIZE, }, + { "ST320413A", NULL, ATA_HORKAGE_HPA_SIZE, }, + /* End Marker */ { } }; diff --git a/include/linux/libata.h b/include/linux/libata.h index cd9c2a28136a..f9ed198e4fcd 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -330,6 +330,7 @@ enum { ATA_HORKAGE_MAX_SEC_128 = (1 << 3), /* Limit max sects to 128 */ ATA_HORKAGE_BROKEN_HPA = (1 << 4), /* Broken HPA */ ATA_HORKAGE_SKIP_PM = (1 << 5), /* Skip PM operations */ + ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */ }; enum hsm_task_states {